Arduino ESP32 DIY Water Level Sensor and DIY Level Indicator

A self-made (cheap) water level sensor and water level indicator to measure 5 water levels in a reservoir tank.

Dec 1, 2018

59487 views

8 respects

Components and supplies

1

Arduino UNO

1

Capacitor 1 nF

1

Capacitor 220 nF

1

Water Level Sensor

6

Resistor 680 k Ohm

1

ESP 32

1

Water Level Indicator

Apps and platforms

1

Arduino IDE

Project description

Code

Waterlevel_measuring.ino

arduino

ARDUINO Sketch for DIY Water Level Sensor and DIY Water Level Indicator with 5 levels running on a ESP 32 or ARDUINO UNO or similar (with small modifications)

Downloadable files

Water Level Sensor and Level Indicator

This diagram shows the set up of a system for measuring waterlevels with a DIY sensor and a display for level indication in combination with an ARDUINO

Water Level Sensor and Level Indicator

Water Level Sensor and Level Indicator

This diagram shows the set up of a system for measuring waterlevels with a DIY sensor and a display for level indication in combination with an ARDUINO

Water Level Sensor and Level Indicator

Documentation

template for Water Level Indicator

template for drilling holes and printing text for the Water Level Indicator

template for Water Level Indicator

template for Water Level Indicator

template for drilling holes and printing text for the Water Level Indicator

template for Water Level Indicator

Comments

Only logged in users can leave comments

Pedro52

2 years ago

To Rolf Varga Dear Rolf, Please connect your questions with the project, so everyone who has similar questions can follow the conversation. I need to know more about how and what you have done. Can you post pictures of the sensor that you have constructed and how. To which input of the NANO are you connecting? The NANO has an 8 bits ADC, whereas the ESP32 uses 12 bits, although I don't believe this is the problem. How is your electronics circuit build up? Best Regards Pedro

Anonymous user

2 years ago

Hello Pedro, i have the issue that the Masseur values jump to much. As Example: for no Water between 342 and 261. i my case i have it also try it with 3x 220nf in hope to get a better value but that was not successful. I cant here send screenshots or videos.. to share it with you.

Anonymous user

2 years ago

Corrosion of the probes with a DC supply would be a problem. Commercial conductivity systems use alternating current to prevent corrosion. Better materials would be stainless steel or graphite, both used commercially. You could also look at periodic powering up rather than continuous, easy with an MCU

Anonymous user

2 years ago

I built this project, and when testing by shorting wires together with a jumper, I was able to get the expected voltage divider outputs. When I put in water, it acts like it is in air. That would indicate my water isn't acting as a conductor. Maybe there is too much water? I built it to monitor water level for my chickens. It is essentially 5 gallons of water. That didn't work, so now just testing in my sink it still doesn't work. Did you ever test in more water than a pint jar?

Anonymous user

2 years ago

Hey, thanks for your Projekt. I have try to reconstruct it but it was for me not possible. I have a arduino nano. I dont need the level meter i only need the messurance unit. So i have cut the code about it. But it get only worse numbers out. Have you a hint why ? thanks a lot!

Anonymous user

2 years ago

Hi, I am trying to modify your design to two copper wires and a relay that would operate my bilge pump in my boat. The idea is to start the pump when the level reaches the second wire, and stop the pump 10 sec after the water level is below the first wire. I'm testing with a Wemos d1 mini pro clone. What I can't get work is getting anything reasonable from the copper wires, and I suspect that i am connecting all wrong. Could you please open up a bit more in the Fritzing-image which pin is connected to which wire :-) BR René

Pedro52

2 years ago

Dear René, a 2 wire solution should very well be possible. For proper measurements you need to connect to the analog input of the Wemos and feed the circuit with a GPIO output (with 3,3 v high level). The circuit can be modified as follows: https://1drv.ms/w/s!AmbHsqsYUWDxqD-8d5XcgWPuu4tq?e=Cj9Bk5 you could even leave out the capacitors if not available. use line 104 : Serial.print(" LEVELarray: "); Serial.print(level); etc in the code to determine the right values for the level array. Let me know once you have solved the problem

Anonymous user

2 years ago

