Smart Soil Moisture Sensor with the Pi Pico

In this tutorial we will be using the Raspberry Pi Pico, a Soil Moisture sensor and a relay. In the first part of the tutorial we will write code to get the Raspberry Pi Pico to read the value from the soil moisture sensor and depending on the reading we will decide if we need to water the plant. Within the second part of the tutorial we will program the Pi Pico, so that on pressing a button the Pi Pico will read soil moisture level from the humidity sensor and then make a decision on the need to water the plant.

About the Soil Moisture Sensor: A soil moisture sensor can read the amount of moisture present in the soil surrounding it. It’s a low tech sensor, but ideal for monitoring an urban garden, or your pet plant’s water level. This is a must have tool for a connected garden!!!! A soil moisture sensor uses the two probes to pass current through the soil, and then it reads that resistance to get the moisture level. More water makes the soil conduct electricity more easily (less resistance), while dry soil conducts electricity poorly (more resistance). A simple project with a soil moisture sensor can be helpful to remind us to water our indoor plants or to monitor the soil moisture in our garden. 

Resistive Soil Moisture Sensor

The soil moisture sensor has four pins of which we will be using three. These include –

  1. Vcc – Connected to 3.3V power supply
  2. Gnd – Connected to Ground
  3. A0 – Connected to one of the pins of the Pi Pico

Relay – A relay is a programmable electrical switch that can be used to turn devices on and off using code. A relay can be used to turn on or turn off low voltage devices, special relays with opt-isolators are used to switch high voltage devices. We will only be dealing with low voltage devices. PLEASE DO NOT use this tutorial with high voltage relays, you do so at your own peril.

Simple Low Voltage Relay

One side of the relay has three different pins i.e. GND, VCC and SIG. These are connected as follows –

  1. GND – Connected to Ground on the Pi Pico
  2. Vcc – Connected to 3V3 on the Pi Pico
  3. Sig – Connected to a digital pin so we can trigger the relay i.e. turn it on or off

The pins on the other side of the relay include –

  1. No – Normally Open
  2. NC – Normally Closed
  3. Common – Connected to Ground

Among the pins listed above we will connect Normally Open or NO to one of the terminals of the motor while the Common terminal is connected to the ground.

It’s worth nothing that certain relays are known to not work with a 3V power source. If you find yourself having issues getting the relay to turn on or off with a 3V source then you might need to replace your relay for one that works with a 3V power source. I would recommend avoiding mixing 3V and 5V devices on such a circuit.

Raspberry Pi Pico – Raspberry Pi Pico is a tiny, fast, and versatile board built using RP2040, the flagship microcontroller chip designed by Raspberry Pi in the UK. From light displays and IoT devices to signage and manufacturing processes, Raspberry Pi Pico gives the maker the power to control countless home, hobby, and industrial projects. Programmable in C and MicroPython, the Pi Pico is adaptable to a vast range of applications and skill levels, and getting started is as easy as dragging and dropping a file. More experienced users can take advantage of Raspberry Pi Pico’s rich peripheral set, including SPI, I2C, and eight Programmable I/O (PIO) state machines for custom peripheral support.

Here’s the specifications (from Raspberry Pi Foundation website) of the Raspberry Pi Pico in case you are interested –

  1. 21 mm × 51 mm form factor
  2. RP2040 microcontroller chip designed by Raspberry Pi in the UK
  3. Dual-core Arm Cortex-M0+ processor, flexible clock running up to 133 MHz
  4. 264kB on-chip SRAM
  5. 2MB on-board QSPI flash
  6. 2.4GHz 802.11n wireless LAN (Raspberry Pi Pico W and WH only)
  7. 26 multifunction GPIO pins, including 3 analogue inputs
  8. 2 × UART, 2 × SPI controllers, 2 × I2C controllers, 16 × PWM channels
  9. 1 × USB 1.1 controller and PHY, with host and device support
  10. 8 × Programmable I/O (PIO) state machines for custom peripheral support
  11. Supported input power 1.8–5.5V DC
  12. Operating temperature -20°C to +85°C (Raspberry Pi Pico and Pico H); -20°C to +70°C (Raspberry Pi Pico W and Pico WH)
  13. Castellated module allows soldering direct to carrier boards (Raspberry Pi Pico and Pico W only)
  14. Drag-and-drop programming using mass storage over USB
  15. Low-power sleep and dormant modes
  16. Accurate on-chip clock
  17. Temperature sensor
  18. Accelerated integer and floating-point libraries on-chip

Pinout diagram for the Raspberry Pi Pico – To help you work out which pins are located where and what they are called you can refer to the pinout diagram for the Raspberry Pi Pico provided below.

Raspberry Pi Pico Pinout Diagram

Bill Of Material – Here’s the Bill Of Material for this tutorial.

  1. 1 x Raspberry Pi Pico
  2. 1 x Resistive Soil Moisture sensor
  3. 20 x Male to Male Dupont cables
  4. 1 x 800 point breadboard
  5. 2 x 10K resistor
  6. 1 x Push button switch
  7. 1 x Breadboard power module
  8. 2 x LED’s
  9. 1 x Motor

Circuit Diagram – Here’s the circuit you will need to put together. .

Raspberry Pi Pico with Soil Moisture Sensor, Relay & Water Pump

The above diagram was put together in Fritzing.

Please note that the power module on the breadboard (shown above) supplies both 5V and 3V. If you have a similar power module PLEASE MAKE SURE you use the 3V power pins and not the 5V pins since that will damage the Raspberry Pi Pico.

