TDS Meter Library for Proteus V1.0: the TDS sensor with its STATUS panel and the Advance pop-up

TDS Meter Library for Proteus V1.0: TDS Sensor with Arduino

2.5K Views
40
700
60
25
60
PCBWay

Hello friends, I hope you all are doing great. Today, I am going to share the new TDS Meter Library for Proteus V1.0. A TDS sensor tells you how much salt and minerals your water carries: tap water, drinking water from a filter, an aquarium, a hydroponics tank or a pool. The usual board for Arduino is a small blue TDS meter with a two-pin waterproof probe. It sends a tiny AC current through the water, and the cleaner the water, the less current flows. The board turns that into a voltage on its A pin, and your Arduino turns the voltage into ppm.

Behind the part sits our own model, written from the board maker's published data. It gives the voltage the real board gives for the water in the beaker, with the published conversion, the 2 % per degree that conductivity rises with the temperature, the top of the range at 2.3 V, a probe that reads a few percent high or low until you calibrate it, and a probe lifted out of the water. You can change the water while the simulation runs: tap water, distilled water, a 707 ppm calibration buffer, sea water, a pinch of salt, warm water. You get a Simple device with a live STATUS panel and an Advance device with a pop-up window and three test tools. The demo runs on our Arduino UNO V4.0.

NOTICE: a TDS sensor is easy to fake: a potentiometer on an analog pin. We wanted more. Our TDS meter knows the water it stands in and gives exactly the voltage the published conversion turns back into that water. Its output depends on the temperature the way a real probe's does, every probe can read a few percent off, the output stops at the top of the range, and a dry probe reads nothing - so a sketch without temperature compensation, an uncalibrated probe or sea water fail exactly as they do in a real beaker. It took our team a lot of hard work. Your feedback is the fuel that keeps us going, so please tell us what you think in the comments below or in the TDS meter board of our forum. And if our free libraries help you, you can buy us a coffee. So, let's get started with the TDS Meter Library for Proteus V1.0:

TDS Meter Library for Proteus V1.0: the TDS sensor with its STATUS panel and the Advance pop-up
Figure: The TDS Meter Library for Proteus V1.0: a Simple TDS meter in tap water with its STATUS panel, and the pop-up of an Advance one in a 707 ppm buffer after the calibration.

What is a TDS Meter?

TDS means total dissolved solids: all the salt and minerals dissolved in the water, in ppm (parts per million, the same as mg per litre). Distilled water has almost none, tap water a few hundred ppm, sea water about 35000. A TDS meter does not weigh anything. It measures how well the water conducts electricity - its EC, electrical conductivity, in uS/cm - because dissolved salts carry the current. For ordinary drinking water, half the EC is a good estimate of the TDS: TDS = EC x 0.5.

The TDS meter board in numbers
ParameterThe analog TDS sensor board
Supply3.3 to 5.5 V, 3 to 6 mA
Output0 to 2.3 V on the A pin
Range0 to about 1000 ppm
Accuracyabout +- 10 % of the full scale at 25 C
Probetwo stainless steel pins, waterproof, up to about 55 C
Connectionsa 3-pin header (+, -, A) and a 2-pin socket for the probe

From Volts to ppm

The board's maker publishes the conversion from the voltage on A to the conductivity at 25 C: EC = 133.42 V^3 - 255.86 V^2 + 857.39 V in uS/cm, and TDS is half of that. At 0.669 V that gives 499 uS/cm and 249 ppm - tap water. The conversion is a fit for 25 C. Water conducts about 2 % better for every degree above 25 C and 2 % worse below, so the sketch first divides the voltage by 1 + 0.02 x (T - 25) with the water's temperature T. Without that, warm water reads high and cold water reads low.

The Three Pins

The + pin goes to 5V (or 3.3V), - to GND and A to an analog input. The output never goes above 2.3 V, so it is safe for a 3.3 V board too. The demo uses A0.

What's New in TDS Meter Library for Proteus V1.0

  • The published conversion: the model gives the voltage that EC = 133.42 V^3 - 255.86 V^2 + 857.39 V and TDS = EC x 0.5 turn back into the water's TDS.
  • The temperature: the output rises 2 % per C above 25 C, as a real probe's does.
  • The range: 0 to 2.3 V for 0 to about 1000 ppm; above that the output stops at 2.3 V.
  • A cell factor for each probe: the CELL property makes a probe read a few percent high or low, so you can practise the calibration.
  • The water on the panel: - and + for the TDS (10 ppm a click) and the temperature (1 C a click), six presets - DISTILLED, RO, TAP, MINERAL, BUFFER and SEA - and four actions - SALT, DILUTE, PROBE OUT and WARM.
  • A beaker beside the board: the water's colour follows the TDS, and PROBE OUT lowers the water below the probe.
  • Three test tools on the Advance device: Output & conversion, Temperature & calibration, and Wiring & range.
  • A two-node demo on our Arduino UNO V4.0 with no library at all: a reading every 40 ms, the median of 30 each second, the temperature compensation, and the TEMP, CAL, K and FILTER commands.
  • A compact package: about 1.25 MB, without the C++ source code of the model.

Two Devices: Simple and Advance

TDS meter sensor board in Proteus with its probe in a beaker of water
Figure: The TDS meter as the library draws it, with its PWR and PROBE LEDs lit for the picture.

The part shows the blue board with its 3-pin header on the left - +, - and A - the signal electronics in the middle and the white 2-pin socket on the right. A black cable runs from the socket to the probe, and the probe stands in a beaker of water. Two LEDs sit on the board: PWR while the board has power and PROBE while the probe is in the water. During the simulation the water in the beaker changes its colour with the TDS. The beaker, the LEDs, the badge and the button are TEP additions.