Just had a second look at this. One thing that caught my eye was the figure for your tap water conductivity of 35-mS/cm. That would worry me, it's too high. The UK maximum for tap water conductivity is 2.5-mS/cm at 20 degrees Celsius and my own tap water, considered to be hard water with a lot of dissolved calcium, is only 250-uS/cm. I don't know where you are or where you get your drinking water from, but I would make some enquiries. Your figure suggests contamination from say seawater or pipework breaking down. Rainwater is typically 150-uS/cm. I'm surprised it doesn't taste differently to say, bottled water

Pedro52

2 years ago

Dear Phil No worries, the average conductivity value of the tap water supplied in my area is approx. 35 mS/m not per cm!, (see description under Step 1), so actually quite good. The hardness is specified as 7,6 ºdH i.e. approx. 135 gr of calcium per m3. So pretty good drinking water :)

Anonymous user

2 years ago

Hi Pedro ! Great design, i will experiment that asap. Do you have a feedback on evolution of imerged copper wires after a long duration with exposition to water or air or both ? I have a suggestion : i would slightly modify the design in order to alternate the voltage seen by electrodes : use another GPIO instead of GND to connect to the (-) pole of the 2x1 MEG after a 200 ms supply + voltage reading with 2 GPIOs like (+VDD,GND) , i would swap the 2 GPIOs (ie GND,+VDD) This is the recommendation to avoid electrolytic issues (ions are moving back and forth between electrodes) Best regards JB

Pedro52

2 years ago

Dear JB, thank you so much for your comment! To be honest I have no experience yet with the copper wires for a long period of time; the electrodes are exposed to a voltage only for a short period of time per day. Hower there could be a certain corrosion after some time due to oxigen and other elements in the water. You recommendation to alternate the voltage looks like a good idea though, but will require a change of the sketch of course, but that should be easy. Another possibility would be to use stainless steel electrodes instead of copper for instance using stainless steel welding electrodes. I have also considered to build in a calibration function that enables to compute the lower and upper limits and thus compensate for any deterioration of the copper sensor. Pleas let me know your findings after your experiments. This low cost sensor is anyway worth it to be further developed. Best Regards Pedro

Anonymous user

2 years ago

Hi Pedro Nice project. I was thinking on use the capacitive sensors of the ESP32 (a pin each level) for the task, then your setup appeared on the search. Very interesting! I was thinking maybe it would be feasible for this project, to add one more (pair) sensor that would be set to the very bottom (always wet), and then by sampling this, obtain an auto regulation correlation formula that could be used to auto calibrate the readings? So at setup (and/or every now and then) the uC would read this "standard" reading and then have a prediction value for the other levels automatically. What do you think?

Pedro52

2 years ago

Dear mad_b Your idea looks feasible, it might help to eliminate measurement inaccuracies with respect to the reference values as a result of voltage changes of the power supply. The solution requires a second measurement channel with an identical resistor network as the first sensor. Also some mathematics will be needed to calculate the new reference values (once in a while) using the formula as given in figure WaterLevelValues vs Level. In addition you could consider to also sample the "dry" value for better results and put that into the equation. All this will contribute to more consistent level indications over time. Thank you for bringing this idea on the table. Best Regards Pedro

Anonymous user

2 years ago

I'm trying to build this with a ESP-01 and relay module. Obviously I don't have pin 27 to provide the +3.3. I'm wondering if I could put a pullup resistor between 3.3V and the output of the resistor ladder. Something like this example: http://electronic-projects.50webs.com/water-level-sensor-circuit.htm. Otherwise, great project! I have Blynk and Node-Red integrated into the sketch with just a few hours of work. Please let me know if you can help calculate the pullup resistor.

Pedro52

2 years ago

Yes of course the LevelSensorPin needs to be connected to an analog pin of the ESP in order to measure the WaterLevelValue = analogRead(LevelSensorPin); I just checked the ESP-01 pinout and found that it does not have an ADC input. Perhaps the following can help you. Otherwise I would suggest to consider another board. Depending on the resolution of the ADC input also the values in the LEVELarray may need to adjusted in case it is not a 12 bits ADC. I was interested in how you have implemented Blynk in the project code Best Regards Pedro

Pedro52

2 years ago

