How to measure Integration of rain pulse counter into daily value

It is a calculated value of the rainfall in mm for every pulse that is counted. It is calculated by measuring the area the rain is collected, and by testing with 200ml water how many counts there were. It seems a valid value for my sensor, but Im not sure yours would have the same dimensions.

area: 4,9 x 110mm,
200ml -> 101 pulses.
1mm rainfall = 5,39 ml.
1ml = 0,1855 mm.
1 pulse = 1,98 ml.
1 pulse = 0,367 mm rain.

Thx @gdschut for your reply. I have exactly the same rain gauge bought from the same Aliexpress seller. I wired it pretty much the same as you, one wire to GPIO14 (D5) other to GND. The only difference is about pin number
When I pour out 200ml of water into the bucket it counts as 187-192 pulses. Much more than yours. I think it is overcounting pulses. If I trigger shoulders manually it count as more than one pulse.

[21:55:58][D][pulse_counter:159]: 'Rainfall': Retrieved counter: 187.00 pulses/min
[21:55:58][D][sensor:092]: 'Rainfall': Sending state 68.62901 mm with 2 decimals of accuracy

Do you have any idea how to debounce readings?

You can use delayed_on and/or delayed_off to debounce the input.

Thanks @tom_l
I got it working and seems the correct number of On values are counted
How to count the ONs and publish as number of pulses (counts) per minute?

After an update of the esphome platform and an update of the rain sensor code I noticed several false positive pulses counted.
I did some experiments and the below code might not be optimized, at least it seams to deliver good values :slight_smile:

I also tried to debounse the pulse counter, but could not get it working.

Mind the use of D6 as binary sensor, D7 as switch and D8 as pulse counter, where D7 and D8 are connected with a wire. D6 has the connection with the actual rainsensor (switching to ground).

binary_sensor:
  - platform: gpio
    pin:
      number: D6
      inverted: True
      mode: INPUT_PULLUP 
    name: "${friendly_name} Rainfall Pulse"
    filters:
      - delayed_off: 10ms
    on_press:
      then:
        - switch.turn_on: tmp_switch
        - delay: 1s
        - switch.turn_off: tmp_switch

sensor:
  - platform: pulse_counter
    pin:
      number: D8
    unit_of_measurement: 'mm'
    name: "${friendly_name} Rainfall"
    filters:
# opp:4,9x110mm, 200ml -> 101 pulses. 1mm rainfall = 5,39 ml. 1ml = 0,1855 mm. 1 pulse = 1,98 ml. 1 pulse = 0,367 mm rainfall.  
      - multiply: 0.367

switch:
  - platform: gpio
    pin: D7
    name: "${friendly_name} tmp_switch"
    id: tmp_switch

Hi everyone!

My first home assistant post here! :slight_smile: I had the same issue, but I did some tests to check how the filter works. I think the problem is that you are counting pulses using the rising edge, and in the pulse_counter documentation it says clearly it has to be on falling edge:

internal_filter ( Optional , Time): If a pulse shorter than this time is detected, it’s discarded and no pulse is counted. Defaults to 13us . On the ESP32, this value can not be higher than 13us , for the ESP8266 you can use larger intervals too. If you enable this, set up the count_mode to increase on the falling edge, not leading edge. For S0 pulse meters that are used to meter power consumption 50-100 ms is a reasonable value.

So, I wrote a simple code to count values:

sensor:
  - platform: pulse_counter
    name: "rain_gauge"
    pin:
      number: D5
      mode: INPUT_PULLUP    
    update_interval: 1s
    count_mode:
      rising_edge: DISABLE
      falling_edge: INCREMENT
    internal_filter: 13us
    filters:
      - multiply: 0.0166666666666666666667

In this way, it’s shown the pulse count per second, every second. Then, using the function generator of my Picoscope, I generated a signal simulating some bouncings:

