Rain Sensor switched power

Hello,

I think it’s great that there are forums where you can get information and learn from others. I am looking for a code that will energize my rain sensor for measurement only.

I’ve been searching for a while and haven’t really found what I’m looking for. fabir-git has realized something similar via deepsleep, but I want to keep the module powered and therefore don’t need the deepsleep way. [Rain Sensor with deepsleep]

Here is my wish:

I have a rain sensor that I would like to power and read out via an ESP8622. I have rebuilt the circuit as shown in the picture, only on an ESP8622 D1m.

(the picture is from https://diyi0t.com/rain-sensor-tutorial-for-arduino-and-esp8266/)
I would like to energize the rain sensor only when I carry out a measurement (corrosion). I have switched the power pin to D2. I read out the signal via A0 and via D1, whereby I must not look at the change of the signal here, as this changes when I switch the voltage.
I would like to take a measurement every minute or see if it is raining.

The idea is to make a warning via a voice system (e.g. Alexa) to bring in the laundry to be dried.

Here my Code without powering:

sensor:
  - platform: adc
    pin: A0
    id: Waterbox_Leak_Detection
    name: "Waterbox Leak Detection"
    update_interval: 10s
    accuracy_decimals: 1    
    unit_of_measurement: 'V'

binary_sensor:
  - platform: gpio
    name: "Regen"
    pin:
      number: D1
      inverted: true
      mode:
        input: true
        pullup: true

I would be happy if someone could help me with the code.

Thanks in advance
the Noblast

Welcome.

Looks like you want something like this?

Hi Marko_Mahko,

perfect, that’s exactly what I was looking for and it works. Now I was able to customize the code to my needs. I’m surprised that I didn’t find the article by myself, maybe it was because I was searching in German or translated it badly.

Thanks again
the Noblast

1 Like

Hello,

and now I come to the next task. I also wanted to use the digital output from the board, which is set to high at a threshold value. I have connected this to pin D1. Unfortunately, the output of the digital threshold switch changes every time the board is energized. How can I configure the digital input (D1) so that it only queries the status when it also queries the analog input and the board is energized? And does not write every change from low to high or vice versa.

# binary_sensor:
#  - platform: gpio
#    name: "Regen"
#    pin:
#      number: D1
#      inverted: true
#      mode:
#        input: true
#        pullup: true

sensor:

  - platform: wifi_signal
    name: "WiFi Signal Sensor"
    id: "Wifi_Sensor"
    update_interval: 60s
    entity_category: "diagnostic"
    
  - platform: adc
    pin: A0
    id: regensensor_geschaltet
    internal: true
    filters:
      - calibrate_linear:
          # Map 0.0 (from sensor) to 0.0 (true value)
          - 0.40 -> 100.0
          - 1.0 -> 0.0

  - platform: template
    name: "Regensensor Garten"
    id: regensensor_garten
    accuracy_decimals: 1
    unit_of_measurement: "%"
    icon: "mdi:water-percent"    



interval:
  - interval: 10s
    then:
      - output.turn_on: rs_power
      - delay: 500ms
      - component.update: regensensor_geschaltet
    
      - sensor.template.publish:
          id: regensensor_garten
          state: !lambda |-
            return id(regensensor_geschaltet).state; 
#           return id(status_regen).state;     
      - delay: 200ms
      - output.turn_off: rs_power
      
 
output:
  - platform: gpio
    pin: D2
    id: rs_power

In the code are the lines marked with #, which I wanted to read out the value. I think the option about giop could be the problem.
I only want to know the status at the time of the lambda query.

Thank you very much
the Noblast

I’m not sure how to do it that way.

But you could look at using a template binary sensor or even a analogue threshold binary sensor?

Hi Noblast,
the code snippet I posted then is quite old. I modified it since then and maybe this will come in handy for you:

output:
  - platform: gpio
    pin: D1
    id: rs_power
  - platform: esp8266_pwm
    pin: D2
    frequency: 10000 Hz
    max_power: 0.25
    id: heizung

light:
  - platform: monochromatic
    name: "Regensensor Heizung"
    output: heizung
    gamma_correct: 0
    default_transition_length: 0s
    id: heizung_light 

sensor:
  - platform: adc
    pin: A0
    id: regensensor
    internal: true
  - platform: template
    name: "Regensensor Garten"
    id: regensensor_garten
    device_class: moisture
    state_class: measurement
    accuracy_decimals: 1
    filters:
      - calibrate_linear:
          # Map 0.0 (from sensor) to 0.0 (true value)
          - 0.0 -> 0.0
          - 1.0 -> 10.0    
    unit_of_measurement: "%"
    icon: "mdi:water-percent" 
    force_update: false
  - platform: template
    id: "heizung_pwm"
    update_interval: never
    accuracy_decimals: 0
    lambda: |-
      return id(heizung_light).current_values.get_brightness();

globals:
  - id: heizungsstatus
    type: int
    restore_value: no
    initial_value: '0'



interval:
  - interval: 30s
    then:
      - if:
          condition:
            light.is_on: heizung_light
          then:
            - component.update: heizung_pwm
            - logger.log:
                format: "Aktuelle Heizleistung ist %.2f. Wird gespeichert... "
                args: [ 'id(heizung_pwm).state' ]
            - logger.log: "Heizung ist AN. Wird ausgeschaltet..." 
            - output.turn_off: heizung
            - logger.log: "Heizung ist AUS" 
            - delay: 500ms
            - logger.log: "Regensensor Power an"
            - output.turn_on: rs_power
            - delay: 500ms
            - logger.log: "Regensensor auslesen"
             - logger.log: "Regensensor Garten updaten"
            - component.update: regensensor
            - sensor.template.publish:
                id: regensensor_garten
                state: !lambda |-
                  return id(regensensor).state;      
            - delay: 200ms
            - logger.log: "Regensensor Power aus"  
            - output.turn_off: rs_power
            - delay: 200ms            
            - output.set_level: 
                id: heizung
                level: !lambda |-
                  return id(heizung_pwm).state;                
            - logger.log: "Heizung ist wieder AN"
            - logger.log:
                format: "Heizleistung von %.2f wieder hergestellt. "
                args: [ 'id(heizung_pwm).state' ]            
          else:
            - logger.log: "Heizung ist AUS. Keine Aktion erforderlich..." 
            - logger.log: "Regensensor Power an"
            - output.turn_on: rs_power
            - delay: 500ms
            - logger.log: "Regensensor auslesen"
            - logger.log: "Regensensor Garten updaten"
            - component.update: regensensor
            - sensor.template.publish:
                id: regensensor_garten
                state: !lambda |-
                  return id(regensensor).state;      
            - delay: 200ms
            - logger.log: "Regensensor Power aus"  
            - output.turn_off: rs_power


Hello Kai,

thanks for your reply, I am trying to understand the new code. It seems to be a bit more complex and you have a heater for the plate or for the housing.
What I am looking for is to query the digital input of the threshold switch at a certain point in the program.
I have it set as binary.sensor and it seems that every change is logged even the one when I switch the supply voltage for the board. I am not able to query the status at any particular time. I thought component.update was the way to go, unfortunately it doesn’t seem to work with a binary sensor.

Thank you
the Noblast
(May I switch to German)

I wouldn’t care switching to german, as this is my mother tongue, but this isn’t that popular here as it makes it hard for future visitors to follow :slight_smile:

To be honest I didn’t even read the whole thread before, but now I’ve seen the image in the start post. I’ve had the same sensor / PCB combo but dismissed the PCB right away. I’m powering the one rain sensor side (let’s say +) directly with a digital pin (D2):

output:
  - platform: gpio
    pin: D2
    id: rs_power

The other side (-) ends directly in an analog input (A0)

  - platform: adc
    pin: A0
    id: regensensor_geschaltet
    internal: true
    filters:
      - calibrate_linear:
          - 0.40 -> 100.0
          - 1.0 -> 0.0

By doing so, I can estimate “how much” it’s raining. If it’s only a few drops or fog in the morning I can filter it out later.

This leads to a more granular “rain quantity measurement”.

Like you already figured out, I have a heater glued below the Sensor PCB and I would strongly recommend doing so. The sensor is more sensitive then one might think and when I started fidddling around with it. I had false positives EVERY morning only because of acuumulating moisture, especially in the summer months.
Also when the rain stops it takes extremely long for the sensor to dry off again without heating. The professional sensor which are build this way all have a heater.

The heater is controlled via PWM (D2) over a MosFET and i chose this one, which is not intended for that use but works perfect for over 2 years now.
It was a small PET film with resitive inlays which are used in these back massage thingis that can warm up.
grafik

I 3D printed an enclosure and fill the whole assembly with epoxy to make it water tight.

I do the whole automation which comes afterwards in NodeRed. The only Information from the sensor I receive is “how much is it raining” in percent. This surely isn’t an accurate unit for rain quantity, but It’s enough to estimate if I have to run for the laundry or not :slight_smile:
As soon as there is more than “1 %” rain the heater pwm increases more and more with increasing “rain quantity”. It heats as long until the sensor shows 0% again.

I also estimate the on time for the garden sprinklers with this value. Works like a charme…

And…one last information to better understand my code…I have to switch off the heater (only if currently on) while reading the sensor value as the heater pwm creates a lot of noise in the sensor wires.

Schönen Abend noch und schöne Grüße aus dem Rheinland

c Hello Kai,

thank you very much for your explanations. And you are right, as should stay in English.
The heating thing is a good idea, I will try my hardware and software first and I am sure from your experience I will improve it too :wink:

My analog input already works and I get a value between 0.45 and 1 V out of it and convert it to a percentage value.
The digital input should have a redundant signal. The threshold switch comes directly from the board, which also outputs the analog signal. Here you can set the threshold value via a potentiometer. I am afraid that the analog value will change over time due to corrosion. I am aware that this will of course also have an influence on the threshold value, but it is always the case that having is better than needing, and of course I am also interested in finding out how to implement this.

Thank you and greetings from the North Sea coast
the Noblast

Hi Noblast,

I see that the digital input is meant to be a redundant signal, but this is some kind of falsch gedacht.
The signal source is always the resistance between the two pcb traces. At A0 of your PCB you get this raw signal (maybe amplified or attenuated) and at D0 you get the SAME signal only via a Schmit Trigger whose threshold can be adjusted with the potentiometer. So, in fact this isn’t redundant as if the sensor fails (due to corrosion or broken wire or whatever) BOTH signals, A0 and D0, will be invalid at the same time.

In other words, the PCB just converts the analog sensor value into a digital value.
This can easily be done in ESPhome like, but it won’t make much sense regarding redundancy requirements:

  - platform: template
    name: Regensensor digital
    lambda: |-
          if (id(regensensor_analog).state > 0.5) {
            return true;
          } else {
            return false;
          } 

This would in fact give the same redundancy than using the D0 output of the PCB and adjusting the potentiometer to trigger the schmitt trigger at “50%” rain.

Regarding your interest in implementing it anyway I’m not quite sure what would be the best way.
I suppose you get false positive as the D0 output is low active, meaning that the “it’s raining” state is a low signal at the D0 pin. This leads to a continous high signal as soon as the board is powered until it starts raining.
The problem here is that the signal also becomes high when the PCB gets powered (D0 = high) and becomes low again if the supply voltage is switched off (D0 = low).
So you have to only query the A0 and D1 at the same time and make sure that at this time the supply voltage is already on. That’s a little tricky, but in fact I do something similar with the sensor heater. I only query and update the sensor values if the heater is off (if it’s not off I turn it off while measuring). Maybe you can adapt the lambda in my interval section to fit your needs. You “only” have to add the digital D1 input in the same way I did for the A0 input.

The corrosion problem is not as big as you might thing. My first sensor showed very slight corrosion marks after 2 months of CONTINOUS operation. That’s why I decided to switch to the interval measurement version. I bought a new sensor, changed the code and since then the sensor works perfectly and shows absolutely no corrosion. It’s located on the roof of my garden cabin with a 30° tilt.
What I want to say is, that putting too much effort in redundancy isn’t really required here. If redundancy is crucial for you (and your laundry :wink:) I would better think of adding a second sensor assembly and compare the state of both for the final “Oh god it’s raining” signal.

Hello Kai,

thank you for being so patient. You are right about the digital signal, it is of course not redundant that it ever comes from the same source.
I just assumed that it would be easy to simply query this digital high and low channel.
Since I evaluate the values in Home assistant, it is of easy to create a helper there that turns the analog value into a switch if it’s Rains or not.

This would allow me to bypass the Lambda code :wink:

I have tried querying the digital signal at the time of energizing in the interval loop query, but unfortunately this does not come up as desired. And due to the previous configuration of the gpio input, I also get the changes that are outside of this loop.

interval:
  - interval: 10s
    then:
      - output.turn_on: rs_power
      - delay: 500ms
      - component.update: regensensor_geschaltet
    
      - sensor.template.publish:
          id: regensensor_garten
          state: !lambda |-
            return id(regensensor_geschaltet).state; 
#           return id(status_regen).state;     
      - delay: 200ms
      - output.turn_off: rs_power

So I only need to know is how to query pin D1 in this loop and hide the notifications at a change outside of this request. For example, is there a command that does this directly or do I always have to configure a sensor before?

binary_sensor:
  - platform: gpio
    name: "Regen"
    pin:
      number: D1
      inverted: true
      mode:
        input: true
        pullup: true

But I don’t want to overstress this subject either, I now have everything I need for my notification, it’s starting to rain and bring in the laundry in :wink:

Thank you
the Noblast

No problem, I have some time at work :slight_smile:
The following code is untested and may need some adjustments.
The template sensors can be extendend with

  • device_class:
  • state_class:
  • accuracy_decimals:

as you wish.

sensor:
  # this sensor is to receive the analog value from the PCB, invisible in HA
  - platform: adc 
    pin: A0
    id: regensensor_analog_input
    internal: true # can be omitted, only to clarify
  # this sensor is visible in HA and shows the analog value
  - platform: template
    name: Regensensor analog
    id: regensensor_analog_template
    force_update: false

binary_sensor:
  # this sensor is to receive the digital value from the PCB
  - platform: gpio
    pin:
      number: D1
      inverted: True
    id: regensensor_digital_input
    internal: true # can be omitted, only to clarify
    # this sensor is visible in HA and shows the digital value
  - platform: template
    name: Regensensor digital
    id: regensensor_digital_template 

output:
  - platform: gpio
    pin: D1
    id: regensensor_power
    internal: true # can be omitted, only to clarify

interval:
  - interval: 30s
    then:
            - output.turn_on: regensensor_power
            - delay: 500ms
            - logger.log: "Analogsensor updaten"
            - component.update: regensensor_analog_input
            - logger.log: "template Sensoren updaten"
            - sensor.template.publish:
                id: regensensor_analog_template
                state: !lambda |-
                  return id(regensensor_analog_input).state;
            - binary_sensor.template.publish:
                id: regensensor_digital_template
                state: !lambda |-
                  return id(regensensor_digital_input).state;
            - delay: 200ms
            - output.turn_off: regensensor_power

Btw. the mode section is not necessary as long as the input is connected to a digital output. The pullup is only needed if, for example, a switch button is connected to the input whichs pulls the input to ground if pressed.
To specify a binary_sensor as input is also not needed. So for the future, just omit these lines :wink:

Hello Kai,

I am now satisfied. The code works fine, only the output has to be set to D2 instead of D1 :wink:

Maybe I always made a mistake when reading the log.

Here the switching changes at D1 are always logged as soon as a voltage is applied. But the signal “Rain sensor digital” (without “_”) is only reported when there is a change.

It works perfectly, thanks for the support.

Thanks a lot

the Noblast

Here is an excerpt from the log file



[09:20:04][D][sensor:093]: 'WiFi Signal Sensor': Sending state -55.00000 dBm with 0 decimals of accuracy

[09:20:18][D][sensor:093]: 'regensensor_analog_input': Sending state 1.00000 V with 2 decimals of accuracy

[09:20:20][D][binary_sensor:036]: 'regensensor_digital_input': Sending state ON

[09:20:20][D][binary_sensor:036]: 'regensensor_digital_input': Sending state OFF

[09:20:21][D][main:391]: Analogsensor updaten

[09:20:21][D][sensor:093]: 'regensensor_analog_input': Sending state 1.00000 V with 2 decimals of accuracy

[09:20:21][D][main:395]: template Sensoren updaten

[09:20:21][D][sensor:093]: 'Regensensor analog': Sending state 1.00000 with 1 decimals of accuracy

[09:20:22][D][binary_sensor:036]: 'regensensor_digital_input': Sending state ON

[09:20:22][D][binary_sensor:036]: 'regensensor_digital_input': Sending state OFF

[09:20:50][D][binary_sensor:036]: 'regensensor_digital_input': Sending state ON

[09:20:50][D][binary_sensor:036]: 'regensensor_digital_input': Sending state OFF

[09:20:51][D][main:391]: Analogsensor updaten

[09:20:51][D][sensor:093]: 'regensensor_analog_input': Sending state 1.00000 V with 2 decimals of accuracy

[09:20:51][D][main:395]: template Sensoren updaten

[09:20:51][D][sensor:093]: 'Regensensor analog': Sending state 1.00000 with 1 decimals of accuracy

[09:20:52][D][binary_sensor:036]: 'regensensor_digital_input': Sending state ON

[09:20:52][D][binary_sensor:036]: 'regensensor_digital_input': Sending state OFF

[09:21:04][D][sensor:093]: 'WiFi Signal Sensor': Sending state -57.00000 dBm with 0 decimals of accuracy

[09:21:18][D][sensor:093]: 'regensensor_analog_input': Sending state 1.00000 V with 2 decimals of accuracy

[09:21:20][D][binary_sensor:036]: 'regensensor_digital_input': Sending state ON

[09:21:21][D][main:391]: Analogsensor updaten

[09:21:21][D][sensor:093]: 'regensensor_analog_input': Sending state 0.31250 V with 2 decimals of accuracy

[09:21:21][D][main:395]: template Sensoren updaten

[09:21:21][D][sensor:093]: 'Regensensor analog': Sending state 0.31250 with 1 decimals of accuracy

[09:21:21][D][binary_sensor:036]: 'Regensensor digital': Sending state ON

[09:21:22][D][binary_sensor:036]: 'regensensor_digital_input': Sending state OFF

[09:21:50][D][binary_sensor:036]: 'regensensor_digital_input': Sending state ON

[09:21:51][D][main:391]: Analogsensor updaten

[09:21:51][D][sensor:093]: 'regensensor_analog_input': Sending state 0.33203 V with 2 decimals of accuracy

[09:21:51][D][main:395]: template Sensoren updaten

[09:21:51][D][sensor:093]: 'Regensensor analog': Sending state 0.33203 with 1 decimals of accuracy

[09:21:52][D][binary_sensor:036]: 'regensensor_digital_input': Sending state OFF

[09:22:04][D][sensor:093]: 'WiFi Signal Sensor': Sending state -52.00000 dBm with 0 decimals of accuracy

[09:22:18][D][sensor:093]: 'regensensor_analog_input': Sending state 1.00000 V with 2 decimals of accuracy

[09:22:20][D][binary_sensor:036]: 'regensensor_digital_input': Sending state ON

[09:22:20][D][binary_sensor:036]: 'regensensor_digital_input': Sending state OFF

[09:22:21][D][main:391]: Analogsensor updaten

[09:22:21][D][sensor:093]: 'regensensor_analog_input': Sending state 1.00000 V with 2 decimals of accuracy

[09:22:21][D][main:395]: template Sensoren updaten

[09:22:21][D][sensor:093]: 'Regensensor analog': Sending state 1.00000 with 1 decimals of accuracy

[09:22:21][D][binary_sensor:036]: 'Regensensor digital': Sending state OFF

[09:22:22][D][binary_sensor:036]: 'regensensor_digital_input': Sending state ON

[09:22:22][D][binary_sensor:036]: 'regensensor_digital_input': Sending state OFF

I expected more like indentation errors or something :laughing:
The D1 / D2 swap was easy to catch.
I’m glad I could help.
Have a nice weekend :raising_hand_man:t3: