How to count pulse frequency accurately with ESPHome?

Hi @noxx
I am also now collecting data from the gas meter using a reed switch. For some reason, my hall sensors did not pay attention to the magnet on the last drum.
Your problem reminded me of mine when the reed switch was too deeply immersed in a magnetic field. Try to determine at what value your magnet is located (for me, this is the number 3), and try to place your magnetic field sensor on the border of the magnetic field.

image

Hi
The Problem is esphome with pulse_counter or pulse_meter.
I use since some days a arduino Script and it runs perfect.

@noxx
During debugging, I placed a reed switch at the edge of the magnetic field. For counting pulses, I use pulse_counter. And it works like a charm.
image

ok, i have had no success. the arduino script works perfect. no deviations beween gas meter and home assistent.

here more:

Thanks @stevebaxter for your pulse_meter component. I have implemented it here and it worked out of the box.
I am in the process of migrating away from Domoticz to HA and when it comes to default graphs Domoticz handled this very good. My only issue with HA and pulse_meter is that each time I restart HA or the nodemcu gets restarted (config upload etc) the kwh part of the meter starts at 0.
I use an external influx/grafana server to present these readings in some nice graphs. One of my graphs show total usage pr day. This worked perfert on Domotics even across reboots of Domoticz server, but with HA and ESPhome Power_meter the daily kWh graph gets reset to 0, meaning all the previous registered kWh for that day is lost.

Is it something obvious I have missed to get the HA/ESPHome continue where it “left” after a HA and/or nodemcu reboot so I can have a consistent kWh report during the day even with some restarts fo HA or the nodemcu responsilble for the Utility readings?

Thanks again for your effort on this @stevebaxter, the values I get from your component is much more accurate and detailed than my previous reader (ESPEasy over MQTT to Domoticz).

UPDATE 11.03.2021
It was actually storing all readings. It only lost them if I did do changes to the yaml of my NodeMCUs concering entity_id. Which makes sense. I can reboot the nodemcus, HA and it will just continue where it left. I have also created a monthly, daily an hourly utility meter to keep more track and pushing those to Grafana via Influxdb. Works great. I had to keep the median filter in though as I experienced frequent spikes. Need to look more into that… With EspEasy I did not experience those spikes.

@stevebaxter In a previous post I mentioned that I didn’t have any Spikes any more, unfortunately they are popping up again. more frequently now and I found the issue. It is my coffee machine and my airfryer :thinking:

Every time I use them I get a spike. Which is weird because I am reading the watts that come from my panels with this kwh meter:

I can’t figure out why it is spiking using those applications. Dischwasher, fridge electric oven are on the same group and they don’t give spikes on that meter. Also the meter is in its own group since it is connected to the solar panels.

If some brilliant minds here might have a clue, I am all ears.

How long are these spikes? When in the process of cofefemaking / frying do they occur; exactly AT startup, or a few seconds after, of when the process is done (switching off)? It maybe some coils delivering their energy when they de-energise, which your meter is registering as (negative) power?
Also intersting to observe is that you apparently didn’t have any spikes for a while. While I can image (not condone ;)) you didn’t use your fryer for a while, I’m guessing you drank coffee?

Hi @JeeCee thanks for taking the time to respond.
I did indeed drank coffee and I just got the fryer. Thats why I realised it. So for the coffee machine it is not always giving spikes.


I’ve pointed out the spikes in the solar panels and when a lot of power was taken by a machine. The spikes have the same time in the two graphs on the second.
As you can see in the solar panel graph today there are a lot of spikes. Way more than yesterday. And nothing was changed in my setup or code. Strange. Maybe something in the air??

Hi @stevebaxter,
thanks a lot for this great work! It is working flawlessly so far for my water meter and my gas meter. Howerver I was wandering if you had an idea how to implement the following:
When installing the pulse_meter I already had a reading >0 on my actual water and gas meters. So in order to show the correct reading i added an offset to both sensors. This works fine, however I can only hardcode this offset into the esphome code. I can’t find a way to template this offset. This would be very useful when recalibrating the pulse_meter to the real meter reading every now and then by implementing the offset via an input_number from lovelace/homeassistant. Do yo see an elegant way to implement this?
Thx

@stevebaxter : first of all thanks for the sensor :slight_smile:
i want to add to the topic of spikes and incorrect readings:

i just started two days back, i did lot of testing and tweaking, and i also ended up with the similar issues:

  • in 15 hours i got 20.5 kWh usage from this sensor vs 18.5 usage from the meter
  • while checking the log i found that the sensor shows occasionally 50kWh - 60kWh spikes for second or two
  • i added a binary sensor and connected the pulse to it too to see if really that many pulses are coming through