TDS meter in Proteus as a Simple device with its STATUS panel and as an Advance device
Figure: The TDS meter as a Simple device with its STATUS panel, and as an Advance device with OPEN PANEL on its board.
The two devices (search "TDS" in Pick Devices; both in TEPTDS.LIB)
SimpleAdvance
DeviceTDSMETERTEPTDSMETERADVTEP
On the schematicThe board, the beaker and the STATUS panelThe board and the beaker
The water and the actionsOn the STATUS panelIn the pop-up
StatusBanner, a ruler, 10 readouts, the last 4 eventsA pop-up: Sensor, Event log, Tests

Download TDS Meter Library for Proteus

Click the button below to download TDS-Meter-Library-for-Proteus-v1.0.zip (about 1.25 MB, without the C++ source code of the model):

TDS Meter Library for Proteus V1.0
  • README.txt: the devices, installation, the demo, wiring, the test tools and real hardware.
  • Proteus Library Files: TEPTDS.LIB and ArduinoV4TEP.LIB from our Arduino Library for Proteus V4.0.
  • Proteus Model Files: TEPTDS.DLL and TEPARDUINO.DLL.
  • Proteus Simulation: TDS-Meter-ArduinoUnoV4.pdsprj, TDS_Water_Demo.hex and copies of the two DLLs.
  • Arduino Code: TDS_Water_Demo.ino - it needs no library.

No Proteus yet? Read How to Download and Install Proteus 7 and 8. New to libraries? Follow How to Install a New Library in Proteus.

How to Install TDS Meter Library for Proteus

  1. Close Proteus and extract the whole zip file, for example to your Desktop.
  2. Copy the two files from Proteus Library Files into the LIBRARY folder of Proteus (usually C:\Program Files (x86)\Labcenter Electronics\Proteus 8 Professional\LIBRARY).
  3. Copy TEPTDS.DLL and TEPARDUINO.DLL from Proteus Model Files into the MODELS folder.
  4. Delete TEPTDS.IDX from the LIBRARY folder if it is there.
  5. Start Proteus, press P and search for TDS.

Tip: keep the Proteus Simulation folder together, because the project needs its .hex file and the DLLs beside it. The library is tested in Proteus 8.5; Proteus 7 is not supported.

The TDS Meter Part in Proteus

TDS meter in Proteus with its STATUS panel in tap water
Figure: Node 1 up close: U1, the Simple TDS meter, in tap water - 250 ppm at 25 C, 0.667 V on A, read as 249 ppm.

The Simple device adds the STATUS panel under the board. Its banner shows the reading, the EC and the output: green when all is well; amber when the water is away from 25 C, when the probe reads high or low, or when the probe is in air; red over the range or without power; grey while the output settles. Below it, THE WATER has - and + for the TDS (10 ppm a click) and the temperature (1 C a click), and a ruler from 0 to 1200 ppm with the water and the reading. Then come six presets, four actions, ten readouts - the state, the output, the water, its temperature, the EC at 25 C, the reading with the temperature and at 25 C, the analogRead value, the probe's cell factor and the range - and the last four events.

The six presets of the water
PresetTDSThe water
DISTILLED2 ppmdistilled water
RO18 ppmfrom a reverse osmosis filter
TAP250 ppmtap water
MINERAL420 ppmmineral water
BUFFER707 ppmthe 1413 uS/cm calibration solution
SEA35000 ppmsea water, far above the range

The actions change the water the way real life does. SALT is a pinch of salt: +100 ppm as it mixes. DILUTE pours as much distilled water again: half the TDS. PROBE OUT lifts the probe out of the water, and WARM warms the water to 40 C. A second click puts the probe back or lets the water cool again. The red X closes the STATUS panel, and the PANEL button on the board opens it again:

TDS meter in Proteus with its STATUS panel closed by the red X
Figure: The STATUS panel closed with its red X: only the board and the beaker stay, with PANEL: OFF on the board.

The Advance device keeps the schematic clean: only the board and the beaker. The live data opens in a pop-up window at Run, and the OPEN PANEL button on the board brings the window back:

TDS meter in Proteus as an Advance device
Figure: Node 2 up close: U2, the TDS meter as an Advance device, with OPEN PANEL on its board, in a 707 ppm buffer.

The properties set the water at the start: TDS in ppm at 25 C (250 by default) and TEMP in C (25), and the probe's CELL factor (1.0 means the probe follows the conversion exactly; 0.92 reads 8 % low, 1.05 reads 5 % high). The Simple device also has PANEL (open or closed). Every run starts again from the properties.

The Demo Circuit

TDS sensor Proteus simulation: two Arduino UNO V4.0 boards and two TDS meters on A0
Figure: The demo project running: node 1 with a Simple TDS meter in tap water, node 2 with an Advance one in a 707 ppm buffer at 20 C.

The demo project has two nodes, each an Arduino UNO V4.0 from our Arduino UNO Library for Proteus V4.0 with a TDS meter on A0. Node 1 is tap water, 250 ppm at 25 C, with a probe that follows the conversion. Node 2 is a 707 ppm calibration buffer at 20 C, and its probe is a little different: cell factor 0.92, it reads 8 % low - the kind of probe you calibrate. Both UNOs run the same TDS_Water_Demo.hex.

TDS meter demo project in Proteus edit mode: the two nodes before the simulation runs
Figure: The same project before Run: the STATUS panel waiting for the simulation.

Wiring

The wiring of the two nodes (in Proteus and on a real board)
TDS board pinArduino UNOIn the demo
+ (VCC)5V (the board takes 3.3 - 5.5 V)a VCC terminal
- (GND)GNDa GND terminal
AA0 (any analog input)A0 through the labels TDS_1 and TDS_2

In Proteus the A pin reaches its UNO through a net label - TDS_1 for node 1 and TDS_2 for node 2 - and VCC and GND are power terminals. The serial monitor needs no wires at all, because it is built into the UNO V4.0.

The Arduino Code

