Core Electronics Forum

Water tank level monitoring + Node Red

This might be in the wrong place, if so apologies… I put it here because its not a project just yet.

My problem… Our new farm is on tank water and I want to keep a close eye on water levels.

I had been thinking about either using an ultrasonic sensor or one of these:

Neither really float my boat - Ive not had a lot of success with the ultrasonic sensors and the AquaPlumb seems expensive and needs the ‘box of tricks’ to make it work before it even gets to something to upload to TTN.

Randomly, I stumbled across these videos last night and it got me thinking.

Could I use this basic concept (& should I use the BC547’s or could I get away without them)?

Im thinking something like having 6 or so wires of different lengths suspended in a plastic tube in the water tank, each connected to a different GPIO on a Raspberry Pi with the Pullup resistors enabled. Supply 5V (or GND??) into the water from the Pi.

In Node Red I think I could detect the change from high to low (or low to high) on each GPIO. Perhaps either through code in a function node or a collection of nodes I could output to a chart that shows tank x% full.

My biggest area of concern / unknown is feeding 5V into the water and if the GPIOs would be driven high/low through conductivity in the water and if the pull-up resistors would be sufficient, of if I would need the additional 100ohm resistors.

What do you think guys? Is it a go, or fundamentally flawed??

Thoughts please.


Well after a bit of thinking I have the node-red side more-or-less sorted, at least as a proof of concept anyway. I have used sliders to represent my GPIO’s being Hi or LOW and had to use a JOIN node to pull my 5 GPIOs together such that I could manipulate the data in a function node. A few ‘if’ statements later and I have chart representation of my theoretical water tank.

Could this be more efficient, or is there a better way?