Dear mrkoch Any digital output pin should serve the purpose, even if it provides 5V levels. You will probably have to adjust the values in the LEVELarray. I am interested in your Blynk solution, please let me know. Best Regards Pedro

Anonymous user

2 years ago

Currently I am reporting water level and relay position to the app. With the bridge feature, Node Red sends a heartbeat every minute (Blynk does not have the last will feature that MQTT supports). If the heartbeat timeouts, the relay is controlled locally based on minimum water levels. Otherwise, Node Red assumes full control which provides a higher tolerance for water levels. With the bridge, the board also reports to Node Red the level and relay state, as well as uptime and heartbeat timeout status.

Anonymous user

2 years ago

Couple ideas. 1. A voltage to frequency converter could make it work. https://www.analog.com/en/analog-dialogue/raqs/raq-issue-169.html# 2. A few more components could hold the water sensor open til the chip boots. https://www.webx.dk/oz2cpu/esp8266/esp8266-wifi-mailbox-email.htm Of course just changing for an Wemos D1 Mini Pro might be the fastest and simplest for me.

Anonymous user

2 years ago

Turns out that when the water level holds GPIO2 or TX low, then the board won't boot. So I have to use a board with more inputs or add an ADC. What would you like to know about the Blynk setup?

Anonymous user

2 years ago

I can’t get any value from the pin with AnalogRead. Google indicates that it has to be an analog pin, which is not exposed on the esp-01 development board. I see several options on the Internet for one-wire water level sensors but they’re beyond my capabilities. I think I’m going to try converting the TX and RX to GPIOs. That leaves me with three pins which will be enough.

Anonymous user

2 years ago

Hi Pedro. Great project. Congratulations. One question: would it work if you used one wire per level (5 in total) connected each to one GPIO configured as inputs and one additional wire at the bottom of the tank connected to a GPIO configured as output. Then you write HIGH the bottom wire and read the 5 input GPIOs. The number of input GPIOs with voltage means the water is at that level. What do you think?

Anonymous user

2 years ago

This is how I tested it today with only 3 levels (for now): 1. The Output (digital) pin goes directly into the water at the bottom of the bucket 2. The 3 input pins (analog) have a wire that goes into the water (at 3 different levels) and one wire to a 1M ohm resistor which in turn goes to GND of the ESP32 This works as a voltage divider, with the water as R1 and the 1M ohm resistor as R2. I then digitalWrite HIGH the output pin for 200 ms and analogRead the 3 input pins. Any pin with a value is considered under the water. The 1M Ohm resistor is large enough to provide "elbow" room for any salinity level or water volume or temperature. It does create a little sporadic noise on "dry" input pins but in the order of 0.2v (the ADC is 12 bits so the max value is 4096. The noise never goes above 300). Any reading above, say, 2000 (1.6v) can be considered as "wet". I'll build a 6 level testbed an run it for a few days and see how it goes. The downside, as you correctly mentioned, is that 5 or 6 or 7 (depending on how many levels) pins are necessary, and care must be taken of ADC1 & ADC2 because some implementations on the ESP32 turn one of the ADCs off when using WiFi. The upside is that water conditions become immaterial (I think....). I tested several scenarios with a capacitor to try to eliminate the sporadic noise to no avail. What are your thoughts?

Pedro52

2 years ago

Good thinking, that could also work, however that way you will be using 6 GPIO's , instead of just 2. In your approach I would connect the ground pin to GND of the circuit and give each wire a resistor, while connecting all resistors to 1 GPIO output pin and the "sensing" pins to the GPIO input pins and the others side of each resistor.

Pedro52

2 years ago

I believe that your solution will work and that it eliminates the influence of conductivity variations of the water, but at the cost of a number of ADC input pins (one for each level). Perhaps putting a small capacitor (100 nF) across the 1 M resistor can reduce the noise.

Anonymous user

2 years ago

Hi pedro..great project. I was looking to build a similar project like this and i think i will replicate yours. A few questions here: Since practically the wire going from Arduino to the sensor will be much longer. I connected a wire coil of 90 metres and jitter existing on sensor values is much above the margin of 4%, thus a lot of varying values( whereas with a short jumper wire, is no problem). How do you solve this ? Also, can you explain how the virtual Wheatstone bridge is formed here. a little trouble in recognizing it.

