ESPHome water level sensor

I guess this Post will help you:

@Syntox Not really.
I’m looking at using the INA219 to read the current directly on the ESP. I cannot see that this is disussed in the thread. My concern is that this has a precision of 0.8mA and that might give a too coarse resolution to be practical with the pressure sensor.

For those that might be interested.
I just tested a setup using a ESP32 with a INA219 current sensor module, measuring the the current of a TL-136 water level sensor (0-1 meter version, 4-20mA).

I tested it in the range from 0 to 20cm and it seems to give stable measurements from 4-7.3mA with a precision of ~0.1mA. This fit the INA219 specification with internal gain set to 400mA (div8).

This means that one should be able to monitor water level from 0 to 1 meter with a precision better than 1cm.

I’ll continue testing this and will report my findings.

1 Like

Just for the sake of comparison:
I got a 0-2m pressure sensor which reports in 4-20mA and am using a current to voltage converter and my accuracy is about 1mm. So I have higher accuracy but also a more complex set-up perhaps. More info about that can be found in posts above :wink:

Yes, your set-up might give higher precision, but is also more complex.

The INA219 connects easily to the ESP32 using I2C and is directly supported by ESPHome, so the setup is extremly simple.

With 0.1mA precision it will give you appx. 160 measuring points on a 4-20mA sensor. This is enough for a precision of less than 1cm for a 0-1 meter sensor, and a bit more than 3cm for a 0-5 meter sensor. For my purpose this is more than good enough.

Hi all,

Lots of interesting ideas above!

I’ve finished my water tank level sensor and successfully read level in range, volume/litres, and %. My project is Wemos D1_mini based, and my level sensor is the JSN-SR20 (ultrasonic, waterproof, dual-sensor model of HC-SR04, around AU$8). This sensor has a dead band of ~5cm so can be readily mounted direct to the top of the tank - no cone or spacer required, simplifying installation. It also has a range over 4m, for those with tall tanks! I’ve added a DS18B20 for external air temp, to round things out, and a rainfall sensor to tell me when it’s raining.

To get reliability I’ve added the following parameters (not mentioned anywhere above, but in the sensor docs) for the ultrasonic sensor:

  • Pulse_time extended to 20us. The default is 10us, whereas most sensors want a minumum of 20us.
  • Timeout set to 3m. The default is documented as 2m, but my sensor wouldn’t reliably report values over 1.80m without this.

I was getting regular “timeout” and “nan” values in my returns prior to adding these; none in the days since.

Others have noted time-of-day variability which would be temperature sensitivity - which I’m also seeing (tank level is currently 3cm overnight but 7cm when air temp is around 18C). There are arduino libraries to reduce temperature sensitivity, but not sure how to implement something like this in ESPHome. Has anyone had success in reducing temperature sensitivity?

1 Like

This is a great discussion. I’m contemplating adding a water level sensor in my above ground pool, so that it can stop the pump from running ‘dry’ if the water level is too low.
I’m thinking about placing it in the skimmer, so that it won’t be affected by the kids playing in the pool.
The skimmer is only about 20 cm’s high, so not much room to play with, but I’m thinking about using the TL-136 (0-1m) with INA219. If the water level is too low, the pump will empty the skimmer and suck in water, so there should be enough ‘room’ for a proper measurement, just a bit unsure of how the current of the water flowing through will affect the sensor?

I’ve finished my water tank level sensor yesterday, and I’m very pleased with the result !!!

Hadware :

TOTAL : about 40-45€ including shipping costs

The water pressure has a sensor for outdoor pressure that will help to take into account outdoor pressure when measuring water tank pressure.

The water pressure sensor output goes from 4ma et 20ma. The current converter allow a way better precision than using directly a pressure sensor that gives a voltage.
The current convertr can be adjusted. I’ve set mine to give 0V when water tank if empty, and 9V when it is full.
Accuracy is amazing !!! The Shelly displays voltage with 2 decimals and that’s very very stable. It means I have about 900 possible measures on a 3000 Liters water tank. That’s a 3.3 liter accuracy !!

Unfortunately, Home Assistant native Shelly integration only reports a 1 decimal rounded value, so that’s only 90 possible measures and a 33 liter accuracy which is enough for my usage indeed.
And this value is not reported at all through MQTT so there is no workaround this way either.

and you place the sensor on the ground of your tank?

