Using ESPhome to build a water flow rate meter

In case anyone cares, the 10k resistor is meant to hold the input signal level high. When the magnet gets next to the sensor that input gets pulled low by the hall sensor, When the magnet goes away the resistor to 5v pulls the input high again. Since the D1 max input voltage spec is 3.6v, applying 5 volts for an extended time is likely to wear out your input if not kill it outright. Ideally the pullup resistor should be tied to a 3.3v supply. I would be interested in how long the device survives with 5v pullup. Please report if it dies.

2 Likes


So this should be the suggested wiring diagram…isn’t it?

Thank you for that post !

which water flow sensor are you using ?
how to calculate the resistor and capacitor depending on VCC ? (ESP32 with ESPhome)
if VCC is 5V can I use the same PSU for Sensor & ESP32 ? (no idea of power consumption of YF-S401 Water Flow Sensor)

Thanks for all the input on this thread. I am trying to implement an automation that when a flow meter detects a massive flow (high gallons/min rate) from the livestock water line it will automatically close a valve since we are on a well. The livestock (cows, water buffalo, & pigs) can be tough on the infrastructure and there have been a few times a ruptured line can quickly drain our 5,000 gallon (18,9000 Liter) holding tank. It takes about 2 days to refill the water tank so every drop counts.

I am now getting my mind wrapped around on how to do the first part of measuring the flow. I currently am using a M5Stack ATOM Lite and a this DAE MJ-100a Flow meter for our livestock water line and have it showing in HA:

image

ESPHome and HA along with everything everyone has been sharing is making this much easier than expected. Now off to work on the second part and learn about relays to control the valve. I’ll also be adding a water pressure sensor to monitor our water tank levels.

1 Like

Hi @kimocal , great to hear that it’s working for you. You don’t mention what valve you’re using, but I assume that it’s something that can be activated by a relay. The only thing to watch for is how much current it uses to move the valve - for water flow, it can sometimes be higher than you think, which means a 10A relay such as you commonly find in Sonoff devices, or standard hobby relays, might not be enough.

You’ll have to check the spec sheet for the electronic valve you’re using. If it needs more than 10A, you can still use a relay to control a Contactor with sufficient amps. Contactors are like big relays, you can get them at an electric supply store, and they can be controlled with a small amount of current.

In any case, setting up a relay in ESPHome is very simple - see below.

switch:
  - platform: gpio
    name: "Valve Control" # or whatever you want to call it
    pin: GPIO12 # change for the actual GPIO you are using
    id: relay # optional, but useful if you're going to call this from a physical button

And that’s it. ESPHome will do the rest, and it’ll show up as a switch entity in Home Assistant.

Thanks for the info.

I had originally bought a Shelly 2.5 and this 3 Wire AC/DC ball valve. After getting the Shelly and playing around I realize I hadn’t read the Shelly 2.5 DC wiring close enough. The Shelly outputs negative, and I need positive for that valve. So now I ordered some relay boards and will be using a 2nd M5Stack ATOM Lite. This way I can add the pressure sensor to monitor my water tank level and also add another flow meter to monitor all the ag water lines. The first Atom Lite is further away and will only be used for the flow meter on the livestock water line. The Shelly will be used for a future project or I just may return it.

EDIT

Valve wiring discussion here.

1 Like

I’ve now needed another water meter and came across this. It has a dry contact reed switch that closes for each litre of water, making it nice and simple to implement and no scaling or calibration required.

Ebay water meter

1 Like

