Using ESPhome to build a water flow rate meter

Greetings fellow humans,

I wish to build a thingy that tracks the flow of water from our borehole pump to the tanks. I am using a Wemos D1 R2, and a YF-DN40 water flow sensor (the big one). I notice that ESPhome has a Pulse Counter, which is basically how a flow meter works: there’s an inline rotor with a magnet in it, and a hall sensor that notices when the magnet comes round again.

Before I go barking up the wrong tree, is the Pulse Counter the right component to use? I could hack something up in the Arduino IDE, but ESPhome integrates so beautifully into HA (and therefore NodeRed) that it would make capturing this data into pretty graphs very, very easy. Am I on the right track?



To me, your approach of using pulse counter seems like the right approach. I am also interested in this kind of water flow rate meter.
YF-DN40 is a plastic material sensor and I would prefer a brass one for durability and to avoid any leakage situations.
SEN-HZG1WA 1" Brass Water Flow Sensor is one I found on the web.

I will be very interested to know the outcome of this project.

Hi @Puneit_Thukral, thank you for your encouragement.

I would also prefer a brass sensor, but these things are unfortunately not easily available in my country. Even the YF-DN40 was extremely expensive - I could have bought 10 Wemos D1s for the same money.

Anyway, so far so good. I had a little trouble to begin with because I was trying to power the sensor from the Wemos 5V out, which it didn’t enjoy. But once I gave the sensor 5V off the rail, it worked great. It is reporting pulses to HA just fine.

Now I just need to figure out the formula to translate pulses into Litres/hr, which I think I can do right there in the ESPhome config. If I don’t come right with that, then I’ll do it in Node-RED.

1 Like

It looks like your sensor specs are:


* Thread size: Male 1 1/2”
* Size:L  92x OD46  X1.5"
* Colour: Black colour 
* Flow rate: 5~200L/min
* Flow Pulse:  F(Hz)=(0.45xQ) +/-3%    Q=L/min
* 1L water= 27Pulse
* Max. Working Current: 15mA (DC5 V)
* Min. Working Voltage: DC 4.5V
* Working Voltage: DC 5V~24V
* Load Capacity: =10 mA (DC 5 V)
* Operating  Working  Temperature : 
* -25 Degree centigrade to +80 Degree centigrade
* Liquid Temperature: 85
* Accuracy: 3~5%
* Working environment: water, liquid,  light oil etc

So for every litre of water which passes through it 27 pulses should be read.

You may need to configure at least two counters to get the result you want.

The first counter will count to 27 and then deliver one pulse to the second counter (litres cumulative counter) and at the same time reset itself to zero and commence counting again.

If you want litres per hour you may need another counter and a timer to continue counting the litres but reset itself to zero each hour.

You can keep repeating for 24hr or 7 days etc.

That’s how I do it in PLC’s so not sure how you do that using ESPhome?

1 Like

Hi @wellsy, thank you for posting those specs. I have been unsuccessful in finding them myself, beyond the fact that it generates 27 pulses per litre, so that info was super handy.

I think a lot of the work you’re describing has already been done in ESPhome. The reason I say this is that simply by hooking the sensor up to the board and defining it in the yaml (ie: this is a pulse counter) I was getting pulses per minute back from it. I did not have to count total pulses myself, or measure time - it was already kicking back the data as “pulses per minute”, so it seems that a lot of the hard word has already been done. The number it’s producing directly correlates with how fast it’s spinning, it’s not an increasing total.

This being so, converting that data into L/hr was achieved with a very basic lambda. Here’s my config, which @Puneit_Thukral may also find useful:

  - platform: pulse_counter
    pin: GPIO5
    name: "Pulse Counter"
    update_interval: 5s
    - lambda: return (x / 27.0) * 60.0;
    unit_of_measurement: "L/hr"  

The update interval is too quick for practical everyday use (more data than I want) but perfect for testing now. I will reduce it to the default of 60s when I deploy it. The sensor filter divides the incoming pulse rate by 27 (because we know it’s 27 pulses per litre) and then multiplies by 60 to get the value per hour.

That appears to be all that’s needed to get this to work in ESPhome. Truly, this software is a marvel.


Why not just divide pulse by 27 to get litres? Then you don’t need two counters. (I may be missing something, that happens!)

