Thomas shares makes

2025-07-30

Rainwatertank Level Pressure Probe

rain water level sensor principle

Pressure based water level sensor

I designed and built my own rainwater tank level sensor for fun a few years ago. Unfortunately the unavoidable happened and its insides got wet... I had to fix it or get an other one. My brother had installed a submersible Pressure Transducer in his rainwater tank, and rather than improving my old project I chose to get an off the shelve sensor to measure the tank level and use the saved time for other fun projects.

Principle

modbus adc module

Pressure level transmitter principle.

The weight of the water column creates a pressure difference which the transmitter module converts to an electric current value.

This sensor is a drop-in replacement for my own rainwater tank level sensor, so hooking the sensor up is exactly the same.

Note

In the article I wrote about the sensor I designed I explain how the current loop principle works, check it out for more juicy details.

Current loop to Modbus

I bought a very crappy Analog to digital conversion module on Aliexpress:

It's a 6€ "4-20MA RS485 Voltage Current Analog Collector ADC Modbus RTU 4-Channel N4AIA04 Voltage Current Acquisition Module", which I plan to replace with a device of my own design somewhere in the future.

modbus adc module

Analog (4-20mA and 0-10V) to Modbus converter

Configuring and testing

First we need to set the Modbus address to be an unique value:

modbus  -b 9600 -s 1 /dev/ttyUSB0  14=6

Read current values

modbus  -b 9600 -s 6 /dev/ttyUSB0  2 3

Next we need some Homeassistant configuration, first we set the details in modbus.yaml on how to read the sensor:

- name: level_current
  slave: 6
  address: 2
  scale: 0.1
  precision: 1
  data_type: uint16
  unit_of_measurement: mA
  device_class: current

And add a template sensor(template.yaml):

- trigger:
    - platform: time_pattern
      minutes: "/1"
    - platform: state
      entity_id:
        - sensor.filtered_level_current
      not_from:
        - "unknown"
        - "unavailable"
      not_to:
        - "unknown"
        - "unavailable"
  sensor:
    - name: rainwater_level
      unique_id: rainwater_level
      unit_of_measurement: "%"
      device_class: signal_strength
      state_class: measurement
      state: >
        {% set l = states('sensor.filtered_level_current')|float %}
        {% set level = (((l - 4)/16) * 100 ) %}
        {{ '%0.3f' | format(level) }}
      attributes:
        dummy: "{{ now().minute }}"

To overcome the noise of the crappy ADC Modbus module, I added a low pass filter:

- platform: filter
  name: "filtered_level_current"
  entity_id: sensor.level_current
  filters:
    - filter: time_simple_moving_average
      window_size: "01:00"
      precision: 2

Automations

What's next is to add an automation that sends me an alert when the water level gets too low. For the time being my obsession about the data and plots keeps me informed, but at one point it will grow old and the toilet might stop flushing suddenly...


Liked something? Worked on something similar? Let me know what you think on Mastodon!
You can use your Mastodon account to reply to this post.

Reply to post

You can respond to this post with an account on the Fediverse or Mastodon. Since Mastodon is decentralized, you can use your existing account or create your account on a server of your choice.

Copy and paste this URL into the search field of your favourite Fediverse app or the web interface of your Mastodon server.

Learn how @carlschwan wrote the code that loads Mastodon posts into this webpage here.

Follow me on Mastodon!