Used with a waterproof ultrasonic sensor
i’m using the dfrobot model:

  - platform: ultrasonic
    trigger_pin: GPIO 01
    echo_pin: GPIO 03
    name: "Ultrasonic Sensor"  
    pulse_time: 10us
    update_interval: 1s

    
  - platform: ultrasonic
    trigger_pin: GPIO 1
    echo_pin: GPIO 3
    name: 'ultrasonic water distance'
    id: dist2water
    unit_of_measurement: 'm'
    accuracy_decimals: 3
    update_interval: 2s
    pulse_time: 10us
    timeout: 2.0m
    filters:
      - filter_out: nan
      - sliding_window_moving_average:
          window_size: 10 #creates a moving average of the last 10 values
          send_every: 1 #sends the moving average at every measurement (but only if it passes the delta filter below)) 
          send_first_at: 1 #after startup immediately start sending the result rather than wait for the first 10 measurements
      - delta : 0.0015 #only send the result if the voltage difference with the last sent result is higher than this      
  - platform: ultrasonic
    trigger_pin: GPIO 1
    echo_pin: GPIO 3
    name: "Ultrasonic Sensor Level"
    unit_of_measurement: '%'
    accuracy_decimals: 3
    update_interval: 5s
    pulse_time: 10us
    timeout: 2.0m
    icon: mdi:water-percent
    filters:
      - lambda: return ((((x*100)-27)-(60-27))/(60-27))*-100;
      - filter_out: nan
      - sliding_window_moving_average:
          window_size: 10 #creates a moving average of the last 10 values
          send_every: 1 #sends the moving average at every measurement (but only if it passes the delta filter below)) 
          send_first_at: 1 #after startup immediately start sending the result rather than wait for the first 10 measurements
      - delta : 0.0015 #only send the result if the voltage difference with the last sent result is higher than this
  - platform: ultrasonic
    trigger_pin: GPIO 1
    echo_pin: GPIO 3
    name: "Ultrasonic Sensor Volume"
    unit_of_measurement: 'l'
    icon: mdi:cup-water
    accuracy_decimals: 2
    update_interval: 2s
    pulse_time: 10us
    timeout: 2.0m
    filters:
      - lambda: return ((((x*100)-27)-(60-27))/(60-27))*-70;
      - filter_out: nan
      - sliding_window_moving_average:
          window_size: 10 #creates a moving average of the last 10 values
          send_every: 1 #sends the moving average at every measurement (but only if it passes the delta filter below)) 
          send_first_at: 1 #after startup immediately start sending the result rather than wait for the first 10 measurements

you’re welcome
/LeFab

3 Likes

hi there. can you please help me with the total water usage? how can i achieve that? thank you.

See post above by DeeBeeKay

I finally got the rest of the parts to install it and am hoping to get it done this weekend. Then I can start tracking the water the livestock is using. Working on actionable notifications now for when it detects a high flow rate.

1 Like

Hi Fabien,

i’m very curious about your solution , you have been able to mesure water flow with only 1 JSN-SR04T ?

how do fix the sensor to your pipes?

thanks for sharing your code :slight_smile:

1 Like
ads1115:
  - address: 0x48
i2c:
  sda: 4
  scl: 5
  scan: True
  
sensor:
  - platform: ads1115
    multiplexer: 'A0_GND'
    gain: 2.048
    id: watertank_voltage
    name: "watertank Level Voltage"
    icon: 'mdi:water'
    unit_of_measurement: 'V'
    update_interval: 0.5s #the delta filter will ensure it only sends values when something changes. 
    filters:
      - sliding_window_moving_average:
          window_size: 5 #creates a moving average of the last 10 values
          send_every: 1 #sends the moving average at every measurement (but only if it passes the delta filter below)) 
          send_first_at: 1 #after startup immediately start sending the result rather than wait for the first 10 measurements
      - delta : 0.001 #only send the result if the voltage difference with the last sent result is higher than this

  - platform: uptime
    name: "irrigation System Uptime"
    
  - platform: wifi_signal
    name: "WiFi Signal Sensor"
    update_interval: 60s
    
  - platform: ultrasonic
    trigger_pin: GPIO 01
    echo_pin: GPIO 03
    name: "Ultrasonic Sensor"  
    pulse_time: 10us
    update_interval: 1s

    
  - platform: ultrasonic
    trigger_pin: GPIO 1
    echo_pin: GPIO 3
    name: 'ultrasonic water distance'
    id: dist2water
    unit_of_measurement: 'm'
    accuracy_decimals: 3
    update_interval: 2s
    pulse_time: 10us
    timeout: 2.0m
    filters:
      - filter_out: nan
      - sliding_window_moving_average:
          window_size: 10 #creates a moving average of the last 10 values
          send_every: 1 #sends the moving average at every measurement (but only if it passes the delta filter below)) 
          send_first_at: 1 #after startup immediately start sending the result rather than wait for the first 10 measurements
      - delta : 0.0015 #only send the result if the voltage difference with the last sent result is higher than this      
  - platform: ultrasonic
    trigger_pin: GPIO 1
    echo_pin: GPIO 3
    name: "Ultrasonic Sensor Level"
    unit_of_measurement: '%'
    accuracy_decimals: 3
    update_interval: 5s
    pulse_time: 10us
    timeout: 2.0m
    icon: mdi:water-percent
    filters:
      - lambda: return ((((x*100)-27)-(60-27))/(60-27))*-100;
      - filter_out: nan
      - sliding_window_moving_average:
          window_size: 10 #creates a moving average of the last 10 values
          send_every: 1 #sends the moving average at every measurement (but only if it passes the delta filter below)) 
          send_first_at: 1 #after startup immediately start sending the result rather than wait for the first 10 measurements
      - delta : 0.0015 #only send the result if the voltage difference with the last sent result is higher than this
  - platform: ultrasonic
    trigger_pin: GPIO 1
    echo_pin: GPIO 3
    name: "Ultrasonic Sensor Volume"
    unit_of_measurement: 'l'
    icon: mdi:cup-water
    accuracy_decimals: 2
    update_interval: 2s
    pulse_time: 10us
    timeout: 2.0m
    filters:
      - lambda: return ((((x*100)-27)-(60-27))/(60-27))*-70;
      - filter_out: nan
      - sliding_window_moving_average:
          window_size: 10 #creates a moving average of the last 10 values
          send_every: 1 #sends the moving average at every measurement (but only if it passes the delta filter below)) 
          send_first_at: 1 #after startup immediately start sending the result rather than wait for the first 10 measurements
      - delta : 0.0015 #only send the result if the voltage difference with the last sent result is higher than this
  - platform: pulse_counter
    pin: 02
    id: water_usage
    name: 'Current water usage'
    unit_of_measurement: 'L/min'
    accuracy_decimals: 2
    update_interval: 2s
    filters:
      - lambda: return x / 450.0;
      - filter_out: nan
      - sliding_window_moving_average:
          window_size: 10 #creates a moving average of the last 10 values
          send_every: 1 #sends the moving average at every measurement (but only if it passes the delta filter below)) 
          send_first_at: 1 #after startup immediately start sending the result rather than wait for the first 10 measurements
      - delta : 0.0015 #only send the result if the voltage difference with the last sent result is higher than this