[{"id":"762b3609.fe53a8","type":"join","z":"6d91a674.1b8e38","name":"","mode":"custom","build":"object","property":"payload","propertyType":"msg","key":"topic","joiner":"\\n","joinerType":"str","accumulate":true,"timeout":"","count":"5","reduceRight":false,"reduceExp":"","reduceInit":"","reduceInitType":"","reduceFixup":"","x":330,"y":480,"wires":[["20cca6c7.1be3ca"]]},{"id":"20cca6c7.1be3ca","type":"function","z":"6d91a674.1b8e38","name":"Determine % Full","func":"if (msg.payload.pin37 === false && msg.payload.pin35 === false && msg.payload.pin33 === false && msg.payload.pin31 === false && msg.payload.pin29 === false) {\n msg.payload = \"EMPTY\";\n}\nelse if (msg.payload.pin37 === true && msg.payload.pin35 === false && msg.payload.pin33 === false && msg.payload.pin31 === false && msg.payload.pin29 === false) {\n msg.payload = 20;\n}\nelse if (msg.payload.pin37 === true && msg.payload.pin35 === true && msg.payload.pin33 === false && msg.payload.pin31 === false && msg.payload.pin29 === false) {\n msg.payload = 40;\n}\nelse if (msg.payload.pin37 === true && msg.payload.pin35 === true && msg.payload.pin33 === true && msg.payload.pin31 === false && msg.payload.pin29 === false) {\n msg.payload = 60;\n}\nelse if (msg.payload.pin37 === true && msg.payload.pin35 === true && msg.payload.pin33 === true && msg.payload.pin31 === true && msg.payload.pin29 === false) {\n msg.payload = 80;\n}\nelse if (msg.payload.pin37 === true && msg.payload.pin35 === true && msg.payload.pin33 === true && msg.payload.pin31 === true && msg.payload.pin29 === true) {\n msg.payload = 100;\n}\n\nelse\n msg.payload = \"ERROR\";\n\nreturn msg;\n","outputs":1,"noerr":0,"x":520,"y":480,"wires":[["403ec636.f266b8","c5192ed5.9e6cc","b1d12b19.03dcc8"]]},{"id":"403ec636.f266b8","type":"debug","z":"6d91a674.1b8e38","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","x":750,"y":500,"wires":[]},{"id":"bb1480fc.2bb53","type":"ui_switch","z":"6d91a674.1b8e38","name":"","label":"pin29","tooltip":"","group":"c1ab5a5a.c7aec8","order":1,"width":0,"height":0,"passthru":true,"decouple":"false","topic":"pin29","style":"","onvalue":"true","onvalueType":"bool","onicon":"","oncolor":"","offvalue":"false","offvalueType":"bool","officon":"","offcolor":"","x":140,"y":360,"wires":[["762b3609.fe53a8"]]},{"id":"55a8477e.60e8d8","type":"ui_switch","z":"6d91a674.1b8e38","name":"","label":"pin31","tooltip":"","group":"c1ab5a5a.c7aec8","order":1,"width":0,"height":0,"passthru":true,"decouple":"false","topic":"pin31","style":"","onvalue":"true","onvalueType":"bool","onicon":"","oncolor":"","offvalue":"false","offvalueType":"bool","officon":"","offcolor":"","x":140,"y":400,"wires":[["762b3609.fe53a8"]]},{"id":"96d53533.55b908","type":"ui_switch","z":"6d91a674.1b8e38","name":"","label":"pin33","tooltip":"","group":"c1ab5a5a.c7aec8","order":1,"width":0,"height":0,"passthru":true,"decouple":"false","topic":"pin33","style":"","onvalue":"true","onvalueType":"bool","onicon":"","oncolor":"","offvalue":"false","offvalueType":"bool","officon":"","offcolor":"","x":140,"y":440,"wires":[["762b3609.fe53a8"]]},{"id":"bea66753.7ba388","type":"ui_switch","z":"6d91a674.1b8e38","name":"","label":"pin35","tooltip":"","group":"c1ab5a5a.c7aec8","order":1,"width":0,"height":0,"passthru":true,"decouple":"false","topic":"pin35","style":"","onvalue":"true","onvalueType":"bool","onicon":"","oncolor":"","offvalue":"false","offvalueType":"bool","officon":"","offcolor":"","x":140,"y":480,"wires":[["762b3609.fe53a8"]]},{"id":"29529c04.b72e64","type":"ui_switch","z":"6d91a674.1b8e38","name":"","label":"pin37","tooltip":"","group":"c1ab5a5a.c7aec8","order":1,"width":0,"height":0,"passthru":true,"decouple":"false","topic":"pin37","style":"","onvalue":"true","onvalueType":"bool","onicon":"","oncolor":"","offvalue":"false","offvalueType":"bool","officon":"","offcolor":"","x":140,"y":520,"wires":[["762b3609.fe53a8"]]},{"id":"c5192ed5.9e6cc","type":"ui_text","z":"6d91a674.1b8e38","group":"c1ab5a5a.c7aec8","order":6,"width":0,"height":0,"name":"","label":"text","format":"{{msg.payload}}","layout":"row-spread","x":730,"y":380,"wires":[]},{"id":"b1d12b19.03dcc8","type":"ui_gauge","z":"6d91a674.1b8e38","name":"","group":"c1ab5a5a.c7aec8","order":7,"width":0,"height":0,"gtype":"wave","title":"Water Tank Level","label":"% Full","format":"{{value}}%","min":0,"max":"100","colors":["#b50000","#e6e600","#38ca3b"],"seg1":"25","seg2":"75","x":770,"y":440,"wires":[]},{"id":"c1ab5a5a.c7aec8","type":"ui_group","name":"Group 1","tab":"6bf393ab.448f0c","order":1,"disp":true,"width":6},{"id":"6bf393ab.448f0c","type":"ui_tab","name":"Tab 3","icon":"dashboard","order":3}]



Just seeking some thoughts please…

As a side thought, I was thinking about using P8, P10, P19 through P23 for my LEDs as I think these have built in resistors.

Also, would anyone like to comment / advise if the ADC on the LoPy4 is sufficiently good enough to use for reliable & accurate data collection from an ultrasonic sensor? (I recall reading that the ADC on these boards is not very good) - This would then allow me to map the 0 - 1023 range from the ultrasonic to the “% full” representation of the LEDs, or a simple NodeRed chart, whilst only using 1 data pin.


Here’s a link to the pin configuration for the LoPy4

