When interfacing an analog sensor TDS (Total Dissolved Solids) module like the DFRobot SEN0244 or generic "V1.0" breakout boards with a microcontroller, the direct answer is this: the output is a 0–3.3V DC analog voltage proportional to the water's electrical conductivity. You do not read a digital protocol like I2C; you read a raw ADC (Analog-to-Digital Converter) value, convert it to millivolts, apply temperature compensation, and run it through a polynomial curve to get parts per million (ppm).

How an Analog Sensor TDS Actually Measures Water

A TDS sensor does not measure dissolved solids directly. Instead, it measures Electrical Conductivity (EC) by applying an alternating current (AC) square wave across two or more exposed electrodes submerged in the water. Dissolved ions (like calcium, magnesium, and sodium) carry the current; the more ions present, the higher the conductance. The breakout board's internal op-amp circuit rectifies and smooths this AC response into a stable DC analog voltage. Because pure water is an insulator and ion-heavy water is a conductor, the resulting voltage maps directly to EC.

To convert EC to TDS, the microcontroller multiplies the EC value by a conversion factor (typically between 0.4 and 0.7, with 0.5 being the standard for most maker modules). This assumes the dissolved solids are primarily sodium chloride or similar typical salts. The USGS defines TDS as the sum of all inorganic and organic substances in a liquid, meaning while EC gives a highly accurate estimate for standard tap or hydroponic water, it cannot identify specific chemical contaminants or non-ionized solids like sugars or oils.

Expected Output Voltages and Hardware Pinout

Before wiring your microcontroller, it is critical to understand the voltage output you should expect across different water profiles. The table below maps real-world water types to their expected EC, TDS, and the resulting analog output voltage from a standard 3.3V-referenced sensor TDS module.

Table 1: Water Profile to Analog Voltage Mapping (at 25°C)
Water Type Typical TDS (ppm) Conductivity (µS/cm) Expected Analog Out (V) ESP32 12-bit Raw ADC
Distilled / RO Water 0 – 20 0 – 40 0.01 – 0.08 12 – 100
Municipal Tap Water 150 – 300 300 – 600 0.75 – 1.10 930 – 1360
Hydroponic Nutrient 800 – 1500 1600 – 3000 1.80 – 2.40 2230 – 2970
Brackish / High Mineral 3000 – 5000 6000 – 10000 2.80 – 3.25 3470 – 4020
⚡ ESP32 ADC Pin Warning: Never wire an analog sensor TDS to an ADC2 pin (e.g., GPIO 4, 12, 13, 14, 15, 25, 26, 27) if you plan to use WiFi or Bluetooth. The ESP32's ADC2 peripheral is shared with the RF subsystem and will return garbage values or fail entirely when the radio is active. Always use ADC1 pins (GPIO 32, 33, 34, 35, 36, 39). GPIO 35 is recommended for this build.

Wiring and Supply Specifications

The breakout board contains an internal voltage regulator and signal conditioning op-amp, allowing it to operate safely across a range of logic levels. Below is the exact wiring matrix for an ESP32 DevKit V1.

Table 2: Sensor TDS to ESP32 Wiring Pinout
Sensor Pin ESP32 Pin Function & Notes
VCC 3V3 or 5V (VIN) Supply Range: 3.3V to 5.5V. 5V preferred for cleaner op-amp headroom.
GND GND Common ground. Keep ground paths short to avoid noise.
AOUT GPIO 35 Analog Output (0-3.3V). Do not exceed 3.3V into the ESP32 pin.

Raw ADC to TDS Math and ESP32 Code

The most common failure point in maker water quality projects is treating the ESP32's 12-bit ADC as perfectly linear. It is not. The raw `analogRead()` value curves off at the extremes. To bypass this, modern ESP32 Arduino Core (v2.x and v3.x) includes `analogReadMilliVolts()`, which uses the chip's internal eFuse calibration data to return a highly accurate millivolt reading.

Once you have the voltage, you must apply Automatic Temperature Compensation (ATC). Conductivity increases by roughly 2% per degree Celsius above 25°C. If your water is 35°C, the raw reading will artificially inflate by ~20%. You must divide the measured voltage by the temperature compensation factor before applying the polynomial curve.

Here is the complete, compilable C++ code for the ESP32, incorporating the ATC math and the standard cubic polynomial used to map voltage to TDS (ppm):

#include <Arduino.h>

// Pin Definitions
#define TDS_PIN 35       // ADC1 channel
#define TEMP_PIN 4       // DS18B20 data pin (requires OneWire library)