That’s exactly what I did, see the quoted yaml config. Works great!

1 Like

Thanks, it really inspires me try as well

1 Like

Hi DeeBeeKay, How did you setup it up with d1 mini?

Hi @saboaua, are you asking to see my complete yaml file, or do you want pictures of the circuit?

Yes, if you can share some pic of the project and yaml file. I’m looking to implement something similar and found your topic.

Luckily I have the board in front of me (it’s going back in the enclosure later this morning) so I was able to snap a picture.

As you can see, not a lot exciting going on. On the right, AC power coming in. I put it through a large MOV, and then a PCB-mount 220V-5V adapter. Then a small MOV (because I am paranoid), and a 4700uF capacitor. All of that is just to clean the power supply and protect the D1 from spikes.

Then I just have the D1 Mini mounted on some female pin headers, and on the other side of the board, I soldered some traces. On the left side, the three connectors are for the flowmeter, and the trigger and echo pins of the ultrasonic I’m using to measure how much water is in the reservoir.

The resistor you see on the left joins to the flowmeter’s data line before it hits the D1’s input pin. It’s a 10kohm resistor, coming from 5V+. I am not an electronics genius, I saw this in a YouTube tutorial for working with this flowmeter, and they didn’t explain it, but if I have to guess what it does, I think it effectively boosts the signal that the flowmeter is putting out.

Here is the full yaml file:

  name: d1m001_reservoir
  platform: ESP8266
  board: d1_mini

  ssid: "xxxxxxxx"
  password: "xxxxxxxxxxxxx"

# Enable logging

# Enable Home Assistant API


  - platform: pulse_counter
    name: "Flow rate"
    pin: GPIO5
    update_interval: 60s
    - lambda: return (x / 27.0) * 60.0;
    unit_of_measurement: "L/hr"  
  - platform: ultrasonic
    name: "Reservoir level"  
    trigger_pin: D3
    echo_pin: D4
    update_interval: 60s
    - lambda: return 200000 - ((x / 2.1) * 200000.0);
    unit_of_measurement: "L"

As you can see, I am using filters to format the data into usable form. ESPHome reports the flowmeter’s speed in revolutions per minute, and I know that the flowmeter turns 27 revolutions per litre. Therefore the formula is (x/27)*60, which gives the speed in Litres per hour.

Then for ultrasonic, I really want to do the formula better, but, basically, I know the capacity of the reservoir is 200,000L, and it’s 2,1m deep. The ultrasonic is returning a measurement in metres, so I divide by 2.1 to get percentage, and multiply by 200,000. This effectively shows how much water would still be needed to fill the reservoir. To get the actual amount, therefore, I just subtract the result from 200,000. It works, but I wish I could make that calculation a little more elegant.

Anyway I hope that helps you.

200000.0 * (1.0 - (x/2.1))

But that is really the same number of calculations

1 Like

or better

200000.0 - (95238.0 * x)

which is just simplifying 200000/2.1 = 95328

1 Like

True, but, yours is much more beautiful and clean.

Much better! But oddly, not as beautiful as the previous one :rofl:

Thank you for your contribution, I feel much better about it now.

Thanks for sharing your project. I also noticed some setup has the resistor, but as you mentioned, there’s not allot details on the setup.

Will try it out!

Perhaps you are after a circuit diagram?

I’m using this flow meter which includes a resistor on the unit which, I believe, makes it unnecessary to put one on the board.

This is more of a presumption on my part as my electronics knowledge is far from great.

The unit is plastic. I haven’t been able to find a brass unit that uses npt fittings (npt is the US plumbing standard for threaded fittings). The rest of the world seems to use the British “g” standard and brass “g” to npt adapters, unfortunately, cost more than flow meters.

So, a small update on this. I finally got it deployed in the wild; it’s about 60 metres from the house in a box, and working.


The numbers its kicking back seem to be excessively high. Like, when I measure by catching the water in a 20L jug and timing how long that takes, it seems to be very, very wrong. Like, my shitty jug measurement gives me about 900L/hr. The flow meter says 3,800L/hr.

Is there some sort of calibration thingy that I ought to be doing?

Annnnnd scratch that. Settled down, and now my ghetto jug measurements are within error bars of the digital. No idea what that was all about, but, it’s now working as expected. Yay!

1 Like