The demo sketch needs no library. New to Arduino? Start with Arduino Tutorial for Beginners and Introduction to Arduino UNO. The pin, the reference voltage and the number of readings:

const byte TDS_PIN = A0;                      // the board's A (analog) pin
const float VREF = 5.0;                       // the UNO's ADC reference
const byte SAMPLES = 30;

Every 40 ms loop() takes a reading and puts it into a ring of 30, and once a second it reports:

  if (now - lastSample >= 40) {
    lastSample = now;
    readings[next] = analogRead(TDS_PIN);
    next = (next + 1) % SAMPLES;
    if (filled < SAMPLES) filled++;
  }
  if (now - lastReport >= 1000 && filled > 0) {
    lastReport = now;
    report();
  }
  while (Serial.available()) {

The Median of 30 Readings

A single analog reading can be off by a step or two - noise on the board, a spike on the supply, a bubble on the probe. The sketch sorts a copy of the last 30 readings and takes the one in the middle. Unlike an average, one wild reading cannot move the median:

int medianOf(int *a, byte n) {                // the middle of a sorted copy: one wrong reading cannot move it
  int s[SAMPLES];
  for (byte i = 0; i < n; i++) s[i] = a[i];
  for (byte i = 1; i < n; i++) {
    int v = s[i];
    byte j = i;
    while (j > 0 && s[j - 1] > v) { s[j] = s[j - 1]; j--; }
    s[j] = v;
  }
  return s[n / 2];
}

The Conversion

tdsOf() is the whole TDS meter in four lines: the temperature compensation, the published cubic, no negative conductivity, and half of the EC times K, the calibration factor:

float tdsOf(float volts, float k) {           // the board's conversion with the temperature compensation
  float c = volts / (1.0 + 0.02 * (waterTemp - 25.0));
  float ec = 133.42 * c * c * c - 255.86 * c * c + 857.39 * c;
  if (ec < 0) ec = 0;
  return ec * 0.5 * k;
}

report() takes the median (or, with FILTER 0, the newest reading), turns it into volts with the 5 V reference and prints the line. Two warnings follow the numbers: below 0.01 V the probe is probably in air, and above 2.25 V the water is over the range:

  if (volts < 0.01) Serial.print(F("  - probe in air?"));
  else if (volts > 2.25) Serial.print(F("  - over the range"));

The Commands

TEMP x gives the sketch the water's temperature (a real project reads it from a waterproof temperature probe). CAL x calibrates the probe in a solution of x ppm: it works out what the probe reads with K 1 and makes K the ratio:

  } else if (!strncmp(c, "CAL ", 4)) {
    float ppm = atof(c + 4);
    float raw = tdsOf(lastVolts, 1.0);
    if (ppm > 0 && raw > 1) {
      kValue = ppm / raw;
      Serial.print(F("K = "));
      Serial.print(kValue, 3);
      Serial.print(F(" (the solution "));
      Serial.print(ppm, 0);
      Serial.print(F(" ppm, the reading "));
      Serial.print(raw, 0);
      Serial.println(F(" ppm with K 1)"));
    } else Serial.println(F("CAL x: put the probe in a solution of x ppm first"));

K x sets K by hand, FILTER 0 reports single readings instead of the median and FILTER 1 brings the median back. The HEX file is in the package, so you do not need the Arduino IDE to run the demo. To change the sketch, open it in the Arduino IDE and export the compiled binary, as in How to get the HEX file from Arduino. It needs 8,312 bytes of flash and 354 bytes of RAM.

The Serial Monitor: Tap Water

TDS sensor readings in the built-in serial monitor of the Arduino UNO V4.0
Figure: ARD1's monitor: the header, then tap water - ADC 137, 0.669 V, 249 ppm and EC 499 uS/cm every second.

Both UNOs have the serial monitor built in, and it opens at Run. The screenshots use its Simple interface. The sketch prints its header and the commands, and a report arrives every second:

TEP TDS meter - demo V1.0
The board's output on A0: a reading every 40 ms, the median of 30 each second, 25.0 C, K 1
Commands: TEMP x (water C), CAL x (ppm of the solution), K x, FILTER 0 / 1, HELP
#1  t=1 s  ADC 111  0.542 V  25.0 C  TDS 205 ppm  EC 411 uS/cm
#2  t=2 s  ADC 134  0.654 V  25.0 C  TDS 244 ppm  EC 489 uS/cm
#3  t=3 s  ADC 137  0.669 V  25.0 C  TDS 249 ppm  EC 499 uS/cm
#4  t=4 s  ADC 137  0.669 V  25.0 C  TDS 249 ppm  EC 499 uS/cm
#5  t=5 s  ADC 137  0.669 V  25.0 C  TDS 249 ppm  EC 499 uS/cm

From the third second node 1 reads 249 ppm for 250 ppm of tap water: ADC 137 is 0.669 V, and one ADC step here is about 2 ppm, so the last ppm is simply the resolution of the UNO's 10-bit converter. The first two reports are lower because their median still holds readings from the moment the board was switched on, while its output rose.

TDS meter reading a 707 ppm buffer as 566 ppm at the wrong temperature
Figure: ARD2's monitor: the same sketch reads the 707 ppm buffer as 566 ppm - the water is at 20 C, the sketch assumes 25 C.
#1  t=1 s  ADC 243  1.187 V  25.0 C  TDS 440 ppm  EC 880 uS/cm
#2  t=2 s  ADC 294  1.436 V  25.0 C  TDS 549 ppm  EC 1098 uS/cm
#3  t=3 s  ADC 301  1.470 V  25.0 C  TDS 566 ppm  EC 1131 uS/cm
#4  t=4 s  ADC 301  1.470 V  25.0 C  TDS 566 ppm  EC 1131 uS/cm
#5  t=5 s  ADC 301  1.470 V  25.0 C  TDS 566 ppm  EC 1131 uS/cm

Node 2 stands in a 707 ppm buffer, yet the sketch reads 566 ppm, 20 % too little. Two things are wrong at once: the water is at 20 C while the sketch assumes 25 C, and this probe reads 8 % low. Let's fix both.

The Advance Pop-Up Window

At Run, U2 opens its own window, TDS Meter, with the look of our TEP Serial Monitor Advance for Proteus. It has three tabs, Sensor, Event log and Tests, plus Settings and Help behind the gear and question mark icons. The status bar at the bottom always shows the water, the output and the reading.

TDS meter Advance pop-up with a 707 ppm buffer at 20 C
Figure: U2 at the start: a 707 ppm buffer at 20 C - 1.478 V on A; a sketch at 25 C reads 570 ppm, with 20 C 654 ppm.

The toolbar carries the presets. The water at the probe has -100 / -10 / +10 / +100 ppm, -5 / -1 / +1 / +5 C, the actions and the ruler. What the board gives shows the banner and four tiles: the output on A with its analogRead value, the reading with the water's temperature, the reading of a sketch that assumes 25 C, and the EC. The conversion draws the published curve at 25 C in grey and the curve for this water's temperature in blue, with the point where the output is right now, and the last 150 s plots the water (green) and the reading (blue dots). The amber banner already says it: with 25 C a sketch reads 570 ppm, with 20 C 654 ppm - and the water has 707. The numbers move by a ppm or two from second to second, with the noise of the board.

Temperature & Calibration

TDS meter Temperature and calibration test tool: the water at 20 C and a probe that reads 8 % low
Figure: Temperature and calibration on U2: a sketch at 25 C reads 13 % low; with the temperature 651 ppm; the probe reads 8 % low.

The Temperature & calibration tool splits the error into its two parts. The water is at 20 C, so its EC is 1273 uS/cm instead of the 1414 it has at 25 C, and a sketch at 25 C reads 13 % low. With the temperature the reading is 651 ppm - and the rest is the probe: cell factor 0.92, it reads 8 % low. The tool also explains CAL: K = the solution / the reading with K 1, here about 1.09.

TEMP 20 and CAL 707

So we typed TEMP 20 in ARD2's monitor, waited a few seconds, and then CAL 707, because the probe stands in the 707 ppm buffer:

TDS meter calibrated with TEMP 20 and CAL 707: K = 1.084, then 707 ppm
Figure: ARD2's monitor: TEMP 20 lifts the reading to 652 ppm, CAL 707 gives K = 1.084, and the buffer reads 704 - 707 ppm.
TEMP 20
water temperature: 20.0 C
#11  t=11 s  ADC 302  1.475 V  20.0 C  TDS 652 ppm  EC 1305 uS/cm
#12  t=12 s  ADC 302  1.475 V  20.0 C  TDS 652 ppm  EC 1305 uS/cm
#13  t=13 s  ADC 302  1.475 V  20.0 C  TDS 652 ppm  EC 1305 uS/cm
#14  t=14 s  ADC 302  1.475 V  20.0 C  TDS 652 ppm  EC 1305 uS/cm
CAL 707
K = 1.084 (the solution 707 ppm, the reading 652 ppm with K 1)
#15  t=15 s  ADC 301  1.470 V  20.0 C  TDS 704 ppm  EC 1408 uS/cm
#16  t=16 s  ADC 302  1.475 V  20.0 C  TDS 707 ppm  EC 1414 uS/cm
#17  t=17 s  ADC 301  1.470 V  20.0 C  TDS 704 ppm  EC 1408 uS/cm
#18  t=18 s  ADC 301  1.470 V  20.0 C  TDS 704 ppm  EC 1408 uS/cm

TEMP 20 brings the reading from 566 to 652 ppm: the temperature compensation did its part. CAL 707 then works out K = 1.084 from the last reading, 652 ppm, and from the next second on the buffer reads 704 - 707 ppm and EC 1408 - 1414 uS/cm - the 1413 uS/cm of the label, give or take one ADC step. The pop-up shows the board's side: its banner still compares 25 C and 20 C with K 1, because the K lives in the sketch:

TDS meter pop-up after the calibration in the 707 ppm buffer
Figure: U2 after CAL 707: the same water and 1.470 V - the pop-up reads 649 ppm with K 1; the sketch's K is its own.

Output & Conversion

TDS meter Output and conversion test tool: the conversion step by step
Figure: Output and conversion on U2: 1.467 V, the temperature step to 1.630 V, 1296 uS/cm and 648 ppm.

The Output & conversion tool does the sketch's maths step by step, with the numbers of this moment: 1.467 V is about 300 in analogRead; divided by 1 + 0.02 x (20 - 25) it becomes 1.630 V; the cubic gives 1296 uS/cm; half of that is 648 ppm. It also shows how much one ADC step is worth here - 2.95 ppm - and whether the output is inside the range. Open it first when a reading is far off.

Tap Water and a Pinch of Salt

Now the water. We clicked TAP in U2's pop-up, waited, and then SALT:

TDS meter pop-up in tap water at 20 C
Figure: U2 in tap water: 250 ppm at 20 C, 0.555 V; with K 1 the probe reads 232 ppm with the temperature, 210 ppm at 25 C.
TDS meter pop-up after a pinch of salt
Figure: U2 after SALT: the salt mixes in - 348 of the 350 ppm so far.
TDS meter readings as tap water replaces the buffer and the salt mixes in
Figure: ARD2's monitor: the buffer, then tap water - 249 ppm - and the salt mixing in up to 346 ppm.
#20  t=20 s  ADC 301  1.470 V  20.0 C  TDS 704 ppm  EC 1408 uS/cm
#21  t=21 s  ADC 176  0.859 V  20.0 C  TDS 380 ppm  EC 760 uS/cm
#22  t=22 s  ADC 117  0.571 V  20.0 C  TDS 258 ppm  EC 515 uS/cm
#23  t=23 s  ADC 113  0.552 V  20.0 C  TDS 249 ppm  EC 499 uS/cm
#24  t=24 s  ADC 113  0.552 V  20.0 C  TDS 249 ppm  EC 499 uS/cm
#25  t=25 s  ADC 113  0.552 V  20.0 C  TDS 249 ppm  EC 499 uS/cm
#26  t=26 s  ADC 123  0.601 V  20.0 C  TDS 270 ppm  EC 540 uS/cm
#27  t=27 s  ADC 141  0.688 V  20.0 C  TDS 307 ppm  EC 613 uS/cm
#28  t=28 s  ADC 150  0.732 V  20.0 C  TDS 325 ppm  EC 650 uS/cm
#29  t=29 s  ADC 156  0.762 V  20.0 C  TDS 338 ppm  EC 675 uS/cm
#30  t=30 s  ADC 158  0.771 V  20.0 C  TDS 342 ppm  EC 684 uS/cm
#31  t=31 s  ADC 160  0.781 V  20.0 C  TDS 346 ppm  EC 692 uS/cm

The calibrated sketch reads tap water as 249 ppm. Then the salt: the reading climbs over about five seconds to 346 ppm, as a real pinch of salt dissolves and spreads. Notice #21 and #26: the output itself follows the water within about half a second, but each report is the median of the last 30 readings, so it lags by up to a second.

DILUTE

Then DILUTE - as much distilled water again:

TDS meter readings after the water is diluted with distilled water
Figure: ARD2's monitor: DILUTE halves the 350 ppm - the reading falls from 346 to 179 ppm and on towards 175.
#32  t=32 s  ADC 160  0.781 V  20.0 C  TDS 346 ppm  EC 692 uS/cm
#33  t=33 s  ADC 143  0.698 V  20.0 C  TDS 311 ppm  EC 621 uS/cm
#34  t=34 s  ADC 114  0.557 V  20.0 C  TDS 251 ppm  EC 503 uS/cm
#35  t=35 s  ADC 97  0.474 V  20.0 C  TDS 217 ppm  EC 433 uS/cm
#36  t=36 s  ADC 86  0.420 V  20.0 C  TDS 194 ppm  EC 388 uS/cm
#37  t=37 s  ADC 82  0.400 V  20.0 C  TDS 186 ppm  EC 371 uS/cm
#38  t=38 s  ADC 79  0.386 V  20.0 C  TDS 179 ppm  EC 359 uS/cm

Half of 350 is 175, and the reading settles there: 179 ppm at #38 and still falling. In the real world this is how you check a meter for linearity: dilute a solution by a known factor and the reading must follow.

WARM: Why the Temperature Matters

Now WARM: the water warms from 20 to 40 C over some seconds. The water's TDS does not change at all - only its temperature:

TDS meter pop-up with the water warming to 40 C
Figure: U2 with WARM: 175 ppm at 39.0 C - with K 1 a sketch at 25 C reads 202 ppm, with the water's temperature 161 ppm.
TDS meter readings drifting up as the water warms
Figure: ARD2's monitor: the sketch still says 20.0 C, and the reading drifts from 231 to 241 ppm as the water warms.
#52  t=52 s  ADC 104  0.508 V  20.0 C  TDS 231 ppm  EC 462 uS/cm
#53  t=53 s  ADC 105  0.513 V  20.0 C  TDS 233 ppm  EC 466 uS/cm
#54  t=54 s  ADC 105  0.513 V  20.0 C  TDS 233 ppm  EC 466 uS/cm
#55  t=55 s  ADC 106  0.518 V  20.0 C  TDS 235 ppm  EC 470 uS/cm
#56  t=56 s  ADC 106  0.518 V  20.0 C  TDS 235 ppm  EC 470 uS/cm
#57  t=57 s  ADC 107  0.522 V  20.0 C  TDS 237 ppm  EC 474 uS/cm
#58  t=58 s  ADC 107  0.522 V  20.0 C  TDS 237 ppm  EC 474 uS/cm
#59  t=59 s  ADC 108  0.527 V  20.0 C  TDS 239 ppm  EC 478 uS/cm
#60  t=60 s  ADC 108  0.527 V  20.0 C  TDS 239 ppm  EC 478 uS/cm
#61  t=61 s  ADC 108  0.527 V  20.0 C  TDS 239 ppm  EC 478 uS/cm
#62  t=62 s  ADC 109  0.532 V  20.0 C  TDS 241 ppm  EC 482 uS/cm
#63  t=63 s  ADC 109  0.532 V  20.0 C  TDS 241 ppm  EC 482 uS/cm

The sketch still believes the water is at 20 C, and the reading drifts up to 241 ppm for 175 ppm of water - 38 % too much. Warm water conducts better, and without the right temperature that looks like more salt. It is the most common reason why a TDS reading wanders during the day. We typed TEMP 40:

SEA: Over the Range

TDS meter with TEMP 40 and then sea water over the range
Figure: ARD2's monitor: TEMP 40 gives 172 - 173 ppm; then SEA - 2.295 V and 786 ppm with "over the range".
#63  t=63 s  ADC 109  0.532 V  20.0 C  TDS 241 ppm  EC 482 uS/cm
TEMP 40
water temperature: 40.0 C
#64  t=64 s  ADC 109  0.532 V  40.0 C  TDS 172 ppm  EC 344 uS/cm
#65  t=65 s  ADC 110  0.537 V  40.0 C  TDS 173 ppm  EC 347 uS/cm
#66  t=66 s  ADC 109  0.532 V  40.0 C  TDS 172 ppm  EC 344 uS/cm
#67  t=67 s  ADC 110  0.537 V  40.0 C  TDS 173 ppm  EC 347 uS/cm
#68  t=68 s  ADC 300  1.465 V  40.0 C  TDS 451 ppm  EC 902 uS/cm
#69  t=69 s  ADC 457  2.231 V  40.0 C  TDS 755 ppm  EC 1509 uS/cm
#70  t=70 s  ADC 470  2.295 V  40.0 C  TDS 786 ppm  EC 1572 uS/cm  - over the range

With TEMP 40 the reading is 172 - 173 ppm again: right, within the 2 % per degree of the compensation and one ADC step. Then we clicked SEA, 35000 ppm. The output climbs to 2.300 V and stops there, and the sketch prints "over the range". The reading, 786 - 788 ppm at 40 C, means nothing: the probe cannot tell sea water from brine. The pop-up turns red:

TDS meter pop-up in sea water: above the range, the output stops at 2.3 V
Figure: U2 in sea water: 35000 ppm is above the range - the output stops at 2.3 V, about 1121 ppm at 25 C.

Wiring & Range

TDS meter Wiring and range test tool: the power, the A pin, the probe and the range
Figure: Wiring and range on U2 in sea water: the power, the A pin, the probe in the water, and the range in red.

The Wiring & range tool checks the power - 5.00 V on +, about 4.5 mA - the A pin, the probe and the range. Its tips cover the two classic puzzles: a reading of 0 ppm (a dry probe, an unplugged probe or distilled water) and a reading stuck near 1120 ppm (too much salt for the probe).

PROBE OUT

Back to TAP, and then PROBE OUT - somebody lifts the probe out of the water:

TDS meter pop-up with the probe in air: about 0 V and 0 ppm
Figure: U2 with PROBE OUT: the probe is in air - 0.002 V on A, read as 1 ppm.
TDS meter reading a dry probe: probe in air? in the serial monitor
Figure: ARD2's monitor: sea water, tap water, then the probe in air - 5 and then 2 ppm with "probe in air?".
#71  t=71 s  ADC 471  2.300 V  40.0 C  TDS 788 ppm  EC 1577 uS/cm  - over the range
#72  t=72 s  ADC 471  2.300 V  40.0 C  TDS 788 ppm  EC 1577 uS/cm  - over the range
#73  t=73 s  ADC 471  2.300 V  40.0 C  TDS 788 ppm  EC 1577 uS/cm  - over the range
#74  t=74 s  ADC 208  1.016 V  40.0 C  TDS 313 ppm  EC 626 uS/cm
#75  t=75 s  ADC 166  0.811 V  40.0 C  TDS 253 ppm  EC 507 uS/cm
#76  t=76 s  ADC 29  0.142 V  40.0 C  TDS 49 ppm  EC 98 uS/cm
#77  t=77 s  ADC 3  0.015 V  40.0 C  TDS 5 ppm  EC 10 uS/cm
#78  t=78 s  ADC 1  0.005 V  40.0 C  TDS 2 ppm  EC 3 uS/cm  - probe in air?

In air no current flows between the pins, and the output falls to a few mV: 2 ppm and the sketch's warning "probe in air?". #77 still reads 5 ppm without the warning, because 0.015 V is above the sketch's limit of 0.01 V. A dry probe and distilled water look almost the same to a TDS meter, so the warning comes with a question mark.

The Event Log

TDS meter Advance pop-up Event log in Proteus: the readings, the water and a warning, newest first
Figure: The Event log of U2: a reading every 5 seconds, every change of the water, a note and a warning, newest first.

The Event log lists everything that happened, newest first: power, a reading every 5 seconds with the output, the analogRead value and the conversion with and without the temperature, every change of the water, notes and warnings - here the whole story of node 2 backwards, from the probe back in the water, PROBE OUT and the sea water warning down to the power-on. Filter it, pause it, or clear it.

FILTER 0: Single Readings

Back to node 1 in tap water. We typed FILTER 0 in ARD1's monitor:

TDS meter single readings without the median filter, in the serial monitor
Figure: ARD1's monitor: FILTER 0 - single readings of 251 and 249 ppm, ADC 138 and 137.
#81  t=81 s  ADC 138  0.674 V  25.0 C  TDS 251 ppm  EC 502 uS/cm
#82  t=82 s  ADC 137  0.669 V  25.0 C  TDS 249 ppm  EC 499 uS/cm
FILTER 0
filter: off - one reading
#83  t=83 s  ADC 138  0.674 V  25.0 C  TDS 251 ppm  EC 502 uS/cm
#84  t=84 s  ADC 138  0.674 V  25.0 C  TDS 251 ppm  EC 502 uS/cm
#85  t=85 s  ADC 138  0.674 V  25.0 C  TDS 251 ppm  EC 502 uS/cm
#86  t=86 s  ADC 138  0.674 V  25.0 C  TDS 251 ppm  EC 502 uS/cm
#87  t=87 s  ADC 138  0.674 V  25.0 C  TDS 251 ppm  EC 502 uS/cm
#88  t=88 s  ADC 137  0.669 V  25.0 C  TDS 249 ppm  EC 499 uS/cm

The single readings move between ADC 137 and 138 - 249 and 251 ppm - because the board's noise is a few mV and one ADC step is 4.9 mV. Here the output sits right on the border between two steps, so even the median flips now and then (#81 and #82). What the median really removes is the occasional wild reading - a spike on the supply or a bubble on the probe - and it costs nothing, so FILTER 1 brought it back.

The Water on the STATUS Panel

Then we clicked the buttons of U1's STATUS panel with the mouse while the simulation ran. First MINERAL:

TDS meter STATUS panel in Proteus in mineral water
Figure: U1 with MINERAL: 420 ppm of mineral water, 1.144 V on A, read as 423 ppm.
TDS meter reading mineral water in the serial monitor
Figure: ARD1's monitor: from 249 to 420 ppm within two reports.
#96  t=96 s  ADC 137  0.669 V  25.0 C  TDS 249 ppm  EC 499 uS/cm
#97  t=97 s  ADC 138  0.674 V  25.0 C  TDS 251 ppm  EC 502 uS/cm
#98  t=98 s  ADC 218  1.064 V  25.0 C  TDS 392 ppm  EC 784 uS/cm
#99  t=99 s  ADC 231  1.128 V  25.0 C  TDS 417 ppm  EC 833 uS/cm
#100  t=100 s  ADC 233  1.138 V  25.0 C  TDS 420 ppm  EC 841 uS/cm
#101  t=101 s  ADC 233  1.138 V  25.0 C  TDS 420 ppm  EC 841 uS/cm
#102  t=102 s  ADC 233  1.138 V  25.0 C  TDS 420 ppm  EC 841 uS/cm

Mineral water, 420 ppm: the reading follows in two reports, 392 and then 417, and settles at 420 ppm. It takes two reports because the median of the last 30 readings needs a moment to fill with the new water. The water in the beaker turns a little darker.

DISTILLED

TDS meter STATUS panel in Proteus in distilled water
Figure: U1 with DISTILLED: 2 ppm and 0.007 V on A - the water in the beaker turns pale.
TDS meter reading distilled water in the serial monitor
Figure: ARD1's monitor: distilled water reads 2 ppm, with the sketch's warning "probe in air?".
#102  t=102 s  ADC 233  1.138 V  25.0 C  TDS 420 ppm  EC 841 uS/cm
#103  t=103 s  ADC 233  1.138 V  25.0 C  TDS 420 ppm  EC 841 uS/cm
#104  t=104 s  ADC 141  0.688 V  25.0 C  TDS 256 ppm  EC 513 uS/cm
#105  t=105 s  ADC 13  0.063 V  25.0 C  TDS 27 ppm  EC 53 uS/cm
#106  t=106 s  ADC 2  0.010 V  25.0 C  TDS 4 ppm  EC 8 uS/cm  - probe in air?
#107  t=107 s  ADC 1  0.005 V  25.0 C  TDS 2 ppm  EC 4 uS/cm  - probe in air?
#108  t=108 s  ADC 1  0.005 V  25.0 C  TDS 2 ppm  EC 4 uS/cm  - probe in air?
#109  t=109 s  ADC 1  0.005 V  25.0 C  TDS 2 ppm  EC 4 uS/cm  - probe in air?

Distilled water has almost nothing dissolved in it, so it hardly conducts: 2 ppm, and the sketch even asks "probe in air?". Its 0.01 V limit cannot tell distilled water from a dry probe, and neither can a real meter. That is why the Wiring & range tool suggests a check with tap water when a reading is 0 ppm.

SALT and PROBE OUT on the Panel

Then SALT - a pinch of salt in the distilled water - and, a few seconds later, PROBE OUT:

TDS meter STATUS panel in Proteus after a pinch of salt
Figure: U1 after SALT in the distilled water: 102 ppm, read as 98 ppm while the salt mixes in.
TDS meter STATUS panel in Proteus with the probe in air
Figure: U1 with PROBE OUT: the water drops below the probe, the PROBE LED goes off and the panel says IN AIR.
TDS meter with a pinch of salt and then the probe in air, in the serial monitor of node 1
Figure: ARD1's monitor: the salt brings the distilled water to 100 ppm, PROBE OUT drops the reading to 0 ppm.
#110  t=110 s  ADC 1  0.005 V  25.0 C  TDS 2 ppm  EC 4 uS/cm  - probe in air?
#111  t=111 s  ADC 11  0.054 V  25.0 C  TDS 23 ppm  EC 45 uS/cm
#112  t=112 s  ADC 29  0.142 V  25.0 C  TDS 58 ppm  EC 117 uS/cm
#113  t=113 s  ADC 40  0.195 V  25.0 C  TDS 79 ppm  EC 159 uS/cm
#114  t=114 s  ADC 46  0.225 V  25.0 C  TDS 91 ppm  EC 181 uS/cm
#115  t=115 s  ADC 49  0.239 V  25.0 C  TDS 96 ppm  EC 192 uS/cm
#116  t=116 s  ADC 51  0.249 V  25.0 C  TDS 100 ppm  EC 200 uS/cm
#117  t=117 s  ADC 51  0.249 V  25.0 C  TDS 100 ppm  EC 200 uS/cm
#118  t=118 s  ADC 40  0.195 V  25.0 C  TDS 79 ppm  EC 159 uS/cm
#119  t=119 s  ADC 3  0.015 V  25.0 C  TDS 6 ppm  EC 13 uS/cm
#120  t=120 s  ADC 1  0.005 V  25.0 C  TDS 2 ppm  EC 4 uS/cm  - probe in air?
#121  t=121 s  ADC 0  0.000 V  25.0 C  TDS 0 ppm  EC 0 uS/cm  - probe in air?

The salt brings the reading from 2 to 100 ppm in about five seconds: the 2 ppm of the water and the 100 of the salt. Then PROBE OUT: the water in the beaker drops below the probe, the PROBE LED goes out, the panel says IN AIR in red, and the reading falls to 0 ppm. Finally the probe went back into the water, and the red X and the PANEL button closed and reopened the STATUS panel.

The Simulation Log

TDS meter Proteus simulation log: the start-up and the readings
Figure: The simulation log of the final run: both TDS meters at power-on, a reading every 5 seconds and the water of node 2.

The TDS meters also write to the simulation log of Proteus, with the exact simulation time. These lines show the start and the water of node 2:

U2: TEP TDS Meter V1.0 - analog TDS sensor, 0 - 2.3 V on A for 0 - about 1000 ppm; the water 707 ppm at 20.0 C, the probe's cell factor 0.92 - TEPTDS.DLL v1.0
U1: TEP TDS Meter V1.0 - analog TDS sensor, 0 - 2.3 V on A for 0 - about 1000 ppm; the water 250 ppm at 25.0 C, the probe's cell factor 1.00 - TEPTDS.DLL v1.0
U2: POWER ON - VCC 5.00 V: the probe's AC excitation runs, the output rises to 1.471 V (707 ppm at 20.0 C) at 0.0000 s
U1: POWER ON - VCC 5.00 V: the probe's AC excitation runs, the output rises to 0.670 V (250 ppm at 25.0 C) at 0.0000 s
U2: the output 1.469 V (analogRead about 300) - the conversion gives 649 ppm at 20.0 C, 565 ppm without the temperature at 5.0001 s
U1: the output 0.670 V (analogRead about 137) - the conversion gives 250 ppm at 25.0 C, 250 ppm without the temperature at 5.0001 s
U2: the water: TAP, 250 ppm (tap water at 20.0 C; in U2's pop-up) at 20.0001 s
U2: SALT: a pinch of salt - 350 ppm when it has mixed (in U2's pop-up) at 24.8001 s
U2: DILUTE: as much distilled water again - 175 ppm when it has mixed (in U2's pop-up) at 31.7501 s
U2: WARM: the water warms to 40 C (in U2's pop-up) at 38.6493 s
U2: the output 0.397 V (analogRead about 81) - the conversion gives 160 ppm at 23.1 C, 154 ppm without the temperature at 40.0002 s

Each meter reports its water and its probe's cell factor at the start - 707 ppm at 20 C with 0.92, and 250 ppm at 25 C with 1.00 - and the voltage its output rises to. Every 5 seconds follows a reading with the output, its analogRead value and the conversion with and without the temperature: for the buffer 649 ppm at 20 C, but 565 ppm without the temperature. Then come the changes of node 2's water. During WARM, at 40 s, the water was at 23.1 C on its way to 40 C, and the conversion gave 160 ppm - the 175 ppm of the water times the probe's 0.92.

How the Model Works

The TDS meter is an analog model. VCC and GND power the board and draw about 4.5 mA, and the A pin is a voltage source behind 1 kohm. For the water in the beaker the model works out the voltage the published conversion turns back into the water's TDS: the inverse of the cubic for EC = TDS / 0.5 times the probe's cell factor, plus 2 % per C away from 25 C, limited to 2.3 V. The output follows that voltage with a time constant of 0.4 s and gets 3 mV of noise. It changes in steps of 20 ms, and the model tells Proteus where each step falls, so the analog solver never has to guess. A pinch of salt or DILUTE mixes in with a time constant of 1.5 s, and WARM warms the water with a time constant of 8 s.

Troubleshooting

  • Always about 0 ppm: the probe is in air (PROBE OUT) or in distilled water, there is no power on + and -, or the sketch reads another pin.
  • A reading stuck near 1120 ppm (2.3 V): the water is above the range - sea water and brine all read the same.
  • Too high in warm water, too low in cold water: the sketch's temperature (TEMP x) is not the water's.
  • Two probes disagree by a few percent: their cell factors differ - calibrate each with CAL in a known solution.
  • The reading jumps by a few ppm: one ADC step is about 2 to 3 ppm here; keep the median filter on (FILTER 1).
  • No part or no monitor: TEPTDS.DLL or TEPARDUINO.DLL is missing from MODELS and the project folder; a closed monitor opens again with a click on the UNO's USB port.

Things to Know Before Using a Real TDS Meter

  • Power: 3.3 to 5.5 V and 3 to 6 mA; the output stays below 2.3 V, so a 3.3 V board can read it directly.
  • Temperature: measure the water's temperature with a waterproof temperature probe and give it to the conversion - conductivity changes about 2 % per C.
  • Calibration: calibrate each probe in a known solution, such as a 1413 uS/cm (707 ppm) buffer, at a known temperature, and rinse the probe in distilled water between solutions.
  • Two probes: a TDS probe and a pH probe powered from the same supply in the same water disturb each other; measure one at a time or isolate the supplies.
  • Water: the probe and its cable are waterproof, the board and the socket are not. The usual probe is rated up to about 55 C.

Limitations of the Simulation

  • Not modelled: the AC excitation itself and the polarisation of the electrodes, a dirty or ageing probe, bubbles on the pins, two probes in the same water, the kind of salt (the conversion assumes the usual factor of 0.5), the effect of the supply voltage on the output, and temperatures above 55 C.
  • The model's own choices: the cell factor (CELL), the lag of 0.4 s, the mixing of SALT and DILUTE in 1.5 s, the warming of WARM with 8 s, the noise of 3 mV with a new value every 20 ms, 2 mV in air, and the values of the presets.
  • The beaker, the badge, the LEDs, the panel button and the panels are TEP additions.
  • The model is our own, written from the board maker's published data. This library is not made or endorsed by the board's maker or by Labcenter.
  • Licences: the demo sketch uses no library; the HEX file contains the Arduino AVR core 1.8.6 with LGPL-licensed code - the source link is in the README.
  • Tested in Proteus 8.5 in October 2026 (the demo as shipped on two Arduino UNO V4.0 boards with their built-in monitors: TEMP 20 and CAL 707 in the buffer, TAP, SALT, DILUTE, WARM with TEMP 40, SEA, PROBE OUT and the three tools on the Advance meter; FILTER 0 and 1, MINERAL, DISTILLED, SALT, PROBE OUT, the red X and PANEL with the mouse on the Simple one; 137.1 s of simulation took 312 s, about 0.44 x real time with the pop-up and both monitors open). Proteus 7 is not supported.

So, that was all about the TDS Meter Library for Proteus V1.0. I hope the conversion from volts to ppm, the temperature compensation, the calibration in a buffer and the limits of the probe are clear now, and that your water quality project works from the first run. If you use the TDS Meter Library for Proteus in a project, please share it in the comments or in our forum, and if you have any questions, ask in the comments and I will help you out. Till the next tutorial, take care and have fun!


Comments

0

Join the conversation