Pulse_meter and Pulse_counter counting too many pulses

Hi there,
i’m trying to build a pulse meter with esp32 and esphome for my water meter. I already have a solution using a shelly device connected to the pulse sensor wires through the digital input and is working kind of fine.
Some times it freeze so i wanted to replace with an ESP. But i’m having issues on multiple pulses counted. Here’s what i tried:

sensor:
  - platform: pulse_counter
    pin:
      number: GPIO16
      #allow_other_uses: true
      mode:
        input: true
        pullup: true
      inverted: true
    update_interval : 6s
    #unit_of_measurement: 'L/min'
    #filters:
    #  - multiply: 600
    name: "water pulse"
    id: water_pulse
    total:
      unit_of_measurement: 'L'
      name: 'Total liter pulse'
      id: water_meter_total_liter_pulse
      device_class: water
      state_class: total_increasing
      accuracy_decimals: 0
      filters:
        - multiply: 10
  # - platform: pulse_meter
  #   pin:
  #     number: GPIO16
  #     allow_other_uses: true
  #     mode:
  #       input: true
  #       pullup: true
  #     #inverted: true
  #   internal_filter_mode: PULSE 
  #   name: "Water Pulse Meter"
  #   unit_of_measurement: "liter/min"
  #   icon: "mdi:water"
  #   id: water_pulse_meter
  #   total:
  #     name: "Water Meter Total"
  #     unit_of_measurement: "m³"
  #     id: water_meter_total
  #     accuracy_decimals: 3
  #     device_class: water
  #     state_class: total_increasing
  #     filters:
  #       - multiply: 0.01

the pulse_meter was kind of countig each pulse 4 times while the pulse counter seemed to work just fine until the water usage become higher and it is counting somehow 2 times the real water usage:


Blu is the correctly shelly counted water usage and the yellow is the one from my esp.

Thanks!

Do you know your pulse width?
Try to play with internal_filter/mode to eliminate any bounce.

i don’t really know the pulse width. Is it a spec from the meter/sensor?
With a multimeter i read that voltage stays up for quite some time.

Then go with pulse_meter and add some longish internal_filter.

ok, so i should try some value and keep what matches the best?
I really haven’t set up anything for the shelly and i was surprised it worked well from the first time.

Yes, I can’t suggest any specific value if I don’t know the pulse width, but since you say it “stays up for some time” you probably can set some milliseconds instead of microseconds. Try 50ms
What Shelly and method you are using?

This is what works for me after adding the filter:

sensor:
  - platform: pulse_counter
    use_pcnt: false
    pin: 
      number: GPIO34
      mode: INPUT
    unit_of_measurement: 'L'
    name: 'Frischwasser Durchfluss'
    # One rotation is 1 liter, count both edges to get 0.5 liter resolution
    count_mode:
      rising_edge: INCREMENT
      falling_edge: INCREMENT
    # Sometimes the sensor keeps triggering, so we debounce the binary sensor here
    internal_filter: 1500ms
    update_interval: 30s
    filters:
      - multiply: 0.5  # (0.5L/1 pulse)

    total:
      unit_of_measurement: 'L'
      name: 'Frischwasser Zähler'
      device_class: water
      state_class: total_increasing
      accuracy_decimals: 5
      filters:
        - multiply: 0.5  # (0.5L/1 pulse)

1.5 seconds filter. Wow. I wouldn’t even call that pulse anymore… :grinning:

1 Like

I’m trying with 500ms, in my case 1 pulse = 10 liters

Try, Shelly has default 50ms afaik.

If you use pulse_counter you need to use option:
use_pcnt: false
otherwise that value is not working.

1 Like

Many thanks!!!
I’m trying again with the pulse_meter type as it seems to be the replacement to pulse_counter (which is also marked as deprecated while compiling).

Also i haven’t used use_pcnt: false previously.

If you use the pcnt hardware counter, debounce is max 13 us, likely the cause of your problem.

1 Like

It seems working on par now:

I just have one more issue right now, when the esp reboots itself the counter resets to zero. I have it connected via MQTT as home assistant is not on the same local network. How could i keep the counter?

I would expect it to retain the total. Have you set some long flash write interval on your yaml?

I have not set any custom interval.

Then it should be 1min. I’m surprised that it doesn’t save.
You could use integration sensor to save the total. With restore: true option.

ok so the integration sensor should retain the value by default on reboot?

Sure, it’s documented there. I was expecting pulse counter total having same feature…

* **restore** (*Optional*, boolean): Whether to store the intermediate result on the device so that the value can be restored upon power cycle or reboot. Warning: this option can wear out your flash. Defaults to false.

This is what it says

Yes.
You need restore: true
If you are concerned about flash wear, you can adjust the interval to something longer than 1min. 30min for example.

preferences:
  flash_write_interval: 30min
1 Like