Capacitive Soil Moisture Sensor V2.0

Basic tutorial of how to setup a Capacitive Soil Moisture Sensor with the Raspberry Pi via an ADS1115 ADC.

PREREQUISITE: https://www.piddlerintheroot.com/analog-to-digital-converter/

CALIBRATION EQUIPMENT:

Small cup of water

CALIBRATION PROCESS:

1. Place soil sensor on dry surface

2. Run cap_calibration script, enter ‘y’ on first prompt

3. Place soil sensor in small cup of water

4. Enter ‘y’ on second prompt

5. Verify cap_config.json text file was successfully generated

CODE:

cap_calibration.py

import time
import json
import board
import busio
import adafruit_ads1x15.ads1015 as ADS
from adafruit_ads1x15.analog_in import AnalogIn

max_val = None
min_val = None

# Create the I2C bus
i2c = busio.I2C(board.SCL, board.SDA)

# Create the ADC object using the I2C bus
ads = ADS.ADS1015(i2c)

# Create single-ended input on channel 0
chan = AnalogIn(ads, ADS.P0)

baseline_check = input("Is Capacitive Sensor Dry? (enter 'y' to proceed): ")
if baseline_check == 'y':
max_val = chan.value
print("------{:>5}\t{:>5}".format("raw", "v"))
for x in range(0, 10):
if chan.value > max_val:
max_val = chan.value
print("CHAN 0: "+"{:>5}\t{:>5.3f}".format(chan.value, chan.voltage))
time.sleep(0.5)

print('\n')

water_check = input("Is Capacitive Sensor in Water? (enter 'y' to proceed): ")
if water_check == 'y':
min_val = chan.value
print("------{:>5}\t{:>5}".format("raw", "v"))
for x in range(0, 10):
if chan.value < min_val:
min_val = chan.value
print("CHAN 0: "+"{:>5}\t{:>5.3f}".format(chan.value, chan.voltage))
time.sleep(0.5)

config_data = dict()
config_data["full_saturation"] = min_val
config_data["zero_saturation"] = max_val
with open('cap_config.json', 'w') as outfile:
json.dump(config_data, outfile)
print('\n')
print(config_data)
    time.sleep(0.5)

soil_saturation.py

import time
import json
import board
import busio
import adafruit_ads1x15.ads1015 as ADS
from adafruit_ads1x15.analog_in import AnalogIn

# Create the I2C bus
i2c = busio.I2C(board.SCL, board.SDA)
# Create the ADC object using the I2C bus
ads = ADS.ADS1015(i2c)
# Create single-ended input on channel 0
chan = AnalogIn(ads, ADS.P0)

with open("cap_config.json") as json_data_file:
    config_data = json.load(json_data_file)
# print(json.dumps(config_data))

def percent_translation(raw_val):
    per_val = abs((raw_val- config_data["zero_saturation"])/(config_data["full_saturation"]-config_data["zero_saturation"]))*100
    return round(per_val, 3)

if __name__ == '__main__':
    print("----------  {:>5}\t{:>5}".format("Saturation", "Voltage\n"))
    while True:
        try:
            print("SOIL SENSOR: " + "{:>5}%\t{:>5.3f}".format(percent_translation(chan.value), chan.voltage))
        except Exception as error:
            raise error
        except KeyboardInterrupt:
            print('exiting script')
        time.sleep(1)