[13:45:00][D][binary_sensor:036]: 'b_39_test': Sending state ON
[13:45:00][D][sensor:099]: 'c_36_test5': Sending state 1634.58057 W with 2 decimals of accuracy
[13:45:00][D][sensor:099]: 't_36_test5': Sending state 2.69500 kWh with 2 decimals of accuracy
[13:45:00][D][binary_sensor:036]: 'b_39_test': Sending state OFF
[13:45:02][D][binary_sensor:036]: 'b_39_test': Sending state ON
[13:45:02][D][sensor:099]: 'c_36_test5': Sending state 1585.06519 W with 2 decimals of accuracy
[13:45:03][D][sensor:099]: 't_36_test5': Sending state 2.69625 kWh with 2 decimals of accuracy
[13:45:03][D][binary_sensor:036]: 'b_39_test': Sending state OFF
...
[13:45:05][D][sensor:099]: 'c_36_test5': Sending state 59160.87415 W with 2 decimals of accuracy
[13:45:05][D][sensor:099]: 't_36_test5': Sending state 2.69750 kWh with 2 decimals of accuracy
...
[13:45:08][D][binary_sensor:036]: 'b_39_test': Sending state ON
[13:45:08][D][sensor:099]: 'c_36_test5': Sending state 1561.95764 W with 2 decimals of accuracy
[13:45:08][D][sensor:099]: 't_36_test5': Sending state 2.69875 kWh with 2 decimals of accuracy
[13:45:08][D][binary_sensor:036]: 'b_39_test': Sending state OFF

so the flow is like this: sensor HIGH (ON) → calculate → send → sensor LOW (OFF)

  • this gives correct readings

but time to time there is no reading on binary sensor but state is sent, only in these cases the calculation is wrong

  • i increased internal_filter from default 13us to current 100ms → this did not helped at all
  • i increased timeout from 1min to 2min (without success) then to current 5min and this seems to helped, at least for last 2 hours i havent seen any 50kWh spike

ill keep it running for longer to confirm but to me it seems there is some issue with timeout or i did not understood how to use it :slight_smile:

my meter is measuring the whole house consumption and should be doing at least 4-5 pulses every minute (800 pulses = 1kWh) so i thought timeout of 1min is reasonable

i hope this helps with the investigation

update with new findings:

[14:31:03][D][binary_sensor:036]: 'b_39_test': Sending state ON
[14:31:03][D][sensor:099]: 'c_36_test5': Sending state 3244.41235 W with 2 decimals of accuracy
[14:31:03][D][sensor:099]: 't_36_test5': Sending state 3.41625 kWh with 2 decimals of accuracy
[14:31:03][D][binary_sensor:036]: 'b_39_test': Sending state OFF
[14:31:05][D][binary_sensor:036]: 'b_39_test': Sending state ON
[14:31:05][D][sensor:099]: 'c_36_test5': Sending state 1520.27026 W with 2 decimals of accuracy
[14:31:06][D][sensor:099]: 't_36_test5': Sending state 3.41750 kWh with 2 decimals of accuracy
[14:31:06][D][binary_sensor:036]: 'b_39_test': Sending state OFF
[14:31:12][D][binary_sensor:036]: 'b_39_test': Sending state ON
[14:31:12][D][sensor:099]: 'c_36_test5': Sending state 722.42731 W with 2 decimals of accuracy
[14:31:12][D][sensor:099]: 't_36_test5': Sending state 3.41875 kWh with 2 decimals of accuracy
[14:31:12][D][binary_sensor:036]: 'b_39_test': Sending state OFF
[14:31:18][D][binary_sensor:036]: 'b_39_test': Sending state ON
[14:31:18][D][sensor:099]: 't_36_test5': Sending state 3.42000 kWh with 2 decimals of accuracy
=============== why only total is send? current is missing!

[14:31:18][D][binary_sensor:036]: 'b_39_test': Sending state OFF
[14:31:24][D][binary_sensor:036]: 'b_39_test': Sending state ON
[14:31:24][D][sensor:099]: 'c_36_test5': Sending state 725.80646 W with 2 decimals of accuracy
[14:31:24][D][sensor:099]: 't_36_test5': Sending state 3.42125 kWh with 2 decimals of accuracy
[14:31:24][D][binary_sensor:036]: 'b_39_test': Sending state OFF
[14:31:30][D][binary_sensor:036]: 'b_39_test': Sending state ON
[14:31:30][D][sensor:099]: 'c_36_test5': Sending state 722.19550 W with 2 decimals of accuracy
[14:31:30][D][sensor:099]: 't_36_test5': Sending state 3.42250 kWh with 2 decimals of accuracy
[14:31:30][D][binary_sensor:036]: 'b_39_test': Sending state OFF

...