gadlol06

2 years ago

Hi pedro Can you explain to me why is there 220fn capacitor parallel to two 1M ohm resistors because i can't understand this part... because it would make sense to me if it would be in series. Then it would protect the board anyway if you coud link my some pages where i could understand this it would be cool.

Anonymous user

2 years ago

Tank gauges often drill into a non-metallic tank and insert probes made from a rubber rawl nut with a stainless steel bolt. Put the bolt on the inside with sealant and attach wires to the outside with a washer and nut.

Anonymous user

3 years ago

Tank gauges often drill into a non-metallic tank and insert probes made from a rubber rawl nut with a stainless steel bolt. Put the bolt on the inside with sealant and attach wires to the outside with a washer and nut.

Anonymous user

3 years ago

Hi Pedro. Great project. Congratulations. One question: would it work if you used one wire per level (5 in total) connected each to one GPIO configured as inputs and one additional wire at the bottom of the tank connected to a GPIO configured as output. Then you write HIGH the bottom wire and read the 5 input GPIOs. The number of input GPIOs with voltage means the water is at that level. What do you think?

Anonymous user

2 years ago

This is how I tested it today with only 3 levels (for now): 1. The Output (digital) pin goes directly into the water at the bottom of the bucket 2. The 3 input pins (analog) have a wire that goes into the water (at 3 different levels) and one wire to a 1M ohm resistor which in turn goes to GND of the ESP32 This works as a voltage divider, with the water as R1 and the 1M ohm resistor as R2. I then digitalWrite HIGH the output pin for 200 ms and analogRead the 3 input pins. Any pin with a value is considered under the water. The 1M Ohm resistor is large enough to provide "elbow" room for any salinity level or water volume or temperature. It does create a little sporadic noise on "dry" input pins but in the order of 0.2v (the ADC is 12 bits so the max value is 4096. The noise never goes above 300). Any reading above, say, 2000 (1.6v) can be considered as "wet". I'll build a 6 level testbed an run it for a few days and see how it goes. The downside, as you correctly mentioned, is that 5 or 6 or 7 (depending on how many levels) pins are necessary, and care must be taken of ADC1 & ADC2 because some implementations on the ESP32 turn one of the ADCs off when using WiFi. The upside is that water conditions become immaterial (I think....). I tested several scenarios with a capacitor to try to eliminate the sporadic noise to no avail. What are your thoughts?

Pedro52

2 years ago

Good thinking, that could also work, however that way you will be using 6 GPIO's , instead of just 2. In your approach I would connect the ground pin to GND of the circuit and give each wire a resistor, while connecting all resistors to 1 GPIO output pin and the "sensing" pins to the GPIO input pins and the others side of each resistor.

Pedro52

2 years ago

I believe that your solution will work and that it eliminates the influence of conductivity variations of the water, but at the cost of a number of ADC input pins (one for each level). Perhaps putting a small capacitor (100 nF) across the 1 M resistor can reduce the noise.

gadlol06

4 years ago

Hi pedro Can you explain to me why is there 220fn capacitor parallel to two 1M ohm resistors because i can't understand this part... because it would make sense to me if it would be in series. Then it would protect the board anyway if you coud link my some pages where i could understand this it would be cool.

mad_b

4 years ago

Hi Pedro Nice project. I was thinking on use the capacitive sensors of the ESP32 (a pin each level) for the task, then your setup appeared on the search. Very interesting! I was thinking maybe it would be feasible for this project, to add one more (pair) sensor that would be set to the very bottom (always wet), and then by sampling this, obtain an auto regulation correlation formula that could be used to auto calibrate the readings? So at setup (and/or every now and then) the uC would read this "standard" reading and then have a prediction value for the other levels automatically. What do you think?

Pedro52

2 years ago

Dear mad_b Your idea looks feasible, it might help to eliminate measurement inaccuracies with respect to the reference values as a result of voltage changes of the power supply. The solution requires a second measurement channel with an identical resistor network as the first sensor. Also some mathematics will be needed to calculate the new reference values (once in a while) using the formula as given in figure WaterLevelValues vs Level. In addition you could consider to also sample the "dry" value for better results and put that into the equation. All this will contribute to more consistent level indications over time. Thank you for bringing this idea on the table. Best Regards Pedro