Yes.
It’s heavy, so it goes down by itself.

sounds interessting. actually i do it with an ultrasonic sensor but it is not really reliable

That sounds like it should be OK. Flow around the sensor could be an issue but it’s a fluid so it won’t affect the pressure much - if it does you could place a small baffle (say a vented 3cm PVC pipe around it).

If you’re only concerned about a single level, wouldn’t a simple $2 tilt sensor (like Horizontal Liquid Float Sensor Switch Side Liquid Water Level Sensor Controller Automatic Water Pump Controller For Tank Pool|Flow Sensors| - AliExpress) do the job? No need for current/voltage conversion etc; I have one of these in my rainwater tank, been there 10+ years and still works to prevent pump run-dry,

Yes, that was my original plan, and I already have a couple of them here. The problem is that there is not enough room.
A general skimmer looks like this:


Bu mine is an above ground pool, so the skimmer is shortnecked, like this:

So the weir (when it tilts back) goes above the skimmer basket.
So if I install it I have to mount it just above the basket, but then I can’t remove the basket :slight_smile:
I then thought about placing it in the pre-filter on the pump (when it sucks air this will only be half full), but then I have to really break the basket there to place it.
I could also use something like this, and place it in the pump pre-filter:

But I can’t find that on aliexpress / banggood?
I’m going to do some more measurement, maybe I can get the horizontal switch in a smaller version than the one you linked (which is the exact one I have) or maybe even try to fit something like this:

?

Yes - limit space will restrict options. I’ve added a rain sensor to my install, but after one rainy day I’ve got “wet” conditions several days later. I suspect water in the connector where it won’t quickly dry out, so may have to seal that area to get reliability.

You could have the same problem with the Grove level sensor above given the humid environment, but as you’re only looking for wet/dry output maybe go low-tech: use a “rain-drop sensor” like…

Similar to the Grove unit but has electronics separated, so you can do away with the actual level sensor and just bare the ends of the cable (ends spaced a centimetre and positioned at the required low-water height) with cable connected to the same level sensor sub-board?

Ok, I went with two of the very cheap
image
I managed to find some spots where they could be mounted, and just misss the weir, and the basket could still be removed…

They are created with device_class: problem, so they say ‘ok’ or ‘problem’, which suits the task at hand.
The lowest one is open for ok, and the highest one os open for problem.

Looks good, the failsafe redundancy is a nice idea. Hope they do the job!

I have a thrown in level sensor from dfrobot connected through a current to voltage converter and a node MCU. I get the random voltage spikes and voltage variations throughout when no water is being added or removed see below. Can someone please help? Could this be related to the tank heating up and the water inside as the sun hits the western side of the house in the afternoon. Because it is always in the afternoon around the same time. Is anyone else seeing this?

My ESP config is:
sensor:

  • platform: adc
    pin: A0
    id: “water_tank_voltage”
    name: “Water Tank Voltage”
    icon: ‘mdi:water-percent’
    unit_of_measurement: ‘V’
    update_interval: 1s
    • multiply: 3.3
    • sliding_window_moving_average:
      window_size: 15
      send_every: 15
      send_first_at: 1
    • delta : 0.0015

I can confirm that my pressure transducer is affected by temperature. Water density does change with temperature, however, I suspect the transducers performance is what is actually being affected.

I have this type of sensor. It is externally mounted to the outflow pipe at the bottom of my tanks. I had decided to include a bmp280 temp/barrometric sensor in the enclosure for the microcontroller. At first the temperatures being reported got ridiculously high because the enclosure was a sealed black box and was sun exposed. After devising a sun-shade for the transducer and component enclosure, internal temperature held closer to ambient temperature. I was able to see that after overnight readings were stable (no water usage or major temperature changes). At around 8am when direct sunlight/ambient temperature increased, the pressure value decreased. I collected data for a week and became certain that once over 27c the pressure value started to drop. I was able to determine the pressure drop was linear to the increase in temperature, and so applied a linear calibration in firmware.


The light blue line shows after compensating for temperature.

I ended up correcting for this in firmware. I’ve been meaning to do a complete write-up on my experience with this sensor, but haven’t found the time.

esphome:
  name: water_tank_sensor
  platform: ESP8266
  board: d1_mini

i2c:
  scl: D1
  sda: D2
  scan: True

ads1115:
  - address: 0x48
    continuous_mode: on