[14:39:24][D][binary_sensor:036]: 'b_39_test': Sending state ON
[14:39:24][D][sensor:099]: 'c_36_test5': Sending state 1408.45068 W with 2 decimals of accuracy
[14:39:24][D][sensor:099]: 't_36_test5': Sending state 3.56625 kWh with 2 decimals of accuracy
[14:39:24][D][binary_sensor:036]: 'b_39_test': Sending state OFF
[14:39:27][D][binary_sensor:036]: 'b_39_test': Sending state ON
[14:39:27][D][sensor:099]: 'c_36_test5': Sending state 1401.86914 W with 2 decimals of accuracy
[14:39:27][D][sensor:099]: 't_36_test5': Sending state 3.56750 kWh with 2 decimals of accuracy
[14:39:27][D][binary_sensor:036]: 'b_39_test': Sending state OFF
[14:39:30][D][binary_sensor:036]: 'b_39_test': Sending state ON
[14:39:30][D][sensor:099]: 'c_36_test5': Sending state 1407.56970 W with 2 decimals of accuracy
[14:39:30][D][sensor:099]: 't_36_test5': Sending state 3.56875 kWh with 2 decimals of accuracy
[14:39:30][D][binary_sensor:036]: 'b_39_test': Sending state OFF
[14:39:34][D][pulse_meter:025]: No pulse detected for 4294s, assuming 0 pulses/min
=============== why no pulse was detected? there was pulse 4 seconds ago!

[14:39:34][D][sensor:099]: 'c_36_test5': Sending state 0.00000 W with 2 decimals of accuracy
[14:39:34][D][sensor:099]: 't_36_test5': Sending state 3.57000 kWh with 2 decimals of accuracy
=============== why is total different? looks like rounded value!

[14:39:34][D][binary_sensor:036]: 'b_39_test': Sending state ON
[14:39:34][D][binary_sensor:036]: 'b_39_test': Sending state OFF
[14:39:37][D][binary_sensor:036]: 'b_39_test': Sending state ON
[14:39:37][D][binary_sensor:036]: 'b_39_test': Sending state OFF
=============== why no sending? there were two pulses detected!

[14:39:40][D][binary_sensor:036]: 'b_39_test': Sending state ON
[14:39:40][D][sensor:099]: 't_36_test5': Sending state 3.57125 kWh with 2 decimals of accuracy
[14:39:40][D][binary_sensor:036]: 'b_39_test': Sending state OFF
[14:39:43][D][binary_sensor:036]: 'b_39_test': Sending state ON
[14:39:43][D][sensor:099]: 'c_36_test5': Sending state 1373.62634 W with 2 decimals of accuracy
[14:39:43][D][sensor:099]: 't_36_test5': Sending state 3.57250 kWh with 2 decimals of accuracy
[14:39:43][D][binary_sensor:036]: 'b_39_test': Sending state OFF
[14:39:47][D][binary_sensor:036]: 'b_39_test': Sending state ON
[14:39:47][D][sensor:099]: 'c_36_test5': Sending state 1361.57336 W with 2 decimals of accuracy
[14:39:47][D][sensor:099]: 't_36_test5': Sending state 3.57375 kWh with 2 decimals of accuracy
[14:39:47][D][binary_sensor:036]: 'b_39_test': Sending state OFF

right now i suspect that maybe the dual core CPU is causing this, im using the ESP32 which has two cores.
it might be that while loop() is running on core1 the interrupts are running on core0 and occasionally changing the values in the middle of the loop so only part of loop is executed based on logical statements

The binary sensor values might be misleading, I believe that doesn’t use interrupts and therefore may miss signals. In particular it will miss noise from the sensor, which is most likely to be your problem here.

Interesting on the ESP32 and dual core, I only have an 8266. I don’t know enough about the interrupt handling, but others might.

One simple thing to check, do you have the pull-up/down resistor set correctly for the pin you’re reading? Also, work out the longest internal_filter value you can use and still measure the expected maximum power, then use something just below this. The longer this filter can be, the more you will be protected against a noisy sensor.

See this for some info pulse_meter seems to be doubling the amount of pulses counted · Issue #2022 · esphome/issues · GitHub. It would help to post the full config as well, as well as a description of your actual sensor and how it is wired up.

i have to delete my post as i found my connection did not make much sense

here are my findings for those who are interested:

  • im using NodeMCU 32s
  • previously i used pin 39, but that is “input only” pin and it dont have any build-in resistors (thats why i have to use external one)
  • i have changed my pin to 02 and the code to use the build-in pull-down resistor (as per this link NodeMCU 32s supports also pull-down)

i added two filters:

  • internal_filter: im not sure if this one works, because some documents says that ESP32 13us is maximum
  • throttle: this one should work