Anonymous user

4 years ago

Hi Pedro - First, great simple design! Now, would you see any issue with long term powering this solution using a mobile USB charger connected to the 127/220v power line? Any electrical risk if I use this solution on my water tank that feeds the shower head?

Anonymous user

4 years ago

Hi, I am trying to modify your design to two copper wires and a relay that would operate my bilge pump in my boat. The idea is to start the pump when the level reaches the second wire, and stop the pump 10 sec after the water level is below the first wire. I'm testing with a Wemos d1 mini pro clone. What I can't get work is getting anything reasonable from the copper wires, and I suspect that i am connecting all wrong. Could you please open up a bit more in the Fritzing-image which pin is connected to which wire :-) BR René

Pedro52

2 years ago

Dear René, a 2 wire solution should very well be possible. For proper measurements you need to connect to the analog input of the Wemos and feed the circuit with a GPIO output (with 3,3 v high level). The circuit can be modified as follows: https://1drv.ms/w/s!AmbHsqsYUWDxqD-8d5XcgWPuu4tq?e=Cj9Bk5 you could even leave out the capacitors if not available. use line 104 : Serial.print(" LEVELarray: "); Serial.print(level); etc in the code to determine the right values for the level array. Let me know once you have solved the problem

Anonymous user

4 years ago

I built this project, and when testing by shorting wires together with a jumper, I was able to get the expected voltage divider outputs. When I put in water, it acts like it is in air. That would indicate my water isn't acting as a conductor. Maybe there is too much water? I built it to monitor water level for my chickens. It is essentially 5 gallons of water. That didn't work, so now just testing in my sink it still doesn't work. Did you ever test in more water than a pint jar?

Anonymous user

4 years ago

Hi pedro..great project. I was looking to build a similar project like this and i think i will replicate yours. A few questions here: Since practically the wire going from Arduino to the sensor will be much longer. I connected a wire coil of 90 metres and jitter existing on sensor values is much above the margin of 4%, thus a lot of varying values( whereas with a short jumper wire, is no problem). How do you solve this ? Also, can you explain how the virtual Wheatstone bridge is formed here. a little trouble in recognizing it.

Anonymous user

5 years ago

Just had a second look at this. One thing that caught my eye was the figure for your tap water conductivity of 35-mS/cm. That would worry me, it's too high. The UK maximum for tap water conductivity is 2.5-mS/cm at 20 degrees Celsius and my own tap water, considered to be hard water with a lot of dissolved calcium, is only 250-uS/cm. I don't know where you are or where you get your drinking water from, but I would make some enquiries. Your figure suggests contamination from say seawater or pipework breaking down. Rainwater is typically 150-uS/cm. I'm surprised it doesn't taste differently to say, bottled water

Pedro52

2 years ago

Dear Phil No worries, the average conductivity value of the tap water supplied in my area is approx. 35 mS/m not per cm!, (see description under Step 1), so actually quite good. The hardness is specified as 7,6 ºdH i.e. approx. 135 gr of calcium per m3. So pretty good drinking water :)

Anonymous user

5 years ago

I'm trying to build this with a ESP-01 and relay module. Obviously I don't have pin 27 to provide the +3.3. I'm wondering if I could put a pullup resistor between 3.3V and the output of the resistor ladder. Something like this example: http://electronic-projects.50webs.com/water-level-sensor-circuit.htm. Otherwise, great project! I have Blynk and Node-Red integrated into the sketch with just a few hours of work. Please let me know if you can help calculate the pullup resistor.

Anonymous user

2 years ago

I can’t get any value from the pin with AnalogRead. Google indicates that it has to be an analog pin, which is not exposed on the esp-01 development board. I see several options on the Internet for one-wire water level sensors but they’re beyond my capabilities. I think I’m going to try converting the TX and RX to GPIOs. That leaves me with three pins which will be enough.

Anonymous user

2 years ago

