A standard analog TDS (Total Dissolved Solids) meter sensor outputs a 0-3.3V or 0-5V signal corresponding to 0-1000+ ppm. To get accurate, drift-free readings on an ESP32 or Arduino, you must account for microcontroller ADC reference voltages, temperature compensation, and proper probe immersion techniques. The direct answer for most hobbyist setups using a 5V module: expect roughly 1.0V at 300 ppm and 3.1V at 1000 ppm, but raw ADC values will mislead you without proper attenuation and calibration.
Understanding TDS Sensor Electrical Output and Baseline Values
TDS sensors do not measure solids directly; they measure electrical conductivity (EC) and apply a conversion factor (usually between 0.5 and 0.7) to estimate dissolved solids. Because conductivity is highly dependent on ion concentration, the analog voltage output scales non-linearly at the extreme low and high ends of the spectrum.
When interfacing a standard 5V analog TDS module (like the widely used DFRobot SEN0161) with modern microcontrollers, you must translate the physical ppm value into the expected voltage and raw ADC counts. The ESP32 features a 12-bit ADC (0-4095) but suffers from non-linearity above 3.1V, while the Arduino Uno uses a 10-bit ADC (0-1023) referenced to 5V.
| Water Type / Standard | Expected TDS (ppm) | Sensor Analog Out (V) | ESP32 12-bit ADC (Raw) | Arduino Uno 10-bit ADC (Raw) |
|---|---|---|---|---|
| Distilled / Pure RO | 0 - 50 ppm | 0.00 - 0.15V | 0 - 180 | 0 - 30 |
| Good Municipal Tap | 150 - 300 ppm | 0.45 - 0.90V | 550 - 1100 | 90 - 180 |
| Hard / Brackish Water | 500 - 800 ppm | 1.50 - 2.40V | 1850 - 2950 | 300 - 490 |
| Calibration Standard | 1024 ppm | ~3.10V | ~3800 | ~635 |
Note: The EPA recommends a secondary maximum contaminant level (SMCL) of 500 ppm for TDS in drinking water, primarily for aesthetic and taste reasons rather than acute health hazards (EPA Secondary Drinking Water Standards). Readings consistently above 1000 ppm indicate water that will rapidly scale plumbing and foul RO membranes.
Meter Setup and Probe Placement for Accurate Benchmarking
Before trusting your microcontroller code, you must benchmark the sensor against a known good handheld meter and verify the module's power rails. Misleading readings almost always originate at the physical layer.
Multimeter and Handheld Meter Setup
- Multimeter (for module debugging): Set the dial to DC Volts (V⎓). Insert the black lead into the COM jack and the red lead into the VΩ jack. Set the range to Auto or 20V DC. Probe the sensor module's VCC and GND pins to confirm a stable 5.0V (±0.1V). A sagging power rail will proportionally drag down your analog output voltage.
- Handheld TDS Meter (for baseline verification): Power on, select TDS mode (not EC), and ensure the display reads '000' in dry air. Rinse the probe with distilled water and shake dry before submerging in your test sample.
Probe Placement Rules
The physical placement of the TDS probe in the beaker or pipe dictates reading stability. Submerge the probe past the minimum immersion line (usually marked on the epoxy seal) but ensure the water level does not breach the upper plastic housing. Never let the probe rest on the bottom of the beaker. Sediment or localized ion pooling at the bottom will skew conductivity readings high. Hold the probe mid-column and tap it gently against the glass to dislodge any micro-bubbles trapped between the titanium or stainless steel electrodes, as air bubbles act as insulators and cause readings to drop erratically.
Step-by-Step Calibration and Microcontroller Integration
Factory calibration on budget TDS modules is rarely accurate for your specific water chemistry. You must perform a single-point or two-point calibration using a standard buffer solution (typically 84 ppm or 1024 ppm, available from hydroponics or aquarium suppliers).
- Temperature Equalization: TDS calculations assume a baseline of 25°C. Conductivity shifts by roughly 2% per degree Celsius. Let your calibration solution and test water sit in the same room for 2 hours. If your module lacks an onboard thermistor, wire a DS18B20 waterproof temperature sensor to your ESP32 to apply software compensation.
- Physical Cleaning: Wipe the sensor electrodes with isopropyl alcohol and a lint-free swab. Oils from human skin will insulate the probes and ruin the calibration baseline.
- Submerge and Stabilize: Place the probe in the 1024 ppm calibration solution. Stir gently for 10 seconds, then hold still. Wait 60 seconds for the analog voltage to settle.
- Read the Baseline Voltage: Use your multimeter to measure the voltage at the Analog Out pin. It should read approximately 3.10V. If it reads 2.95V, note the offset.
- ESP32 Code Implementation: On the ESP32, avoid using raw
analogRead()due to the ADC's non-linear response curve. Instead, useanalogReadMilliVolts()which utilizes the ESP32's internal eFuse calibration data to return a linearized millivolt value. Divide this by 1000 to get volts, then apply the manufacturer's polynomial conversion formula to calculate ppm.
For deep technical details on the standard analog module circuit and polynomial coefficients, refer to the DFRobot SEN0161 Hardware Wiki.
Troubleshooting Misleading Readings and Drift
When your serial monitor spits out garbage data or values that drift over time, the issue is rarely the microcontroller itself. Use this diagnostic matrix to isolate the fault.
| Symptom on Serial Monitor | Root Cause | Hardware / Code Fix |
|---|---|---|
| Readings slowly drift upward over 24+ hours in static water. | Electrolysis / Electrode Polarization. DC current causes ions to plate onto the probes. | Ensure your module uses AC excitation (switching polarity internally). If using raw probes, drive them with a 555 timer AC circuit. Clean probes with white vinegar. |
| ESP32 maxes out at ~3800 ADC (3.1V) even in high-TDS solutions. | ESP32 ADC saturation. The 12-bit ADC clips above 3.1V when attenuation is set to 0dB. | Add analogSetAttenuation(ADC_11db) in your setup() to extend the readable range to ~3.9V, or use a simple 2-resistor voltage divider on the analog pin. |
| Wildly jittery values (e.g., jumping between 210 and 280 ppm). | 50/60Hz mains interference coupling into the high-impedance analog trace. | Implement a software moving-average filter (window of 10-20 samples). Ensure the sensor module GND is tied directly to the MCU GND, not through a breadboard power rail. |
| Reads 0 ppm in tap water, but 800 ppm when touched by hand. | Floating ground or broken shield wire on the probe cable. | Check continuity from the probe's ground ring to the module's GND pin. Replace the coaxial probe cable if the inner shield is fractured. |
Finally, remember that TDS sensors cannot distinguish between beneficial minerals (like calcium and magnesium) and harmful contaminants (like lead or nitrates). A low TDS reading does not guarantee water is safe to drink, and a high reading does not mean it is toxic. For potable water safety, TDS is strictly a proxy for filtration membrane health and general mineral load, as outlined by the USGS Water Quality Guidelines. Use your sensor data to trigger RO filter change alerts or hydroponic nutrient dosing, but never as a standalone biological safety interlock.