sensor:
  - platform: pulse_meter
    pin:
      number: GPIO02
      mode: INPUT_PULLDOWN
    name: c_02
    unit_of_measurement: "W"
    internal_filter: 150ms
    timeout: 5 min
    filters:
      - throttle: 150ms
      - multiply: 75
    total:
      name: t_02
      unit_of_measurement: "kWh"
      accuracy_decimals: 2
      filters:
        - multiply: 0.00125

chart

the number of spikes is very low and comparing the results the offset is also very minimal so its good so far

Hello, I only found out about the meter_pulse in the changelog through an update from ESPHome.

I have been running the Pulse_counter on a nodemcu for 3 weeks, it worked quite well, my water meter has 1 pulse per liter.

I water with Hunter Hydrawise with a schedule, yesterday morning I had to water the lawn, and I have a totally unrealistic water consumption of about 5000 L in a few minutes.

Now I ask myself what I can change (would it be useful to switch to pulse_meter)?Here is my yaml:

sensor:
  - platform: pulse_counter
    pin: GPIO2
    internal_filter: 120us
    name: "Wasserverbrauch"
    update_interval : 60s
    unit_of_measurement: 'L' 

Hey at all.
I want to say thank you @stevebaxter too. Really a great tool.

@teddy have you already found a way to enter the actual counter reading and that counting does not start at 0? @stevebaxter is there a possibility there?

@Kasper027 : I solved it in hassio using a template sensor which adds the sensor value from pulse_meter and an input_number which I use to enter/correct my actual counter reading.

1 Like

I now have Esphome running on my Shelly Uni for water pressure and water usage. On the pulse meter page it says that you can use on_… to enter the actual water meter reading for addition.

Unfortunately, then my yaml is not correct. Must after on_… also something be entered?

on_...:
  then:
    - pulse_meter.set_total_pulses:
        id: pulse_meter_id
        value: 12345

Thanks for the great sensor. The update rate is awesome in comparison to the counter.
I’m experiencing something weird and did start a separate thread for my issue but this looks like the right place to be. I was wondering if anyone has experienced the Pulse Meter Sensor measuring pretty much exactly double that of the Pulse Counter Sensor. I’m using it as a power meter and the pulse counter is displaying power accurately but when I use pulse meter is reads double the power usage.

I have come up with a way to read my gas meter with a reflective photosensor to detect the white mark on an indicator wheel on the meter and so far the readings seem to very stable.

My gas charges are per Mj and the bill has additional info including ‘heating value’ and ‘pressure factor’ and I would like to convert the reading from the pulse meter sensor to Mj instead of kW.

Can someone explain the liters to kW formula in the gas meter example above so I can attempt to modify it for my usage please:

      # Convert litres (one pulse) to kWH/min using:
      #
      # 1.022640 * 39.2 / 3.6 / 1000 = 0.01113541333
      #
      # Then kWH/min to kW by multiplying by 60 = 0.66812

Gaz

I’ve been battling the same problem a few days ago.

Here is what I found out here or here, and confirmed with @stevebaxter , to be what he meant in his formula.

When you have your corrected number of pulses, you do the following:

Multiply by volume correction factor (1.022640)
Multiply by calorific value of the gas (39.3) - may be different in your country/region
Divide by kWh conversion factor (3.6)
Divide by 100 for converting from 1m3 to 0.01m3 (which is one pulse worth of gas for my meter).

If combined as discussed above, you get very close to what my provider is claiming = 11.312 KWh/m3. In my case, the difference is the slightly different calorific value of the gas.

My final sensor layout below. I am still fighting with a slight overestimation, but this is a matter of getting to the internal_filter sweetspot.
Long enough to deal with debounce and short enough to prevent loss of true counts.

sensor:
- platform: pulse_meter
  id: gas_pulse_meter
  pin:
    number: 13
    mode: INPUT_PULLUP
  internal_filter: 2s
  timeout: 30 sec
  unit_of_measurement: 'kW'
  name: 'Incoming gas power'
  device_class: power
  state_class: measurement
  accuracy_decimals: 2
  filters:
      # Convert 0.01 m³ (one pulse) to kWH/min using:
      #
      # 1.022640 * 39.2 / 3.6 / 100 = 0.1113541333
      # My conversion factor = 0.11312
      #
      # Then kWH/min to kW by multiplying by 60 = 6.7872
   - multiply: 6.7872
  total:
    name: "Gas consumption"
    unit_of_measurement: "m³"
    device_class: gas
    state_class: total_increasing
    accuracy_decimals: 2
    icon: mdi:gauge
    filters:
      - multiply: 0.01

What I don’t get is why the original formula divides by 1000 as opposed to 100.
We are going from 1m3 to 0.01m3, which is 1/100th. What am I misunderstanding here?