Using ESPhome to build a water flow rate meter

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?

Your understanding and my understanding are the same. We can still both be wrong, but right now we agree.

One MOV leg on L, one on N, yes. Unlike a capacitor, the MOV doesn’t care which leg goes where.

1 Like

Hi Alexxed, I have the same YF-B5 and used your x/396 calculation. It seems to underestimate usage (~70%). What are your findings? How accurate are your measurements?

Hi,
I’m using the yf-b2 water flow sensor for my measurements and monitoring my system, but sometimes the code can’t detect the small amount of watering I’m using for.
My watering valve turns on each hour for 30 seconds and then turn off the watering valve for that reason it can’t detect the flow.

My code :
sensor:

  • platform: pulse_counter
    pin: GPIO5
    name: “Water flow”
    update_interval: 10s
    filters:
    • lambda: return (x / 7.5) * 60; → I changed it to 1 and also the unit to s/m but can’t detect either.
      unit_of_measurement: “L/m”

thanks for any help.

Hello everyone!

This thread is the graal for those looking to build flow meters with ESPHome! Thank you all for sharing your knowledge and building the path toward achieving it. I still have a question that, I think, has not been answered so far.

kbx81 on the ESPHome Discord channel said that:

apparently the GPIO pins on the ESP32 are all 5-volt tolerant

I am working with a YF-B5 + ESP32 Development board. I’ve seen some people in this conversation adding a 10k resistor to keep signal pin high. Can I build a flow meter without using a resistor or are there cons to not using it? rradar on ESPHome Discord channel suggested that I

could activate the internal pull up from the esp

I am wondering if using internal pull up from the ESP32 would really help avoid applying 5 volts for an extended time. Is a 10k resistor the only way to go? Anyone has knowledge on this?

I’am using a d1 mini and use the internal pullup, everything is working ok.
Used code:


  - platform: pulse_meter
    pin: 
      number: D4
      mode: INPUT_PULLUP

1 Like

Thanks Johnny,

I got it working too, here is my code:

sensor:
  - platform: pulse_counter
    pin:
      number: 4
      mode:
        input: true
        pullup: true
    unit_of_measurement: 'L/min'
    id: water_usage
    name: "Débit d'eau instantané"
    update_interval: 5s
    filters:
      - lambda: return (x / 396); # 396 = 6,6 * 60
1 Like

Hi @raminrajabi, I’m sorry to hear you’re struggling.

I don’t have any useful advice for you, but, surely if it’s on for 30 seconds that should be fine?

This is a very low tech solution, but it worked for me before I got a big flow meter.

  1. Get a jug of known size (eg 1L), and a stopwatch (eg the Clock app on your phone).

  2. Start the water flowing.

  3. Fill the jug, timing how long it takes to fill 1L. Note the result, and repeat a few times.

  4. Average the result times.

Now you know how long it takes to pump 1L. Extrapolate to 30s.

Not as useful as an actual working sensor, but, better than nothing.

I waiting for my 3/4" 2-45 l/mn copper version and a D1 mini.

thank you so much all for your previous experiences. will come very handy.

@donparlor Sorry I’m only noticing your question now.

I am not strong on the electronics side, I tend to learn by googling what others have done, and making terrible mistakes.

I did use a 10k resistor when I built my initial device based on a Wemos D1 mini (esp8266). However, I have also found that this wasn’t necessary. While experimenting, I got just as good signal connected to other pins that didn’t have the 10k resistor, and that’s to a sensor with a cable that runs a good 12 metres.

So I would say test it and see. The common wisdom is that the 10k resistor is necessary, and I sort of understand why a bit. But my personal experience is that there doesn’t seem to be a benefit.

Of course, if it’s not working at all, maybe add the resistor and see?

Hello @DeeBeeKay!

After 15 days, I confirm it is working flawlessly. The pull up parameter seems to provide a reliable signal and ESP32 pins are very stable with a 5V input from the flow meter. I managed to do quite a lot of interesting programming with my flow sensor, I get different values calculated, I’m very happy with the end result:

For english readers, I have the following values calculated:

  • Instant water debit
  • Total volume in cubic meters
  • Total volume in liters
  • Duration of the last water usage
  • Volume of the last water usage
  • Cost of the last shower

Thank you all for sharing your setup in this thread.

6 Likes

bonjour vincent, @donparlor

will you be happy to share your code ?
blueprint ?

Stephane