How to count "on" to "off" transitions

(Probably a dumb question but I just can’t seem to get anything working)
I have a gas meter that creates a magnetic pulse every 10L of natural gas consumed. I have created a small device with a hall effect detector that measures the magnetic field strength and so tells me when the magnet goes past. I’m using ESPHome ADC code to measure the reading from the detector:

sensor:
  - platform: adc
    pin: GPIO1
    name: "Gas Meter Reading"
    update_interval: 1s
    raw: True
    id: "gas_meter_reading"
    attenuation: 11db

I can see the 'Gas Meter Reading" value in HA.
I’ve also created a Threshold sensor that tells me when the reading indicates that the magnet is close by (I’d show the YAML code but the only way to get it to work was by creating a ‘helper’ and I don’t know how to get the YAML code for one of those.)
I typically see a value from the ADC of over 3200 when the magnet is away and around 2900 when it is near.
The Threshold ‘Lower’ limit is 3100 with a hysteresis value of 100.
Again I can see the state of this binary sensor going on and off correctly.
What I want to do is to count the “on” to “off” transitions (as this will tell me that another 10L has gone through). I’ve tried a history_stats sensor and I can see the counts:

  - platform: history_stats
    entity_id: binary_sensor.gas_meter_pulse
    name: "Gas Daily Counts"
    unique_id: gas_daily_counts
    state: "On"
    type: time
#    start: "{{ now().replace(hour=0, minute=0, second=0, microsecond=0) }}"
    end: "{{ now().replace(microsecond=0) }}"
    duration:
      hours: 24

So, what is the “correct” way to get this count?
(Once I have the count then I can do the manipulations to convert the volume to MJ and then to a utility_meter integration for the daily usage to eventually feed into the energy usage for the house.)
Susan

I’d do most of this in ESPHome with a hardware hack.

Create an ESPHome GPIO output pin. Physically short a pulse counter input to your gpio output.

Create an esphome threshold binary sensor that turns on/off when your ADC sensor is over/under the threshold values:

Use the binary sensor on press and on release triggers to turn on /off your GPIO output so it follows the threshold sensor state.

Create a pulse meter, which will be physically fed by your GPIO output

Example esphome config:

binary_sensor:

  - platform: analog_threshold
    id: a2d_gas_pulse
    sensor_id: gas_meter_reading # ADC input
    threshold:
      upper: 3200
      lower: 2900
    on_press:
      then:
        - output.turn_off: gpio_out
    on_release:
      then:
        - output.turn_on: gpio_out

output:
  - platform: gpio
    pin: GPIO17  # shorted to GPIO16 (counter)
    id: gpio_out

sensor:
  - platform: adc
    pin: GPIO34 # CHANGED: if this is an ESP32 GPIO1 is not an ADC input.
    name: "Gas Meter Reading"
    update_interval: 1s
    raw: True
    id: "gas_meter_reading"
    attenuation: 11db

  - platform: pulse_counter
    pin: GPIO16  # shorted to GPIO17 (gpio output)
    unit_of_measurement: 'm³'  # gas device class does not support Litres
    name: 'Gas Meter'
    device_class: gas
    filters:
      - multiply: 0.01  # (1 pulse per 10L = 0.01m³)

Use utility meter helpers in Home Assistant for your hourly /daily / monthly / yearly totals.

Thanks for the suggestion Tom. I’ll look into those ESPHome components.
I should be able to put in a jumper on the PCB to make the connection as you suggest.
I must admit that my first attempt was to make my own ESPHome component using the Arduino ADC driver and perform my own hysteresis and pulse counting but I got an error that said teh “driver/ADC.h” file was not available and I didn’t investigate further.
BTW the MCU is an Seeed Studio Xiao ESP32S3 which does have GPIO1 as an ADC input. As I said, this part is working nicely.
Susan

Ok, then you will have to adjust the other GPIOs I used too . e.g. use GPIO5 & 6 instead of 16 and 17.

@tom_l - I took your suggestion but with a small twist: instead of having the threshold sensor change a GPIO port that the pulse_counter read, I created my own clone of the pulse_counter that read from another sensor (in this case the analog_threshold sensor).
All works nicely.
Thanks for setting me on the right direction.
Susan

1 Like