Here you can clearly see what pins are in use by default, and the 6 pins that are input only (no internal pullup resistors). Add to that pins in use by any any connected expansion boards to find out what pins are still available for connecting other devices.

The ADC on the board coupled to a HC-SR04, should be more than accurate enough for measuring the depth of water in a tank. The water surface will probably have periods where the surface has ripples, such as when filling the tank, so as long as the readings are consistent, should not pose a problem.

1 Like

Jon, is designed in South Australia, but may be expensive, too.

A HC-SR04 doesn’t require analog inputs; it uses 2 digital IO and measures pulse lengths, but if you Google, you will find it can be done with 1 GPIO!

I have read that US transducers don’t work great with water, but if you had a flat target that could slide up/down in the tank, it should work well.

Im thinking something like having 6 or so wires of different lengths suspended in a plastic tube in the water tank, each connected to a different GPIO on a Raspberry Pi with the Pullup resistors enabled. Supply 5V (or GND??) into the water from the Pi.
My biggest area of concern / unknown is feeding 5V into the water and if the GPIOs would be driven high/low through conductivity in the water and if the pull-up resistors would be sufficient, of if I would need the additional 100ohm resistors.

Although this may work OK, I don’t think it will work for long due to corrosion (maybe electrolysis?)

You could drive LEDs without transistors (FETs are easier than BJTs for this application. I use ubiquitous 2N7000) as long as they don’t draw more current than the SBC/microcontroller can source/sink. IMO, a Pi is rated at 16mA per pin, with some saying 51mA TOTAL and other say 100mA TOTAL for 40pin RPis. 10mA should be bright with a high brightness/efficiency LEDs. In line/series resistors will likely be required. At 3V3 (3.3V) the R would be (3.3-V_LED)/0.01, so an LED of 2V at 10mA would be (3.3-2)/0.01=130Ohms, so I would use 150Ohm resistors.

1 Like

Thanks guys,
Noting the possible electrolysis issues, Im thinking of reverting back to measuring the depth of my water tank(s) with an ultrasonic sensor (with LoPy4 via TTN & NodeRed).

I would want the LoPy4 to wake once from Deepsleep every 24hrs and the battery to last for a couple of months (or more).

A few questions please:

  1. What regulator would you suggest to power the sensor (SEN0208)?
  2. Which battery would you suggest to achieve my goal of a couple of months?

If the 5V power drain would be too large for a sensible battery size, what size solar panel and which solar charger? I wondered if this (PRT-13781) panel would be OK, coupled with this (PRT-12885) charger, but confess I dont have much of an idea in this space.


Hi John,
Have a look at measuring your tank level using hydrostatic pressure measurement, will give you a far better result than ultrasonics with less angst. A 0-1 bar pressure sensor will provide range 0-10.197m of water level. You can get the sensors fairly cheaply and also one that you can just submerse at the bottom of the tank (there is some error due to changing atm pressure but this is negligible in your application). The sensor can produce 4-20mA that you can then read with the LoPy or 0-10V (you will need some interfaces for either, no big deal there.). BTW the ADC on the LoPY (EPS32) is lousy, far better to grab a ADS1115 I2C unit and interface via that.
We have just completed an industrial project doing exactly this for 15+ tanks and it is a great solution, we instrument engineers have been measuring level via hydrostatic pressure for decades. Proven and works. Once your data is in the LoPy then the options for powering, network, Lora, Sigfox are considerable. Same for building your front end, node-red, IoT platform, Grafana, you name it.
Let me know if you need any further pointers, happy to help. Cheers, Steve B.


Hi @Steve47703,
Thanks for the great response. Could you provide a link to a sensor that you are using / would recommend?

Im happy with the notion of the ADS1115 and beyond to NodeRed, but having Googled for a sensor I am staggered by the number of options available and didn’t find anything like what I thought I was looking for!

Thanks again,

Hi Jon,

Something like this will give you 4-20mA for 0-5m depth,

You will need an interface for the 4-20mA, see below from Core and I would interface this to an ADC (ADS1115) via I2C to get a decent accuracy, the onboard ADC is lousy as I said. Both available from Core Electronics. Once you have the input data, you can use Lora, Sigfox, WiFi to pick it up the choice is yours.