Couple ideas. 1. A voltage to frequency converter could make it work. https://www.analog.com/en/analog-dialogue/raqs/raq-issue-169.html# 2. A few more components could hold the water sensor open til the chip boots. https://www.webx.dk/oz2cpu/esp8266/esp8266-wifi-mailbox-email.htm Of course just changing for an Wemos D1 Mini Pro might be the fastest and simplest for me.

Anonymous user

2 years ago

Currently I am reporting water level and relay position to the app. With the bridge feature, Node Red sends a heartbeat every minute (Blynk does not have the last will feature that MQTT supports). If the heartbeat timeouts, the relay is controlled locally based on minimum water levels. Otherwise, Node Red assumes full control which provides a higher tolerance for water levels. With the bridge, the board also reports to Node Red the level and relay state, as well as uptime and heartbeat timeout status.

Anonymous user

2 years ago

Turns out that when the water level holds GPIO2 or TX low, then the board won't boot. So I have to use a board with more inputs or add an ADC. What would you like to know about the Blynk setup?

Pedro52

2 years ago

Yes of course the LevelSensorPin needs to be connected to an analog pin of the ESP in order to measure the WaterLevelValue = analogRead(LevelSensorPin); I just checked the ESP-01 pinout and found that it does not have an ADC input. Perhaps the following can help you. Otherwise I would suggest to consider another board. Depending on the resolution of the ADC input also the values in the LEVELarray may need to adjusted in case it is not a 12 bits ADC. I was interested in how you have implemented Blynk in the project code Best Regards Pedro

Pedro52

2 years ago

Dear mrkoch Any digital output pin should serve the purpose, even if it provides 5V levels. You will probably have to adjust the values in the LEVELarray. I am interested in your Blynk solution, please let me know. Best Regards Pedro

Anonymous user

5 years ago

Corrosion of the probes with a DC supply would be a problem. Commercial conductivity systems use alternating current to prevent corrosion. Better materials would be stainless steel or graphite, both used commercially. You could also look at periodic powering up rather than continuous, easy with an MCU

Pedro52

6 years ago

To Rolf Varga Dear Rolf, Please connect your questions with the project, so everyone who has similar questions can follow the conversation. I need to know more about how and what you have done. Can you post pictures of the sensor that you have constructed and how. To which input of the NANO are you connecting? The NANO has an 8 bits ADC, whereas the ESP32 uses 12 bits, although I don't believe this is the problem. How is your electronics circuit build up? Best Regards Pedro

Anonymous user

2 years ago

Hello Pedro, i have the issue that the Masseur values jump to much. As Example: for no Water between 342 and 261. i my case i have it also try it with 3x 220nf in hope to get a better value but that was not successful. I cant here send screenshots or videos.. to share it with you.

Anonymous user

6 years ago

Hey, thanks for your Projekt. I have try to reconstruct it but it was for me not possible. I have a arduino nano. I dont need the level meter i only need the messurance unit. So i have cut the code about it. But it get only worse numbers out. Have you a hint why ? thanks a lot!

Anonymous user

6 years ago

Hi Pedro ! Great design, i will experiment that asap. Do you have a feedback on evolution of imerged copper wires after a long duration with exposition to water or air or both ? I have a suggestion : i would slightly modify the design in order to alternate the voltage seen by electrodes : use another GPIO instead of GND to connect to the (-) pole of the 2x1 MEG after a 200 ms supply + voltage reading with 2 GPIOs like (+VDD,GND) , i would swap the 2 GPIOs (ie GND,+VDD) This is the recommendation to avoid electrolytic issues (ions are moving back and forth between electrodes) Best regards JB

Pedro52

2 years ago

Dear JB, thank you so much for your comment! To be honest I have no experience yet with the copper wires for a long period of time; the electrodes are exposed to a voltage only for a short period of time per day. Hower there could be a certain corrosion after some time due to oxigen and other elements in the water. You recommendation to alternate the voltage looks like a good idea though, but will require a change of the sketch of course, but that should be easy. Another possibility would be to use stainless steel electrodes instead of copper for instance using stainless steel welding electrodes. I have also considered to build in a calibration function that enables to compute the lower and upper limits and thus compensate for any deterioration of the copper sensor. Pleas let me know your findings after your experiments. This low cost sensor is anyway worth it to be further developed. Best Regards Pedro