It’s counting 4, which is correct, since I have the filter to 13us and my shortest pulse is 17us long. Then I changed the filter time to 10ms, and now it’s counting 1 even if I send 2 pulses together. (Sorry, I uploaded more oscilloscope captures, but it’s telling me I can’t upload more than 1 image because I’m a new user… :man_facepalming:)

The limit where it counts 2 pulses is when I split the pulses about 12ms.

So, my final code is as follows:

sensor:
  - platform: pulse_counter
    name: "rain_gauge"
    pin:
      number: D5
      mode: INPUT_PULLUP    
    update_interval: 60s
    count_mode:
      rising_edge: DISABLE
      falling_edge: INCREMENT
    internal_filter: 10ms
    unit_of_measurement: "mm"
    icon: "mdi:water"
    filters:
      - multiply: 0.359254458

I guess it would be nice if there was some option to prevent sending data if it counts zero, I think it’s not much useful to fill the database with zeros.

Hope to help!

2 Likes

Nice post @gdschut , i used the code from @bernat.albet and so far so good, but how do you all work with deep_sleep? after around 30 secs and pushing all other sensor data, my wemos is going to deep_sleep. It seems because of that not always rain is passed, because it is not counted while it was online.

my output is giving this:

[12:01:14][D][pulse_counter:159]: 'SolarWeatherStation Rain': Retrieved counter: 30.00 pulses/min
[12:01:14][D][sensor:092]: 'SolarWeatherStation Rain': Sending state 10.77763 mm with 2 decimals of accuracy

Is this correct? because i only flipped the Rain sensor just once! now it is giving 30 pulses? 10 mm ?

Sorry, I cannot help you with deepsleep issues. I use NodeMCU and it is never going to sleep.

no problem. How about the measuring?
Perhaps i don’t understand the calculations, but my output is something around the 120-190 pulses/min with the rain sensor and around 50-80 mm sending to Home assistant. But , really? 50-80 mm? if i read the local weather authority they talk most of the times about 0,5 - 3 mm ?

or does the 'update_interval: 2s ’ which i have now need to be at 60 sec?

The calculation depend on the type of sensor, you should calibrate it yourself if you have another type of sensor. The update interval should be the times HA is updated about the value.
To be honest I changed the whole setup to be more independant from network troubles. I do pulse counting and storing on the ESP side, and update an HA sensor from the ESP In HA I calculate Daily Rain. My esp yaml:

substitutions:
  name: weathersensor
  friendly_name: Weathersensor

esphome:
  name: ${name}
  platform: ESP8266
  board: nodemcuv2

wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password

# Enable logging
logger:

# Enable Home Assistant API
api:

ota:

i2c:
   - id: bus_a
     sda: D2
     scl: D1
     scan: True

# D3, D4, D8 are OUTPUT ONLY
dallas:
  - pin: D6

time:
  - platform: homeassistant
    id: homeassistant_time
    on_time:
      - seconds: 0
        minutes: 0
        hours: 0
        then:
           - homeassistant.service:
               service: input_number.set_value
               data:
                 entity_id: input_number.rain_pulse_count
                 value: !lambda return id(pulse_count_int);
           - lambda: |-
               id(pulse_count_int) = 0;

interval:
  - interval: 1min
    then:
      - homeassistant.service:
          service: input_number.set_value
          data:
            entity_id: input_number.rain_pulse_count
            value: !lambda return id(pulse_count_int);
      - logger.log:
          format: "The global var pulse_count_int has value %d "         
          args: [ 'id(pulse_count_int)']

globals:
   - id: pulse_count_int
     type: int
     restore_value: yes
     initial_value: '0'

binary_sensor:
  - platform: gpio
    pin: D5
    name: "${friendly_name} rain sensor"
    filters:
      - delayed_off: 100ms
    on_press:
      then:
        - lambda: |-
            id(pulse_count_int) += 1;
        - homeassistant.service:
            service: input_number.set_value
            data:
              entity_id: input_number.rain_pulse_count
              value: !lambda return id(pulse_count_int);