Cheers. Steve B.


Fantastic @Steve47703, thanks very much.

From the information you provided (Id missed needing the current to voltage converter), I think this is how it would all get connected:

Does that look about right?

Also, in your experience would the pressure sensor need a 24VDC supply or could it be, say 5V? Providing power to my tanks will be my biggest issue. If I can get 240VAC to the tanks, I assume a 24VDC, 1A supply like this would be more than enough, perhaps:

As a better alternative though, Im thinking I could utilise one of these to provide power to the sensor from the LoPy4 battery:

With this option Im thinking that my 2400mAh LiPO that will power the other bits could also power the voltage regulator. To preserve power consumption I could connect a LoPy4 GPIO pin to the ENABLE pin on the regulator and set it HIGH / LOW as we enter from / goto DEEPSLEEP. That way, the voltage regulator would only be ON for a few seconds per day (ie when the LoPy is awake to read the sensor), the rest of the time the ENABLE pin would also more or less turn off the regulator.

The one bit I am unclear on is the pressure sensor wiring. I assume will have 4 wires (2 for the 24VDC supply) and two for the output signal - any thoughts?


Hi Jon, sketch is pretty right. The only thing is the ADS1115 works full range on 5V Vcc so maybe better to power it from 5V but you will then need to add a level shifter between the ADS and the LoPy so the SDA/SCL lines to the LoPy are at the correct level for the device (3.3V). Core has these, only a minor addition. The pressure sensor will need to be 24VC and they are ‘loop powered’ which means they are a 2 wire device - 24VDC to the +ve connection, the -ve (signal connection) then connects to the current-voltage converter and on to ground via the second connection at that device. Yep use a boost converter to generate your 24VDC and turn it on and off to conserve power. You could easily go solar with this applicaiton too, check out the DFRobot sunflower charge controllers for the LiPo batteries, they also have some with an onboard boost reg to power the sensor. I think you are pretty much there, get some gear and go and build it ! You’ll enjoy the outcome and seeing it come to life.

Thanks @Steve47703,
I read on the Adafruit ADS1115 site that it would work between 2V - 5V but didnt appreciate it needed the full 5V to work full range. Fortunately I already have a level shifter in my box of tricks thats left over from a previous project.

If I use the Pycom Expansion board and the LoPy4 I could use the 3V3 on the board to power the level shifter, the current/voltage converter and also the 24VDC. I’ll try without solar to start with and see how the battery lasts, in the knowledge that I could remove the Pycom Expansion board and replace with a solar regulator down the line if required - That will keep the immediate cost down if nothing else (I already have the Pycom stuff).

This is how I see the circuit…

Final question (for now)… Does the Hydrostatic sensor simply sink to the bottom of the tank and record the pressure thats impose by the head of water above?


Hi Jon, Re. your circuit you will need to source the 5V supply from somewhere, the current to voltage converter requires a source supply to power up the module and then it provides a 0-3V signal proportional to the measured current. I had a look though and it will also work on 3.3V as will the ADS so you could power the entire system at that level, note the ADS1115 will scale differently but you can work that out via test and it has the internal PGA gain settings to play with (check its data sheet) so that also does away with the level shifter. It would make it simpler, just a matter of working out the scale of the signal for the ADS, ps. the ADS also has a library available on Github by robert-hh (I think) which works (I am using it). Just be sure you limit the sensor input voltage to the ADS below the Vcc+threshold otherwise you will hurt it, the DF robot unit states max output at 3V so that is fine. But otherwise your circuit is getting there. And yep, you just throw the sensor in to the tank and let it sink to the bottom. Simple as that. Cheers, Steve B.

1 Like

Thanks @Steve47703, Parts ordered - Just need to get stuck into it now!

Quick question about gain when using the hydrostatic pressure sensor with the ADS1115.

After reading the Adafruit manual for the ADS1115 and watching a few Youtube videos on the board Im not 100% sure about how to set the gain. My understanding is that the supply voltage to the analog inputs can’t be greater than the supply voltage to the ADS1115.