sensor:
  - platform: bmp280
    address: 0x76
    update_interval: 1s
    pressure:
      name: "Barometer"
    temperature:
      name: "Thermometer"
      oversampling: 16x
      on_value:
        then:
          - lambda: id(temp_comp_factor).publish_state(x);

## Internal Voltage Reading
  - platform: ads1115
    id: tank_raw_voltage
    multiplexer: 'A0_GND'
    gain: 2.048 #3
    update_interval: 1s
    accuracy_decimals: 3
    on_value:
      then:
        - lambda: id(tank_voltage).publish_state(x);
        - lambda: id(tank_raw_percent).publish_state(x);

## Exposed Voltage Reading
  - platform: template
    id: tank_voltage
    name: "Water Tank Voltage"
    device_class: voltage
    accuracy_decimals: 3
    filters:
      - median:
      - exponential_moving_average:
          alpha: 0.2
          send_every: 25

## Exposed Tank Percentage
  - platform: template
    name: "Water Tank Pressure"
    id: tank_raw_percent
    update_interval: 1s
    accuracy_decimals: 0
    device_class: ""
    unit_of_measurement: "%"
    icon: "mdi:water-well"
    filters:
      - median:
      - exponential_moving_average:
          alpha: 0.2
          send_every: 25
      - calibrate_linear:
          - 0.450 -> 0.0
          - 0.820 -> 100.0
      - lambda: |-
          if (x >= 100) return 100.0;
          else if (x <= 0.0) return 0.0;
          else return x;
    on_value:
      then:
        - lambda: id(tank_comp).publish_state(x);

## Exposed Temperature Compensation
  - platform: template
    name: "Temp Comp Factor"
    id: temp_comp_factor
    accuracy_decimals: 2
    unit_of_measurement: "°C"
    device_class: ""
    filters:
      - calibrate_linear:
            - 27.1 -> 0.0
            - 31.1 -> 2.3

## Exposed Compensated Percentage
  - platform: template
    name: "Water Tank Compensated"
    id: tank_comp
    accuracy_decimals: 0
    unit_of_measurement: "%"
    icon: "mdi:water-well"
    filters:
      - lambda: |-
          if (id(temp_comp_factor).state <= 0) {
            return x;
          } else {
            return (x + id(temp_comp_factor).state);
          }
      - lambda: |-
          if (x >= 100) return 100.0;
          else if (x <= 0.0) return 0.0;
          else return x;
      # - heartbeat: 30s
      - exponential_moving_average:
          alpha: 0.1
          send_every: 5

Hope this helps.

2 Likes

Thanks @ronsum. I like how you have all your calculation are at the sensor output level in ESP home. I might use that idea and some of your code.

But what I find different is my voltage and level percentage calculation increases with temperature which is counter-intuitive I would have thought the hydrostatic pressure would decrease with increase in temperature as the density decreases or stay the same due to an equivalent increase in fluid height due to volume expansion in a fixed container volume. Note my tank is a vented non pressurised tank.

Do you think my volume expansion and hence fluid height increase greater than any density reduction hence I am seeing an increase in level/hydrostatic pressure?

I should probably say that I only have a layman’s understanding of the physics and electronics involved, all based on a few google searches regarding temperature and [water density, water volume, and pressure sensors]. Luckily I added a BMP280 sensor (thinking I may need to compensate for barometric pressure). When I noticed the unexpected fluctuations, I added the BMP280’s data to Grafana and was first able to realize the issue and then gather the data to write the compensation in firmware.

What you described seems to be in sync with the thermal effects on water. My readings weren’t, which lead me to believe that it was the sensor being affected. Either way, if you’re experiencing fluctuations that seem to coincide with the sun, it is likely a temperature issue.

As your sensor is the drop-in type (same temp as water) and the readings seem in sync with thermal effects on water, I suspect you need to monitor the water temperature in your tank. Having my sensor and other electronics all external and housed in the same environment allowed me to use the BMP280 sensor. I can’t recommend any particular in-tank water temperature sensor.

Add a temperature sensor internally (in tank) or externally (at microcontroller), and collect data on a fixed volume of water over a few days. Once you add temperature to your graph, you can verify if a spike in pressure corelates to a spike in temperature, and by how much.

The links up top should help understand the physics.

This is my tank and sensor setup:



2 Likes