sensor:
  - platform: bmp280
    temperature:
      name: "${friendly_name} BMP280 Temperature"
      oversampling: 16x
    pressure:
      name: "${friendly_name} BMP280 Pressure"
    address: 0x76
    update_interval: 60s
    i2c_id: bus_a


  - platform: adc
    pin: A0
    name: "${friendly_name} Illuminance"
    unit_of_measurement: lx
    filters:
      - lambda: |-
          return (x / 10000.0) * 2000000.0;


  - platform: dallas
    address: 0x390115906EAEFF28
    name: "${friendly_name} Temperature" 


  - platform: wifi_signal
    name: "${friendly_name} WiFi Signal Strength"
    update_interval: 60s

  - platform: uptime
    name: "${friendly_name} Uptime Sensor"


text_sensor:
  - platform: version
    name: ${friendly_name} ESPHome Version

switch:
  - platform: restart
    name: "${friendly_name} Restart"
    icon: "mdi:restart"

  - platform: gpio
    name: "${friendly_name} Relay"
    pin: D4


My HA sensor for Daily Rain:

- platform: template
  sensors:
    daily_rain:
      friendly_name: "Daily Rain"
      value_template: '{{(states.input_number.rain_pulse_count.state | float * 0.367) | round(1) }}'
      unit_of_measurement: "mm"
      icon_template: mdi:weather-pouring

This gives me good values, comparable to the weatherforecast, and it has no issues with instable network.

Thanks for answering. I have the same sensor as you had from AliExpress. How do you compare an output as 60-80 mm to the real weather data like 1-3mm?

I did by calculating the top area of the sensor.
Than I measured 200ml of water and dripped it slowly into the sensor, counting the wips of the sensor.
area: 49mm x 110mm,
200ml → 101 pulses.
1mm rainfall = 5,39 ml.
1ml = 0,1855 mm.
1 pulse = 1,98 ml.
1 pulse = 0,367 mm rain.
:slight_smile:

I understand but would assume when I just make 1 flip so 1 pulse it should calculate 0,367mm isn’t ?

Correct! At least for my sensor it is.

why are you using delayed_off as 100ms?
on my sensor (identical with yours) flips are much faster than 100ms so if I keep this number, it discards a lot of transitions (pulses).

For now I removed completely the delayed_off and it seems to count all pulses (I also have a pull-up between D5 and 3.3v)

It works different, read about it here: Binary Sensor Component — ESPHome
I never experienced missed pulses, but very rare I have false positives, but I still do not know what caused that.

What do you mean it works differently?
Line stays on ON. When a pulse occurs, it goes to OFF for the duration of the pulse, then back to ON.
So delayed_off simply requires the OFF to stay for 100ms in this case. Meaning that the pulse must be at least 100ms long, otherwise is completely discarded…
And I am seeing much shorter “off” pulses - probably 3 or 10 times faster…

From documentation: “Or in other words: Only send an OFF value if the binary sensor has stayed OFF for at least the specified time period”

Hi Gerben,
I’m a newbie in Home Assistant. Im trying to migrate from Domoticz)
My pair of espeasy and Domoticz worked flawless for years. I found your setup for the rain gauge. Unfortunately, i have not any date. I’m sure that i’m doing something wrong. Therefore pls, sorry for silly questions)

I have created the country via Helpers, however it looks like the HASS doesn’t see it:
What I find in the log:

Unable to find referenced entities input_number.rain_pulse_count

Do you know where should I dig?

I use normally off, and the pulse is on.

Hi, no problem, and welcome to Home Assistant!
I think I would first check under developer tools if the entity really exist. Perhaps a typo in the name?
Than check in configuration, integrations if your esp has connection with HA.
With ESPhome you can monitor your esp with “log” from command line or HA user interface if you use ESPHome addon.
Hope this helps! good luck!