there you go

/LeFab

1 Like

I’m also paranoid, specially after a bad transformer was putting the roof on fire.

Could you please tell me more about MOV used there? What are those specs and if the use of the capacitor is related to them?

Actually I’m using fuses instead.

Thanks.

Hi @raidnet-ms, I made that board 2 years ago and its been in a box on a pole ever since. I’m afraid I don’t remember what the specs of the MOVs are, I just remember that I chose them for their capacities.

Power out here is very bad; the system hasn’t been maintained in decades and everyone expects it to collapse. We get brown-outs, spikes, and short drops from things like trees brushing the lines. And that’s just on a local level. Nationally we also have rolling blackouts - scheduled outages to help reduce load on the grid. When the power comes back, it tends to spike at the moment it comes on, and can destroy appliances.

My intention with the big MOV was to smooth out spikey transients in the power, and protect the circuit if bigger than expected voltages appear. A fuse after it would probably be a good idea, you’re right.

The capacitor smooths the DC power, and acts as a sort of miniature UPS. One of the many power problems we get is that power can go off, then immediately back on. Not great for connected devices. Although it will only last a second or so, the capacitor should keep the circuit running during these very common events.

Since I built that device, we have invested in an array of solar panels and a 5kW inverter. We are still grid-tied, but the inverter conditions the incoming power so that it is smooth and stable. So a lot of these tricks are no longer strictly necessary. Still, you can’t be too safe.

1 Like

I see, thanks!

I bought 2 types of MOV but I wasn’t able to use them.
5D471K
14D241K
I didn’t find a place where I could understand what code is meant for the capacity I need for a circuit like yours.
If you got a link where I could understand how the code/capacity works, would be great!

Great idea the capacitor use, I will grab it!

Any idea how to revert polarity for bistable solenoids?

The supplier I bought MOVs from was kind enough to list the voltages that the MOVs could handle in the product descriptions - that’s how I knew what to get.

The best thing to do is to search for the product code along with the words “spec sheet”. Google says that your 5D471K can handle up to 750V, which is not good for either 110v or 240v power supply (I don’t know what you have). If there was a spike of 700v it would cook your device long before the MOV kicked in.

The 14D241K handles 240v, though, so that might work, but it doesn’t allow a lot of overhead. For example, my power is 240v but will often go just a few volts over, which would trigger this MOV.

I am afraid I don’t know anything about solenoids, bistable or otherwise.

1 Like

I’m in EU yes, so you recommend something a little higher then 240v?
In the 14D241K link you sent me I read a value called “clamping value”. Does it mean anything important? :slight_smile:

I am not very advanced in these topics, but as I understand it, the clamping value of an MOV is the voltage at which it will kick in, preventing the excess voltage from reaching your circuit. Depending on the size of the incoming spike, this may destroy the MOV, but it sacrifices itself to save the circuit.

I would recommend something just a little higher than 240 volts only so you don’t have it clamping from normal voltage fluctuation, if that’s a thing where you live. Here in South Africa the voltage varies between 220-240, and a little bit on each side.

1 Like

So as far I understand this 14D241k handles 240-390v. Over 390 it should pop and burn opening the circuit :slightly_smiling_face:
While fuse works only on current, this preserve for overvoltage.

The mov has one leg on L and the other on N. Right?