// Assume a function getWaterTempC() reads your DS18B20 sensor
float getWaterTempC() {
  return 25.0; // Placeholder: replace with actual DS18B20 read
}

void setup() {
  Serial.begin(115200);
  analogReadResolution(12); // Ensure 12-bit resolution
  analogSetAttenuation(ADC_11db); // Full 0-3.3V range
}

void loop() {
  float temperature = getWaterTempC();
  
  // Read multiple samples to smooth out AC ripple from the probe
  uint32_t analogSum = 0;
  for (int i = 0; i < 20; i++) {
    analogSum += analogReadMilliVolts(TDS_PIN);
    delay(2);
  }
  float averageMilliVolts = analogSum / 20.0;
  float voltage = averageMilliVolts / 1000.0;

  // Temperature Compensation Formula (Reference 25°C, 2% coefficient)
  float compensationCoefficient = 1.0 + 0.02 * (temperature - 25.0);
  float compensationVoltage = voltage / compensationCoefficient;

  // Polynomial Curve: EC to TDS (ppm) conversion
  // Derived from standard 0-10,000 ppm analog module characteristics
  float tdsValue = (133.42 * pow(compensationVoltage, 3) 
                  - 255.86 * pow(compensationVoltage, 2) 
                  + 857.39 * compensationVoltage) * 0.5;

  if (tdsValue < 0) tdsValue = 0; // Clamp negative noise floor

  Serial.printf("Temp: %.1f C | Voltage: %.3f V | TDS: %.0f ppm\n", 
                temperature, voltage, tdsValue);
  
  delay(1000);
}

According to the Espressif ADC documentation, utilizing the calibrated millivolt function reduces reading errors from up to 15% (on raw ADC) down to roughly ±2%, which is the physical limit of the analog probe hardware itself.

Interference, Temperature, and Calibration

Even with perfect math, environmental factors will destroy your reading accuracy if ignored. Water quality monitoring in a sump, hydroponic reservoir, or aquarium introduces specific electrical and physical interference sources.

Common Interference Sources

  • Pump Back-EMI and Ground Loops: Submersible water pumps generate massive electromagnetic interference when their internal brushes spark or when AC/DC switching supplies cycle. This noise couples into the high-impedance TDS probe wires, causing wild ADC spikes. Fix: Use a twisted-pair cable for the probe extension, route it away from pump power lines, and power the pump from a separate power supply that shares a single common ground star-point with the ESP32.
  • Electrode Fouling and Bubbles: Micro-bubbles can cling to the probe's metal rings, acting as an insulator and causing sudden TDS drops. Biofilm buildup over weeks will dampen the AC signal. Fix: Tap the probe against the side of the tank after submerging to dislodge bubbles, and gently wipe the electrodes with a soft cloth and isopropyl alcohol monthly.
  • Thermal Shock: If you move the probe from a 20°C room into a 4°C cold-plunge or 80°C hot tub, the physical expansion of the epoxy potting around the electrodes can cause temporary drift. Allow 3 minutes for thermal equilibrium before trusting the reading.

Single-Point Calibration Procedure

Out of the box, cheap analog modules can be off by 10-20%. For anything beyond novelty use (like dosing hydroponic nutrients or monitoring EPA secondary drinking water standards), you must calibrate using a known reference solution.

  1. Acquire a Standard: Buy a bottle of 1413 µS/cm EC calibration solution (which equates to roughly 707 ppm TDS using the 0.5 factor). Do not mix your own salt water; the ionization rate is too variable.
  2. Stabilize Temperature: Let the calibration solution and the probe sit in the same room for 30 minutes. The solution must be exactly at the temperature printed on the bottle (usually 25°C).
  3. Measure Raw Voltage: Upload a simple sketch that only prints the `averageMilliVolts` variable. Submerge the probe, tap it to remove bubbles, and wait 60 seconds.
  4. Calculate the Offset: If the serial monitor reads 1.15V, but the math dictates 707 ppm should output exactly 1.20V, your sensor has a -0.05V offset. Add this offset directly to your `voltage` variable in the code before the temperature compensation step.
  5. Rinse Thoroughly: Always rinse the probe with distilled water between calibration and tank deployment to avoid introducing the calibration salts into your live system.
⚠️ Probe Storage Warning: Never store a TDS probe in distilled water. The lack of ions will cause the metal electrodes to slowly leach and degrade via oxidation. Store the probe dry, or submerged in a mild storage solution (like 1000 ppm KCl) if the manufacturer specifies it.