The connections are to be made as follows –

  1. GPIO 0 of the Pi Pico connected to the Anode of the Greed LED
  2. Cathode of the Green LED connected to one leg of the 10K resistor
  3. Second leg of the 10K resistor connected to Ground
  4. GPIO 1 of the Pi Pico connected to the Anode of the Red LED
  5. Cathode of the Red LED connected to one leg of the 10K resistor
  6. Second leg of the 10K resistor connected to Ground
  7. GPIO 27 of the Pi Pico connected to the A0 of the Resistive Soil Moisuture Sensor
  8. Ground of Resistive Soil Moisuture Sensor connected to Ground on the breadboard
  9. Vcc of Resistive Soil Moisuture Sensor connected to Vcc or 3V on the breadboard
  10. One leg of the push button switch connected to GPIO 16
  11. Second leg of the push button switch connected to Vcc or 3V on the breadboard

One side of the relay has three different pins i.e. GND, VCC and SIG. These are connected as follows –

  1. GND – Connected to Ground on the Pi Pico
  2. Vcc – Connected to 3V3 on the Pi Pico
  3. Sig – Connected to a GPIO15 so we can trigger the relay i.e. turn it on or off

The pins on the other side of the relay include –

  1. No – Normally Open Connected to black lead of the motor
  2. NC – Normally Closed is not being used
  3. Common – Connected to Ground

The red lead of the motor is connected to the 3V or Vcc on the breadboard.

Code

Here’s the code for the first part of the that you’ll need to put together. You are encouraged to not just copy the code, but rather ask yourself the meaning of each of the lines of code as you type them out and use Google where you need additional support.

from machine import Pin
from time import sleep
#Setting up the LED's
red_led = Pin(0, Pin.OUT)
green_led = Pin(1, Pin.OUT)
#Setting up the relay to read input form GPIO 15
motor = Pin(15, Pin.OUT)
#Setting up soil moisture sensor on GPIO 27 for ADC
sensor = machine.ADC(27)
#Toggle LED's on and off
red_led.on()
sleep(1)
red_led.off()
sleep(1)
red_led.on()
sleep(1)
red_led.off()
sleep(1)
green_led.on()
sleep(1)
green_led.off()
sleep(1)
green_led.on()
sleep(1)
green_led.off()
sleep(1)

while True:
  
  #Reading Soil Moisture value
  soil_read = sensor.read_u16()
  min_moisture=0
  max_moisture=65535
  #converting values to a percentage
  percent_moisture=(max_moisture-soil_read)*100/(max_moisture-min_moisture)
  print("Current soil moisture level is ",percent_moisture)
  #This section will run if the moisture level is 40% or lower
  if (percent_moisture <= 40):
    red_led.on()
    sleep(1)
    red_led.off()
    sleep(1)
    red_led.on()
    sleep(1)
    red_led.off()
    sleep(1)
    runtime = 5
    #Run the motor for a short while to water the plant
    while (runtime <=5) and (runtime >= 0):
      runtime=(runtime-1)
      #print(runtime)
      sleep(1)
      motor.on()
      print("Plant is being watered.....")
    motor.off()
  #This section will run if the moisture level is greater than 40% 
  elif (percent_moisture >= 40):
    green_led.on()
    sleep(1)
    green_led.off()
    sleep(1)
    green_led.on()
    sleep(1)
    green_led.off()
    sleep(1)
  
  #sleep for 10mins
  sleep(600)

Here’s the code for the second part of the that you’ll need to put together. You are encouraged to not just copy the code, but rather ask yourself the meaning of each of the lines of code as you type them out and use Google where you need additional support.

from machine import Pin
from time import sleep
# Setting up the LED's
red_led = Pin(0, Pin.OUT)
green_led = Pin(1, Pin.OUT)
# Setting up the motor
motor = Pin(15, Pin.OUT)
# Setting up the push button
button = Pin(16, Pin.IN, Pin.PULL_DOWN)
# Setting up pint 27 for ADC
sensor = machine.ADC(27)
# Toggle LED's on and off
red_led.on()
sleep(1)
red_led.off()
sleep(1)
red_led.on()
sleep(1)
red_led.off()
sleep(1)
green_led.on()
sleep(1)
green_led.off()
sleep(1)
green_led.on()
sleep(1)
green_led.off()
sleep(1)
while True:
    if button.value() == 1:
        # Reading Soil Moisture value
        soil_read = sensor.read_u16()
        min_moisture = 0
        max_moisture = 65535
        percent_moisture = (
            (max_moisture - soil_read) * 100 / (max_moisture - min_moisture)
        )
        print("Current soil moisture level is ", percent_moisture)
        if percent_moisture <= 40:
            red_led.on()
            sleep(1)
            red_led.off()
            sleep(1)
            red_led.on()
            sleep(1)
            red_led.off()
            sleep(1)
            runtime = 5
            while (runtime <= 5) and (runtime >= 0):
                print("Plant is being watered.....")
                runtime = runtime - 1
                print(runtime)
                sleep(1)
                motor.on()
            motor.off()
            sleep(0.1)
        elif percent_moisture >= 40:
            green_led.on()
            sleep(1)
            green_led.off()
            sleep(1)
            green_led.on()
            sleep(1)
            green_led.off()
            sleep(1)
  

Summary – We hope you’ve enjoyed building a smart soil moisture sensor setup using the Raspberry Pi Pico, Resistive Soil Moisture sensor and a simple low voltage relay. In this module you learned how to wire up all of the components, write the code, upload it to the Pi Pico and test everything out. Please drop us a note at trevor at hack2 dot live if you have any questions.

Leave a Reply

Your email address will not be published. Required fields are marked *