Skip to content
Buy 10+ on select items — save 10% auto-applied
Free US shipping on orders $35+
Order by 3pm ET — ships same-day from the US
Skip to main content

Arduino Nano TDS Sensor: Display Water PPM on OLED | ShillehTek

August 21, 2026 11 views

Arduino Nano TDS Sensor: Display Water PPM on OLED | ShillehTek
Project

Build an Arduino Nano TDS meter using a Gravity-style sensor module and SSD1306 OLED to display live water quality in PPM for fast sample comparisons from ShillehTek.

1 hr Beginner5 parts

Project Overview

Arduino Nano TDS Water Quality Meter: Use an Arduino Nano with a Gravity-compatible analog TDS sensor module to measure total dissolved solids in water and display the result in PPM on an SSD1306 OLED.

This is a practical dip-and-read meter for comparing tap, borewell, filtered, or distilled water samples with live readings on the OLED and in the Serial Monitor.

  • Time: ~1 hour
  • Skill level: Beginner
  • What you will build: A dip-and-read TDS meter with live PPM readings on a 128x64 OLED and the Serial Monitor.
Finished Arduino Nano TDS water quality meter showing PPM on an SSD1306 OLED
The finished meter: dip the probe and read the PPM.

Parts List

From ShillehTek

External

  • Water samples to compare (tap, filtered, distilled, etc.)
  • Optional: a custom PCB shield if you want a permanent handheld unit

Note: TDS guidelines for drinking water - under ~300 ppm is considered excellent; readings near zero (distilled) mean no dissolved minerals at all.

Step-by-Step Guide

Step 1 - What TDS Actually Measures

Goal: Understand the measurement before trusting it.

What to do: Total Dissolved Solids is the sum of everything dissolved in the water, including minerals, salts, and impurities. The measurement principle is simple: two electrodes, a voltage between them, and the conductivity of the water in between indicates how much is dissolved in it.

Two-electrode TDS probe principle showing conductivity through water between electrodes
The two-electrode principle: conductivity between the probes tracks dissolved solids.

Expected result: You know what a PPM reading represents.

Step 2 - Meet the Gravity TDS Sensor

Goal: Know why a dedicated module beats bare electrodes.

What to do: The sensor board excites the probe with an AC signal, which helps prevent electrode polarization and improves repeatability. It runs from 3.3 to 5.5 V, outputs a 0 to 2.3 V analog signal, and measures 0 to 1000 ppm at ±10% F.S.

Gravity-compatible analog TDS sensor kit with interface board and waterproof probe
The sensor kit: interface board plus waterproof probe.
Close-up of the TDS sensor interface module that outputs an analog voltage
The interface board: AC excitation on board, analog voltage output.

Expected result: Sensor operation and key specs are understood.

Step 3 - Gather Components and Wire It

Goal: Assemble the circuit.

Arduino Nano, Gravity TDS sensor module, SSD1306 OLED, and jumper wires laid out for the build
Everything you need: Nano, TDS sensor, OLED, and wiring.

What to do: Wire the TDS sensor module VCC to 5V, GND to GND, and analog out to A1. Wire the OLED on I2C: SDA to A4, SCL to A5, VCC to 5V, and GND to GND. Plug the probe into its connector on the interface board.

Arduino Nano wiring diagram showing TDS sensor connected to A1 and SSD1306 OLED connected via I2C
Full circuit: TDS sensor on A1, SSD1306 OLED on I2C.
Schematic for the Arduino Nano TDS meter showing sensor module and I2C OLED connections
The schematic view for a permanent build.

Expected result: Hardware is assembled and ready to program.

Step 4 - Upload the Code

Goal: Median-filter the readings and convert voltage to PPM.

What to do: Install Adafruit GFX and Adafruit SSD1306 from the Arduino IDE Library Manager. The sketch samples the sensor repeatedly, median-filters the noise, applies temperature compensation, and converts voltage to PPM using the standard Gravity cubic formula.

Code:

#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

#define TdsSensorPin A1
#define VREF 5.0          // ADC reference voltage
#define SCOUNT 30         // samples for median filtering

Adafruit_SSD1306 display(128, 64, &Wire, -1);

int analogBuffer[SCOUNT];
int bufferIndex = 0;
float temperature = 25;   // compensation temperature
float tdsValue = 0;

void setup() {
  Serial.begin(115200);
  pinMode(TdsSensorPin, INPUT);
  display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
  display.clearDisplay();
}

void loop() {
  // sample every 40 ms into the ring buffer
  analogBuffer[bufferIndex] = analogRead(TdsSensorPin);
  bufferIndex = (bufferIndex + 1) % SCOUNT;
  delay(40);

  // median-filtered average voltage
  float averageVoltage = getMedianNum(analogBuffer, SCOUNT) * VREF / 1024.0;

  // temperature compensation, then the Gravity voltage to ppm curve
  float compensation = 1.0 + 0.02 * (temperature - 25.0);
  float v = averageVoltage / compensation;
  tdsValue = (133.42 * v * v * v - 255.86 * v * v + 857.39 * v) * 0.5;

  display.clearDisplay();
  display.setTextSize(2);
  display.setTextColor(SSD1306_WHITE);
  display.setCursor(10, 20);
  display.print(tdsValue, 0);
  display.print(" ppm");
  display.display();
}
Arduino IDE configured with Adafruit SSD1306 libraries for the Arduino Nano TDS meter sketch
Libraries installed and code ready for the 128x64 I2C OLED.

Expected result: The sketch compiles and uploads, and the OLED shows 0 ppm in air.

Step 5 - (Optional) Build It on a Shield

Goal: Go from breadboard to a handheld tool.

What to do: For a more permanent build, you can move the circuit to a custom Nano shield with onboard headers and dedicated sockets. Any PCB service can fabricate something similar from your own layout.

Arduino Nano universal shield PCB design used to mount the OLED and support a permanent TDS meter build
The universal Nano shield design.
PCB layout view for an Arduino Nano shield showing headers and display area for a compact build
Layout view: headers, display, buzzer, and power.

Expected result: A permanent home for the meter (optional).

Step 6 - Dip and Measure

Goal: Read real water samples.

What to do: Dip the probe into your sample and watch the PPM settle on the OLED and Serial Monitor. Out of water it reads zero. Give it a few seconds in liquid to stabilize, then compare tap vs. filtered vs. distilled water.

Arduino Nano TDS meter demo with OLED updating live PPM readings as the probe is dipped in water
Live demo: readings appear as soon as the probe touches water.
SSD1306 OLED showing a stabilized TDS PPM value measured by the Arduino Nano
A stabilized PPM reading on the OLED.

Probe care notes: do not use it in water above 55 C, and keep it away from the container edge since both can affect the reading. The probe head and cable are waterproof; the connector and interface board are not.

Final assembled Arduino Nano TDS water quality meter with probe and OLED ready for use
The complete meter, ready for the kitchen counter or aquarium stand.

Expected result: Stable PPM readings that let you compare water quality across samples.

Conclusion

Using an Arduino Nano, a Gravity-compatible analog TDS sensor module, and an SSD1306 OLED, you built a useful dissolved-solids meter that displays live PPM readings. The AC-excited probe and median filtering help make the measurements more stable for everyday comparisons.

Want the exact parts used in this build? Grab them from ShillehTek.com. If you want help customizing this project or building something for your product, check out our IoT consulting services.

Credits

All photos and images in this tutorial are credited to Lithium ION on Hackster.io. The original guide by Lithium ION served as the reference for this ShillehTek version. We thank them for their excellent work in the maker community.