ESPHome water level sensor

I have the following sensor (https://www.hobbytronics.co.za/p/1119/waterproof-ultrasonic-distance-transducer) connected to a ESP32 board running ESPHome. I am getting values successfully as well by setting up my sensor with the following code (https://esphome.io/components/sensor/ultrasonic.html) from the ESP website. It is currently displaying distance in meters (0.22m for 22cm away). I would like to use this sensor to measure the water level of a water tank and return the values for 0-100 (scale). the tank is about 1.12m deep and I have the sensor mounted about 25cm above the tank to compensate for this sensor not being able to reliably read obstacles closer than 25cm’s. This will have to work in reverse somehow as the level will never rise above 100 (scale), only drop, and the distance will therefore only increase from 0.25m to 1.12m. Please assist me with a solution to use in Home Assistant like a template sensor or alternatively the YAML code for ESPHome.
water%20level%20sensor

5 Likes
Tank level (%) = -114.94*X +128.74 where X is the distance in meters.

To adjust your ESPhome distance sensor to output % instead of meters apply this filter:

filters:
  - multiply: -114.94
  - offset: 128.74

Or

filters:
  - lambda: return x * (-114.94) + 128.74;

Don’t forget to change the unit of measurement to %.

unit_of_measurement: "%"
accuracy_decimals: 0

@tom_l, thanks for the quick reply, here is my code

#################################################################
## DEFAULT CONFIG - SENSOR NODE WATER LEVEL
#################################################################

esphome:
  name: sn12
  platform: ESP32
  board: nodemcu-32s

wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password
# Optional manual IP
  manual_ip:
    static_ip: 10.0.0.41
    gateway: 10.0.0.2
    subnet: 255.255.255.0

# Enable logging
logger:

# Enable Home Assistant API
api:

ota:

web_server:
  port: 80

#################################################################
## SENSORS
#################################################################

# Example configuration entry
esp32_ble_tracker:
  scan_interval: 300s

sensor:
  - platform: xiaomi_miflora
    mac_address: 'C4:7C:8D:6A:3E:97'
    temperature:
      name: "Xiaomi MiFlora Temperature"
    moisture:
      name: "Xiaomi MiFlora Moisture"
    illuminance:
      name: "Xiaomi MiFlora Illuminance"
    conductivity:
      name: "Xiaomi MiFlora Soil Conductivity"
    battery_level:
      name: "Xiaomi MiFlora Battery Level"

# Example configuration entry

  - platform: ultrasonic
    trigger_pin: GPIO13
    echo_pin: GPIO12
    name: "Tank 1 Water Level"
    filters:
      - filter_out: nan

1 Like

Sorry, I just edited my post while you were replying. See above.

Thank you very much for your help, I will try this code tonight.

@tom_l, I have uploaded the code but I am getting a value of -14875 %.

Never-mind, I switched to the lambda code, and it look like it is working.

Which value do I change to fine tune the % value?

Thanks for your help.

If the range isn’t lining up correctly it will be the 114.94 (the multiplication factor), but if the zero point is not correct its the offset you want to adjust (128.74)

This is not answering your question but a few people out there using a different approach to your problem.

Measuring tank level you can easily face into other problems with the ultrasonic sensor, like humidity, condensation and moisture on the head of the sensor when the environment temperature changes or the water evaporates, all of them faking or creating invalid data.

Instead of using ultrasonic distance measurement it’s easier and more accurate to use a cheap pressure sensor installed at the bottom of your tank. Variable voltage will give you the pressure values. Knowing the specific gravity of the water is 1, you can very precisely get the height of the water level calculating back from the hydrostatic pressure with an accuracy of few millimeters based on the quality of the pressure head. The only thing influencing the level is the specific gravity of the fluid which can be easily adjusted if you are measuring other liquid than water.

1 Like

Do you have a pointer to an appropriate sensor?

I’m sure a cheaper version could be found but this is the type of thing A320Peter is referring to

1 Like

Thanks @sparkydave and @A320Peter this is good to know for version 2.0.

Just FYI that was because the offset was applied before the multiplication. I’m not sure if the filters are applied in the order they are listed or by some other random method. That’s why I also listed the lambda version.

1 Like

Eg this confirmed it works with and arduino so should be fine:

pressure sensor

You should consider which type you need based on the size of the tank but for home usage usually 5-20 psi is more than enough.

1 Like

Hi folks,

I’m doing the same thing - as winter draws to a close here in Australia, focus returns to the amount of water in the tanks.

I was hoping I could get an explanation of the values supplied by @tom_l in the first reply?

If my tank is 1.8 meters in height, and the waterproof ultrasonic emitter can only read from 20cm above the surface - what would the values be? How do I read what these values (114.94 & 128.74) represent?

I’ll be working out what my total storage value is, so I’m looking to additionally calculate what 1% of the tank would be - then show how many litres used/collected in a day based on the percentage fluctuation.

Thanks folks!

Brendan

I think I may have nailed this myself:

sensor:
  - platform: wifi_signal
    name: "WiFi Signal Sensor"
    update_interval: 60s
    
  - platform: ultrasonic
    trigger_pin: GPIO5
    echo_pin: GPIO4
    unit_of_measurement: "%"
    icon: "mdi:water-percent"
    accuracy_decimals: 0
    update_interval: 5000ms
    name: "Water storage"
    
    # tank height: 200cm
    # height from full to sensor: 22cm (essentially sensors minimum distance)
    # full tank: 180cm
    # current reading: x
    # ergo: used = (x - 22)
    # ergo: remaining = (180 - used)
    # ergo: percent = (remaining / 180) * 100
    
    filters:
      - lambda: return (1-((x-.22)/1.8))*100;
      - filter_out: nan

Seems right math wise. Let me know your thoughts.

5 Likes

I’ve been trying it out with one of the cheap HC-SR04 sensors. When testing it against a wall It only works up to about 1.5m (even though the spec sheet says up to 4.5m). Has anyone got one reliably working up to 2m or so?

Not sure who advertised it as 4.5m. Most sites have this sensor listed as only having 0.4m range.

The same Chinese websites who tell you 18650 cells have a capacity of 9000mAh! Lol. So I’m after a different one that has practical range of up to 2m, preferably waterproof.

The data sheets I have been able to find say 400cm, which is 4m. https://www.electroschematics.com/wp-content/uploads/2013/07/HCSR04-datasheet-version-1.pdf

EDIT: then again, this one says 5m. FIIK. https://www.electroschematics.com/wp-content/uploads/2013/07/HC-SR04-datasheet-version-2.pdf

1 Like

Well that was dumb. In my defence I… got nothing.