Resistive soil moisture readings

Tags: #<Tag:0x00007fc41e47b1b8>

I’m planning on using a couple of these sensors


They are well known for their “capacity” to get corroded when constantly energized. To avoid this and extend their lifespan, some Arduino or RPi implementations use an interval reading (IE: every 20 minutes).

I’m using an ADS1115 DAC with a Wemos D1 mini to get the analog reading into HA. Like so (just reading the voltage for now):

  - platform: ads1115
    multiplexer: 'A0_GND'
    gain: 6.144
    name: "ADS1115 Channel A0-GND"

There’s an option update_interval option for the ADS1115 component:

That’s interesting, but not sure if that will make the ESP module read the analog value every x seconds, while the probe is constantly energized (which I want to avoid) or both. Assuming this will not be the case, but well, I just wanted to make sure.


I used one of these a few years ago. What you need to do as power it from an output on the ESP so you can completely turn it off when not taking samples. Simply changing the update frequency doesn’t achieve the goal.

You can then create an internal ESPhome automation to cycle the output and power the probe on for say 60 seconds every 10 minutes or whatever timeframe you choose.

When the probe has no power you will get some crazy value as the analogue reading so need to include a filter to stop that coming through to ruin your readings.

Get the capacitive sensors instead of the resistive ones. They are less prone to corrosion though the electronics needs some waterproofing: Waterproofing a Capacitance Soil Moisture Sensor : 11 Steps (with Pictures) - Instructables


Interesting workaround! But since the price of the capacitive sensor is so low, I think I’ll go with a couple of those :wink:

I think you’re right. I will avoid headaches… BTW, nice work on waterproofing! :+1: :

While I wait for the capacitive sensors (which use a different method, but output an analog signal), I’m trying to convert the voltage reading from the probe to percentages.

Tried with this code, but I get negative results :thinking:

  - platform: ads1115
    multiplexer: 'A0_GND'
    gain: 6.144
    name: "Sensor humedad bancal 1"
    update_interval: 60s 
      - calibrate_linear:
          - 0.0 -> 100
          - 5.2 -> 0

Voltage values range from 0v (100% humidity) to 5.2v (dry)


If you get a raw value higher that 5.2 volt that will result in a negative value.
So what it the raw value from the logs is a good start.


This is what I get in the logs:

[15:16:20][D][ads1115:163]: 'Sensor hum bancal 1 (v)': Got Voltage=5.346750V
[15:16:20][D][sensor:099]: 'Sensor hum bancal 1 (v)': Sending state 1.02404 V with 3 decimals of accuracy
[15:16:25][D][ads1115:163]: 'Sensor hum bancal 1 (v)': Got Voltage=5.344687V
[15:16:25][D][sensor:099]: 'Sensor hum bancal 1 (v)': Sending state 1.06370 V with 3 decimals of accuracy
[15:16:30][D][ads1115:163]: 'Sensor hum bancal 1 (v)': Got Voltage=5.347312V
[15:16:30][D][sensor:099]: 'Sensor hum bancal 1 (v)': Sending state 1.01321 V with 3 decimals of accuracy

And the ESP code for the sensor:

  - platform: ads1115
    id: moisture_sensor_1_volts
    multiplexer: 'A0_GND'
    gain: 6.144
    name: "Sensor hum bancal 1 (v)"
    unit_of_measurement: 'V'
    update_interval: 5s
     - calibrate_linear:
       - 0.2 -> 100.0 # low value means the soil is swamped
       - 5.4 -> 0.0 # high value means the soil is dry

On the UI, I’m getting values of around 1v (the value shown in the state section of the logs) :thinking:

It seems reasonable according to the linear calibration you have said.

The raw value is 5.34 and you had said to the linear calibration that 5.4 should be zero.

That means that the calculation becomes something like this

-100/5.2*(5.346750-5.4) = 1.02403846154

Which is sent out.

I used a lambda instead. Which is also possible.
It look like this.

  - platform: adc
    pin: A0
    name: "Jordfuktighet"
    update_interval: 6s
      - exponential_moving_average:
          alpha: 0.1
          send_every: 10
      - lambda: |-
          if (x > 0.8) {
            return 0;
          } else if (x < 0.36) {
            return 100;
          } else {
            return (0.8-x) / (0.8-0.36) * 100.0;

0.36 is when I put the moisture meter in very water drenched soil.
0.8 when I had my meter in the air.
I used the internal adc on my d1. Which is very noisy so I filter it .


1 Like

Not the same quality, but almost there :joy:

That unit in the bottom of the photo will not survive too long, the metal strips will corrode.

Correct. But since I bought some a few months ago, I will use them until they end up in the recycling :man_shrugging: