{"id":109306,"date":"2022-04-06T18:50:24","date_gmt":"2022-04-06T18:50:24","guid":{"rendered":"https:\/\/randomnerdtutorials.com\/?p=109306"},"modified":"2022-04-21T14:11:55","modified_gmt":"2022-04-21T14:11:55","slug":"esp32-tds-water-quality-sensor","status":"publish","type":"post","link":"https:\/\/randomnerdtutorials.com\/esp32-tds-water-quality-sensor\/","title":{"rendered":"ESP32 with TDS Sensor (Water Quality Sensor)"},"content":{"rendered":"\n<p>In this guide, you&#8217;ll learn how to use a TDS meter (Total Dissolved Solids) with the ESP32. A TDS meter indicates the total dissolved solids like salts, minerals, and metals, in a solution. This parameter can be used to give you an idea of water quality and compare water from different sources. One of the main applications of a TDS meter is aquarium water quality monitoring.<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-full\"><img data-recalc-dims=\"1\" fetchpriority=\"high\" decoding=\"async\" width=\"1200\" height=\"675\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2022\/02\/ESP32-TDS-Sensor-Water-Quality-Sensor.jpg?resize=1200%2C675&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"ESP32 with TDS Sensor Water Quality Sensor Arduino\" class=\"wp-image-109571\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2022\/02\/ESP32-TDS-Sensor-Water-Quality-Sensor.jpg?w=1280&amp;quality=100&amp;strip=all&amp;ssl=1 1280w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2022\/02\/ESP32-TDS-Sensor-Water-Quality-Sensor.jpg?resize=300%2C169&amp;quality=100&amp;strip=all&amp;ssl=1 300w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2022\/02\/ESP32-TDS-Sensor-Water-Quality-Sensor.jpg?resize=1024%2C576&amp;quality=100&amp;strip=all&amp;ssl=1 1024w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2022\/02\/ESP32-TDS-Sensor-Water-Quality-Sensor.jpg?resize=768%2C432&amp;quality=100&amp;strip=all&amp;ssl=1 768w\" sizes=\"(max-width: 1200px) 100vw, 1200px\" \/><\/figure><\/div>\n\n\n\n<p>We&#8217;ll use the TDS meter from keystudio and show you a simple example to measure TDS in ppm units using Arduino IDE.<\/p>\n\n\n\n<p><strong>Table of Contents<\/strong><\/p>\n\n\n\n<p>In this tutorial, we&#8217;ll cover the following topics<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li><a href=\"#TDS-introduction\">Introducing the TDS Meter<\/a><\/li><li><a href=\"#ESP32-TDS-Wiring\">Interfacing the TDS Meter with the ESP32<\/a><\/li><li><a href=\"#ESP32-TDS-Meter-Code\">Reading TDS with the ESP32 &#8211; Arduino Code<\/a><\/li><\/ul>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"TDS-introduction\">Introducing the TDS Meter<\/h2>\n\n\n\n<p>A TDS meter measures the number of total dissolved solids like salts, minerals, and metals in the water. As the number of dissolved solids in the water increases, the conductivity of the water increases, and that allow us to calculate the total dissolved solids in ppm (mg\/L).<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-full\"><img data-recalc-dims=\"1\" decoding=\"async\" width=\"750\" height=\"481\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2022\/02\/TDS-meter-keystudio.jpg?resize=750%2C481&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"Total dissolved solids TDS meter\" class=\"wp-image-109566\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2022\/02\/TDS-meter-keystudio.jpg?w=750&amp;quality=100&amp;strip=all&amp;ssl=1 750w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2022\/02\/TDS-meter-keystudio.jpg?resize=300%2C192&amp;quality=100&amp;strip=all&amp;ssl=1 300w\" sizes=\"(max-width: 750px) 100vw, 750px\" \/><\/figure><\/div>\n\n\n\n<p>Although this is a good indicator to monitor the quality of the water, <strong>note that it does not measure contaminants in the water<\/strong>. Thus, you can&#8217;t rely solely on this indicator to determine if the water is good for consumption or not.<\/p>\n\n\n\n<p>A TDS meter can be useful to monitor water quality in many applications like pools, aquariums, fish tanks, hydroponics, water purifiers, etc.<\/p>\n\n\n\n<p>In this tutorial, we&#8217;ll use the TDS meter from keystudio that comes with an interface module and an electrode probe (see picture above).<\/p>\n\n\n\n<p>For more information about the TDS meter, we recommend taking a look at the <a href=\"https:\/\/wiki.keyestudio.com\/KS0429_keyestudio_TDS_Meter_V1.0\" target=\"_blank\" rel=\"noreferrer noopener\">official documentation<\/a>.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Features and Specifications<\/h3>\n\n\n\n<p>This tutorial refers to the TDS Meter V1.0 from keystudio. Here are the sensor parameters:<\/p>\n\n\n\n<p><strong>TDS Meter:<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>Input Voltage: DC 3.3 ~ 5.5V<\/li><li>Output Voltage: 0 ~ 2.3V<\/li><li>Working Current: 3 ~ 6mA<\/li><li>TDS Measurement Range: 0 ~ 1000ppm<\/li><li>TDS Measurement Accuracy: \u00b1 10% F.S. (25 \u2103)<\/li><li>Module Interface: XH2.54-3P<\/li><li>Electrode Interface: XH2.54-2P<\/li><\/ul>\n\n\n\n<p><strong>TDS Probe:<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>Number of Needle: 2<\/li><li>Total Length: 60cm<\/li><li>Connection Interface: XH2.54-2P<\/li><li>Color: White<\/li><li>Waterproof Probe<\/li><\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Where to Buy TDS Sensor?<\/h3>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-full\"><a href=\"https:\/\/makeradvisor.com\/tools\/tds-sensor\/\" target=\"_blank\" rel=\"noopener\"><img data-recalc-dims=\"1\" decoding=\"async\" width=\"263\" height=\"263\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2022\/03\/TDS-Sensor-263.jpg?resize=263%2C263&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"TDS sensor\" class=\"wp-image-109708\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2022\/03\/TDS-Sensor-263.jpg?w=263&amp;quality=100&amp;strip=all&amp;ssl=1 263w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2022\/03\/TDS-Sensor-263.jpg?resize=150%2C150&amp;quality=100&amp;strip=all&amp;ssl=1 150w\" sizes=\"(max-width: 263px) 100vw, 263px\" \/><\/a><\/figure><\/div>\n\n\n\n<p>You can check the TDS sensor on Maker Advisor&nbsp;to find the best price:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li><a href=\"https:\/\/makeradvisor.com\/tools\/tds-sensor\/\" target=\"_blank\" rel=\"noreferrer noopener\">TDS Sensor<\/a><\/li><\/ul>\n\n\n<p>You can use the preceding links or go directly to <a href=\"https:\/\/makeradvisor.com\/tools\/?utm_source=rnt&utm_medium=post&utm_campaign=post\" target=\"_blank\">MakerAdvisor.com\/tools<\/a> to find all the parts for your projects at the best price!<\/p><p style=\"text-align:center;\"><a href=\"https:\/\/makeradvisor.com\/tools\/?utm_source=rnt&utm_medium=post&utm_campaign=post\" target=\"_blank\"><img data-recalc-dims=\"1\" decoding=\"async\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2017\/10\/header-200.png?w=1200&#038;quality=100&#038;strip=all&#038;ssl=1\"><\/a><\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"ESP32-TDS-Wiring\"><span style=\"font-size: inherit;\">Interfacing the TDS Meter with the ESP32<\/span><\/h2>\n\n\n\n<p>The TDS meter outputs an analog signal that can be measured using an ADC pin on the ESP32. You can <a href=\"https:\/\/randomnerdtutorials.com\/esp32-pinout-reference-gpios\/\">check the ESP32 ADC pins here<\/a>.<\/p>\n\n\n\n<p>Wire the sensor as in the following table:<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table><tbody><tr><td><strong>TDS Sensor<\/strong><\/td><td><strong>ESP32<\/strong><\/td><\/tr><tr><td>GND<\/td><td>GND<\/td><\/tr><tr><td>VCC<\/td><td>3.3V<\/td><\/tr><tr><td>Data<\/td><td>GPIO 27 (or any other <a href=\"https:\/\/randomnerdtutorials.com\/esp32-adc-analog-read-arduino-ide\/\">ESP32 ADC pin<\/a>)<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"ESP32-TDS-Meter-Code\">Reading TDS (water quality) with the ESP32 &#8211; Code<\/h2>\n\n\n\n<p>As we mentioned previously, the sensor outputs an analog signal that can be converted to TDS in ppm. We&#8217;re using the code provided by the <a href=\"https:\/\/wiki.keyestudio.com\/KS0429_keyestudio_TDS_Meter_V1.0\" target=\"_blank\" rel=\"noreferrer noopener\">sensor documentation<\/a> with some modifications. <\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-full\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"750\" height=\"422\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2022\/02\/ESP32-TDS-Sensor.jpg?resize=750%2C422&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"ESP32 with TDS sensor water quality\" class=\"wp-image-109569\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2022\/02\/ESP32-TDS-Sensor.jpg?w=750&amp;quality=100&amp;strip=all&amp;ssl=1 750w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2022\/02\/ESP32-TDS-Sensor.jpg?resize=300%2C169&amp;quality=100&amp;strip=all&amp;ssl=1 300w\" sizes=\"(max-width: 750px) 100vw, 750px\" \/><\/figure><\/div>\n\n\n\n<p>To get more accurate results, you&#8217;ll probably need to calibrate your sensor against a solution with a known TDS value. Also, take into account the non-linearity of the ESP32 ADC when it comes to low and high values. <\/p>\n\n\n\n<p>However, these adjustments might be not needed if you are not concerned about specific values but about a qualitative value of TDS.<\/p>\n\n\n\n<p>Upload the following code to your ESP32.<\/p>\n\n\n<pre style=\"max-height: 40em; margin-bottom: 20px;\"><code class=\"language-c\">\/\/ Original source code: https:\/\/wiki.keyestudio.com\/KS0429_keyestudio_TDS_Meter_V1.0#Test_Code\n\/\/ Project details: https:\/\/RandomNerdTutorials.com\/esp32-tds-water-quality-sensor\/\n\n#define TdsSensorPin 27\n#define VREF 3.3              \/\/ analog reference voltage(Volt) of the ADC\n#define SCOUNT  30            \/\/ sum of sample point\n\nint analogBuffer[SCOUNT];     \/\/ store the analog value in the array, read from ADC\nint analogBufferTemp[SCOUNT];\nint analogBufferIndex = 0;\nint copyIndex = 0;\n\nfloat averageVoltage = 0;\nfloat tdsValue = 0;\nfloat temperature = 25;       \/\/ current temperature for compensation\n\n\/\/ median filtering algorithm\nint getMedianNum(int bArray[], int iFilterLen){\n  int bTab[iFilterLen];\n  for (byte i = 0; i&lt;iFilterLen; i++)\n  bTab[i] = bArray[i];\n  int i, j, bTemp;\n  for (j = 0; j &lt; iFilterLen - 1; j++) {\n    for (i = 0; i &lt; iFilterLen - j - 1; i++) {\n      if (bTab[i] &gt; bTab[i + 1]) {\n        bTemp = bTab[i];\n        bTab[i] = bTab[i + 1];\n        bTab[i + 1] = bTemp;\n      }\n    }\n  }\n  if ((iFilterLen &amp; 1) &gt; 0){\n    bTemp = bTab[(iFilterLen - 1) \/ 2];\n  }\n  else {\n    bTemp = (bTab[iFilterLen \/ 2] + bTab[iFilterLen \/ 2 - 1]) \/ 2;\n  }\n  return bTemp;\n}\n\nvoid setup(){\n  Serial.begin(115200);\n  pinMode(TdsSensorPin,INPUT);\n}\n\nvoid loop(){\n  static unsigned long analogSampleTimepoint = millis();\n  if(millis()-analogSampleTimepoint &gt; 40U){     \/\/every 40 milliseconds,read the analog value from the ADC\n    analogSampleTimepoint = millis();\n    analogBuffer[analogBufferIndex] = analogRead(TdsSensorPin);    \/\/read the analog value and store into the buffer\n    analogBufferIndex++;\n    if(analogBufferIndex == SCOUNT){ \n      analogBufferIndex = 0;\n    }\n  }   \n  \n  static unsigned long printTimepoint = millis();\n  if(millis()-printTimepoint &gt; 800U){\n    printTimepoint = millis();\n    for(copyIndex=0; copyIndex&lt;SCOUNT; copyIndex++){\n      analogBufferTemp[copyIndex] = analogBuffer[copyIndex];\n      \n      \/\/ read the analog value more stable by the median filtering algorithm, and convert to voltage value\n      averageVoltage = getMedianNum(analogBufferTemp,SCOUNT) * (float)VREF \/ 4096.0;\n      \n      \/\/temperature compensation formula: fFinalResult(25^C) = fFinalResult(current)\/(1.0+0.02*(fTP-25.0)); \n      float compensationCoefficient = 1.0+0.02*(temperature-25.0);\n      \/\/temperature compensation\n      float compensationVoltage=averageVoltage\/compensationCoefficient;\n      \n      \/\/convert voltage value to tds value\n      tdsValue=(133.42*compensationVoltage*compensationVoltage*compensationVoltage - 255.86*compensationVoltage*compensationVoltage + 857.39*compensationVoltage)*0.5;\n      \n      \/\/Serial.print(&quot;voltage:&quot;);\n      \/\/Serial.print(averageVoltage,2);\n      \/\/Serial.print(&quot;V   &quot;);\n      Serial.print(&quot;TDS Value:&quot;);\n      Serial.print(tdsValue,0);\n      Serial.println(&quot;ppm&quot;);\n    }\n  }\n}\n<\/code><\/pre>\n\t<p style=\"text-align:center\"><a class=\"rntwhite\" href=\"https:\/\/github.com\/RuiSantosdotme\/Random-Nerd-Tutorials\/raw\/master\/Projects\/ESP32\/ESP32_TDS_Sensor.ino\" target=\"_blank\">View raw code<\/a><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">How the Code Works<\/h2>\n\n\n\n<p>Let&#8217;s take a quick look at the code. You can also skip right away to the <a href=\"#demonstration\">Demonstration <\/a>section.<\/p>\n\n\n\n<p>The <span class=\"rnthl rntliteral\">TdsSensorPin<\/span> variable saves the GPIO where you want to get the readings. We chose GPIO27, but you can use any other ADC pin.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>#define TdsSensorPin 27<\/code><\/pre>\n\n\n\n<p>Then, insert the analog voltage reference for the ADC. For the ESP32 is 3.3V, for an Arduino, for example, it is 5V.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>#define VREF 3.3    \/\/ analog reference voltage(Volt) of the ADC<\/code><\/pre>\n\n\n\n<p>Before getting a measurement value, we&#8217;ll apply a median filtering algorithm to get a more stable value. The <span class=\"rnthl rntliteral\">SCOUNT<\/span> variable refers to the number of samples we&#8217;ll filter before getting an actual value.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>#define SCOUNT  30  \/\/ sum of sample point<\/code><\/pre>\n\n\n\n<p>Then, we need some arrays to store the readings as well as some index variables that will allow us to go through the arrays.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>int analogBuffer&#091;SCOUNT];     \/\/ store the analog value in the array, read from ADC\nint analogBufferTemp&#091;SCOUNT];\nint analogBufferIndex = 0;\nint copyIndex = 0;<\/code><\/pre>\n\n\n\n<p>Initialize the <span class=\"rnthl rntliteral\">averageVoltage<\/span> variable and <span class=\"rnthl rntliteral\">tsdValue<\/span> as float variables.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>float averageVoltage = 0;\nfloat tdsValue = 0;<\/code><\/pre>\n\n\n\n<p>The <span class=\"rnthl rntliteral\">temperature<\/span> variable saves the current temperature value. The temperature influences the readings, so there is an algorithm that compensates for fluctuations in temperature. In this example, the reference temperature is 25\u00baC, but you can change it depending on your environment. For more accurate results, you can add a temperature sensor and get the actual temperature at the time of reading the sensor.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>float temperature = 25;       \/\/ current temperature for compensation<\/code><\/pre>\n\n\n\n<p>The following function will be used to get a stable TDS value from an array of readings.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>\/\/ median filtering algorithm\nint getMedianNum(int bArray&#091;], int iFilterLen){\n  int bTab&#091;iFilterLen];\n  for (byte i = 0; i&lt;iFilterLen; i++)\n  bTab&#091;i] = bArray&#091;i];\n  int i, j, bTemp;\n  for (j = 0; j &lt; iFilterLen - 1; j++) {\n    for (i = 0; i &lt; iFilterLen - j - 1; i++) {\n      if (bTab&#091;i] &gt; bTab&#091;i + 1]) {\n        bTemp = bTab&#091;i];\n        bTab&#091;i] = bTab&#091;i + 1];\n        bTab&#091;i + 1] = bTemp;\n      }\n    }\n  }\n  if ((iFilterLen &amp; 1) &gt; 0){\n    bTemp = bTab&#091;(iFilterLen - 1) \/ 2];\n  }\n  else {\n    bTemp = (bTab&#091;iFilterLen \/ 2] + bTab&#091;iFilterLen \/ 2 - 1]) \/ 2;\n  }\n  return bTemp;\n}<\/code><\/pre>\n\n\n\n<p>In the <span class=\"rnthl rntliteral\">setup()<\/span>, initialize the Serial Monitor at a baud rate of 115200.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>Serial.begin(115200);<\/code><\/pre>\n\n\n\n<p>Set the TDS sensor pin as an input.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>pinMode(TdsSensorPin,INPUT);<\/code><\/pre>\n\n\n\n<p>In the <span class=\"rnthl rntliteral\">loop()<\/span>, get new TDS readings every 40 milliseconds and save them in the buffer:<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>static unsigned long analogSampleTimepoint = millis();\nif(millis()-analogSampleTimepoint &gt; 40U){     \/\/every 40 milliseconds,read the analog value from the ADC\n  analogSampleTimepoint = millis();\n  analogBuffer&#091;analogBufferIndex] = analogRead(TdsSensorPin);    \/\/read the analog value and store into the buffer\n  analogBufferIndex++;\n  if(analogBufferIndex == SCOUNT){ \n    analogBufferIndex = 0;\n  }\n}   <\/code><\/pre>\n\n\n\n<p>Every 800 milliseconds, it gets the latest readings and gets the average voltage by using the filtering algorithm created before:<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>static unsigned long printTimepoint = millis();\nif(millis()-printTimepoint &gt; 800U){\n  printTimepoint = millis();\n  for(copyIndex=0; copyIndex&lt;SCOUNT; copyIndex++){\n    analogBufferTemp&#091;copyIndex] = analogBuffer&#091;copyIndex];\n      \n    \/\/ read the analog value more stable by the median filtering algorithm, and convert to voltage value\n    averageVoltage = getMedianNum(analogBufferTemp,SCOUNT) * (float)VREF \/ 4096.0;<\/code><\/pre>\n\n\n\n<p>Then, it calculates a temperature compensation coefficient and calculates the TDS value taking that value into account:<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>\/\/temperature compensation formula: fFinalResult(25^C) = fFinalResult(current)\/(1.0+0.02*(fTP-25.0)); \nfloat compensationCoefficient = 1.0+0.02*(temperature-25.0);\n\/\/temperature compensation\nfloat compensationVoltage=averageVoltage\/compensationCoefficient;\n      \n\/\/convert voltage value to tds value\ntdsValue=(133.42*compensationVoltage*compensationVoltage*compensationVoltage - 255.86*compensationVoltage*compensationVoltage + 857.39*compensationVoltage)*0.5;<\/code><\/pre>\n\n\n\n<p>Finally, it prints the TDS value in ppm:<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>Serial.print(\"TDS Value:\");\nSerial.print(tdsValue,0);\nSerial.println(\"ppm\");<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"demonstration\">Demonstration<\/h2>\n\n\n\n<p>After copying the code to the Arduino IDE, upload the code to your board. Don&#8217;t forget to select the right board in <strong>Tools <\/strong>&gt; <strong>Board <\/strong>and the right COM port in <strong>Tools <\/strong>&gt; <strong>Port<\/strong>.<\/p>\n\n\n\n<p>After uploading, open the Serial Monitor at a baud rate of 115200 and press the ESP32 RST button so that the code starts working.<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-full\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"750\" height=\"422\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2022\/02\/TDS-meter-ESP32-ESP8266-arduino-testing.jpg?resize=750%2C422&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"TDS meter testing ESP32 ESP8266 Arduino\" class=\"wp-image-109567\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2022\/02\/TDS-meter-ESP32-ESP8266-arduino-testing.jpg?w=750&amp;quality=100&amp;strip=all&amp;ssl=1 750w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2022\/02\/TDS-meter-ESP32-ESP8266-arduino-testing.jpg?resize=300%2C169&amp;quality=100&amp;strip=all&amp;ssl=1 300w\" sizes=\"(max-width: 750px) 100vw, 750px\" \/><\/figure><\/div>\n\n\n\n<p>It will show a value of 0 if the probe is not submerged. Put the probe on a solution to check its TDS. You can try with tap water and add some salt to see if the values increase.<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-full\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"601\" height=\"413\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2022\/02\/TDS-Sensor-Arduino-IDE-Serial-Monitor-Demonstration.png?resize=601%2C413&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"TDS Sensor Arduino IDE Serial Monitor\" class=\"wp-image-109564\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2022\/02\/TDS-Sensor-Arduino-IDE-Serial-Monitor-Demonstration.png?w=601&amp;quality=100&amp;strip=all&amp;ssl=1 601w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2022\/02\/TDS-Sensor-Arduino-IDE-Serial-Monitor-Demonstration.png?resize=300%2C206&amp;quality=100&amp;strip=all&amp;ssl=1 300w\" sizes=\"(max-width: 601px) 100vw, 601px\" \/><\/figure><\/div>\n\n\n\n<p>I measured the TDS value for tap water in my house, and I got a value of around 100ppm, which is a good value for drinking water. <\/p>\n\n\n\n<p>I also tested tea, and the TDS value increased to about 230ppm, which seems a reasonable value. <\/p>\n\n\n\n<p>Finally, I also measured the TDS value of bottled water and I got a value of 0ppm. I&#8217;m not sure if this value is correct because the water is advertised as mineral water, so the minerals dissolved in the water should account for a TDS value. I think this value can be explained due to the non-linearity of the ESP32 ADC pins for small voltage values. Do you have one of these sensors? What values did you get for bottled water?<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Wrapping Up<\/h2>\n\n\n\n<p>A TDS meter can measure the total dissolved solids in a solution. It can be used as an indicator of water quality and allows you to characterize the water. The meter returns the TDS value in ppm (parts per million\u2014mg\/L). The TDS value has many applications but it cannot be used by itself to determine if the water is drinkable or not.<\/p>\n\n\n\n<p>A great application of this type of sensor is an aquarium water quality monitor. You can use this sensor alongside a waterproof DS18B20 temperature sensor to monitor your fish tank, for example. <\/p>\n\n\n\n<p>Are you interested in an Aquarium Water Quality Monitor? I was thinking about creating a web app to monitor and control your aquarium temperature and water quality and additionally, also be able to control a pump via an output pin of the ESP32. What do you think?<\/p>\n\n\n\n<p>We hope you found this tutorial useful. We have tutorials for other popular sensors that you may like:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li><a href=\"https:\/\/randomnerdtutorials.com\/esp32-mqtt-publish-ds18b20-temperature-arduino\/\">ESP32 with DS18B20:\u00a0<strong>Temperature Sensor<\/strong><\/a><\/li><li><a href=\"https:\/\/randomnerdtutorials.com\/esp32-k-type-thermocouple-max6675\/\">ESP32: K-Type Thermocouple with MAX6675 Amplifier<\/a><\/li><li><a href=\"https:\/\/randomnerdtutorials.com\/esp32-mqtt-publish-bme680-arduino\/\">ESP32 with BME680:\u00a0<strong>Gas, Pressure, Humidity, and Temperature<\/strong>\u00a0<strong>Sensor<\/strong><\/a><\/li><li><a href=\"https:\/\/randomnerdtutorials.com\/esp32-mqtt-publish-bme280-arduino\/\">ESP32 with BME280:\u00a0<strong>Temperature, Humidity, and Pressure Sensor<\/strong><\/a><\/li><li><a href=\"https:\/\/randomnerdtutorials.com\/esp32-dht11-dht22-temperature-humidity-sensor-arduino-ide\/\">ESP32 DHT11\/DHT22:\u00a0<strong>Temperature, and Humidity Sensor<\/strong><\/a><\/li><li><a href=\"https:\/\/randomnerdtutorials.com\/esp32-bmp388-arduino\/\">ESP32 with BMP388:\u00a0<strong>Altimeter Sensor<\/strong><\/a><\/li><li><a href=\"https:\/\/randomnerdtutorials.com\/esp32-hc-sr04-ultrasonic-arduino\/\">ESP32 HC-SR04:\u00a0<strong>Ultrasonic Distance Sensor<\/strong><\/a><\/li><li><a href=\"https:\/\/randomnerdtutorials.com\/esp32-pir-motion-sensor-interrupts-timers\/\">ESP32 PIR:\u00a0<strong>Motion Sensor<\/strong><\/a><\/li><li><a href=\"https:\/\/randomnerdtutorials.com\/esp32-with-bmp180-barometric-sensor\/\">ESP32 BMP180:\u00a0<strong>Pressure Sensor<\/strong><\/a><\/li><li><a href=\"https:\/\/randomnerdtutorials.com\/esp32-bh1750-ambient-light-sensor\/\">ESP32 with BH1750\u00a0<strong>Ambient Light Sensor<\/strong><\/a><\/li><\/ul>\n\n\n\n<p>Learn more about the ESP32 with our resources:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li><a href=\"https:\/\/randomnerdtutorials.com\/learn-esp32-with-arduino-ide\/\">Learn ESP32 with Arduino IDE<\/a><\/li><li><a href=\"https:\/\/randomnerdtutorials.com\/build-web-servers-esp32-esp8266-ebook\/\">Build Web Servers with ESP32 and ESP8266<\/a><\/li><li><a href=\"https:\/\/randomnerdtutorials.com\/firebase-esp32-esp8266-ebook\/\">Firebase Web App with ESP32 and ESP8266<\/a><\/li><li><a href=\"https:\/\/randomnerdtutorials.com\/projects-esp32\/\">Free ESP32 Projects and Tutorials&#8230;<\/a><\/li><\/ul>\n\n\n\n<p>Thanks for reading.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In this guide, you&#8217;ll learn how to use a TDS meter (Total Dissolved Solids) with the ESP32. A TDS meter indicates the total dissolved solids like salts, minerals, and metals, &#8230; <\/p>\n<p class=\"read-more-container\"><a title=\"ESP32 with TDS Sensor (Water Quality Sensor)\" class=\"read-more button\" href=\"https:\/\/randomnerdtutorials.com\/esp32-tds-water-quality-sensor\/#more-109306\" aria-label=\"Read more about ESP32 with TDS Sensor (Water Quality Sensor)\">CONTINUE READING \u00bb<\/a><\/p>\n","protected":false},"author":5,"featured_media":109571,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[281,276,277,299,264],"tags":[],"class_list":["post-109306","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-esp32-project","category-esp32","category-esp32-arduino-ide","category-0-esp32","category-project"],"aioseo_notices":[],"jetpack_featured_media_url":"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2022\/02\/ESP32-TDS-Sensor-Water-Quality-Sensor.jpg?fit=1280%2C720&quality=100&strip=all&ssl=1","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/posts\/109306","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/users\/5"}],"replies":[{"embeddable":true,"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/comments?post=109306"}],"version-history":[{"count":23,"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/posts\/109306\/revisions"}],"predecessor-version":[{"id":110649,"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/posts\/109306\/revisions\/110649"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/media\/109571"}],"wp:attachment":[{"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/media?parent=109306"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/categories?post=109306"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/tags?post=109306"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}