I will feed the ADS1115 5V via the level shifter from the 3.3V feed on the LoPy4 - so my max voltage on A0 is 5V. The max output voltage on the Analog Current to Voltage Converter is 3V so I think the GAIN for the ADS1115 should be ONE (assuming the sensor is working in a 5m tank).

Does this sound correct or is my understanding / logic wrong somewhere along the way?

If the above rationale re Gain is accurate then I’ll start to think about what the gain should be given a max tank depth (based on a linear output from the sensor and converter).


Deleted post - I solved my own problem:)

Hi Jon, glad to hear that, just saw your post in my ever growing emails. You will have worked out the syntax, value =, channel) for single ended channels, you can also specify two channels for differential mode. Also, in your schematic you need to feed +5V to the logic level shifter, the purpose of this device is not to boost voltage as is suggested i think by your sketch. 5V will need to be generated elsewhere. Good luck, you must be getting close. Cheers, Steve B.

Thanks Steve,
You are correct, I had misunderstood the level shifters / forgotten how they operate. Having said that I have re-looked at the Analog Current to Voltage device on the Core website and it says:

“…3.3V~5.5V wide voltage power supply, 0~3V voltage signal output.”

From this I assume that if I feed it 3.3V it will still give the full 0-3V output.

Similarly, with the ADS1115, it says:

“it can run from 2V to 5V power/logic”

During my testing of the ADS1115, feeding VDD with the 3.3V from the Pycom LoPy4, when I provide 3.3V to A0 I get a reading of 32767 and when I put A0 to GND I get approx 0. This (I think) suggests that I am getting a full 16-bit range response with an input of 3.3V.

With nothing connected to the Analog to Voltage converter and the signal wire connected to A0 (again fed from the Pycom 3.3V), the reading on A0 is approx 0 (actual readings observed were -1, 0, 3, 5).

In short I guess I am failing to understand why the analog-voltage converter and ADS1115 need 5V when the LoPy4 board is a 3.3V devices and the 2 boards in question appear to run on 3.3V? Am I missing something with the pressure sensor and its requirements (I plan to feed that 24V)?

Perhaps @Graham or one of the team can confirm if the two components mentioned need 5V, or confirm if they will provide full functionality from 3.3V.

I have not yet connected the 24V convertor to the pressure sensor.


Hi Jon
The arrangement you have described and tested sounds fine. The current to voltage converter will provide 0-3V output based on 4-20ma signal and powered by 3.3V and the ADS1115 will provide a measurement range to suit if powered by 3.3V (and reflecting the programmable gain setting). You just need to ensure that the ADS1115 does not receive an input greater than Vdd as it can damage the device. So, no 5V required for your arrangement or a level converter which makes things easier. Powering the sensor loop is a separate supply as you have said, it will require a power supply as per its specs to generate the 4-20mA signal to the converter which in turn translates to 0-3V connected to the ADS1115. Good luck, let me know how you go. Cheers. Steve B.

Thanks @Steve47703,
Its great when someone with WAY more knowledge that me confirms my thinking / logic. I feel Im slowly learning stuff!
Just need to get the multi-meter out and start checking voltages before I get carried away with the 24VDC… Dont want to smell that acrid burning smell:)

With regards the pressure sensor, does it need any calibration within the software? I fairly happy that I can test the ADS1115 and get the software to output the correct A0 value from it (based on a supply of 0V, 3.3V and various values in-between (through the use of 2 resistors in a voltage divider fashion).

Once Im happy that the ADS1115 is measuring / reporting correctly, is it then simply a case of hooking up the other bits (sensor to convertor, converter to A0) and job done? The data sheet for the pressure sensor specifies a linear output from 0m-5m and 4-20mA so I am assuming that the only logic I need to establish in software are the parameters of my water tank and the resulting ADS1115 Gain. eg a 3m water tank / head of water could expect a maximum of ((20-4)/(5-0) * 3) + 4 = 13.6mA, which should provide an input voltage to the ADS1115 of (3-0)/(5-0) * 3 = 1.8V. 1.8V should equate to a reading of approx 17870 form the ADS1115.

This maximum 1.8V then allows determination of the ADS1115 Gain, in this case gain would = 2.


1 Like