Go to file
David Doblas Jiménez d546d5fb3c Update 'testing.py' 2023-08-05 19:05:36 +02:00
figures Add odp file 2022-09-24 11:35:57 +02:00
README.md Add second sensor instructions and ToDo list 2022-06-27 18:49:24 +02:00
testing.py Update 'testing.py' 2023-08-05 19:05:36 +02:00
water_plants.py Initial commit 2022-06-25 12:31:14 +02:00

README.md

Watering Plants using a Raspberry Pi

As this year, crossing fingers, we're planning for a great trip, my wife started to worry about her plants. She has put some effort in keeping them in good shape, so leaving them unattented for several weeks would probably end up in a disaster.

In order to make her happy, I decided to make an automatic watering system using a Raspberry, and some moisture sensors.

List of items needed for the project

  • Raspberry Pi -> any model would work, but for convenience we would choose one with WiFi
  • Breadboard -> a small solderless 400 points one
  • MCP3008 ADC -> as we're using analog moisture sensors
  • Capacitive soil moisture sensors -> the resistive ones would corrode over time
  • 5V Relay module -> one channel per pump is needed
  • 3V-6V Submersible water pump ->
  • Power supply -> we're using an old AC adapter (12 V, 2 A) that we already had with a female DC adapter
  • Fish tank tube -> Several meters, depending on your plants layout, 4 mm diameter transparent tube

A schematic of how all parts are connected is below:

How the system is connected

Moisture sensor

As the capacitive sensors are not digital, we'll need to transform their analog readout to a digital one, as the GPIO pins on the Raspberry Pi only support digital inputs (distribution of GPIO pins in the raspberry is explained here).

In order to convert digital signals into analog ones, we'll need and ADC, analog-to-digital converter. MCP3008 is a cheap solution for this problem.

This chip is placed into a breadboard (assuming you know how a breadboard works) to facilitate the input/output of other components. Carefull must be taken positioning the chip, remembering its orientation (chip's pins diagram can be found here).

Once the chip is hooked up into the breadboard, we'll proceed to connect it to the GPIO pins in the raspberry:

  • VDD pin is connected to the power rail on the breadboard
  • VREF pin is also connected to the power rail on the breadboard
  • AGND pin is connected to the ground rail on the breadboard
  • CLK pin is connected to GPIO11 (pin #23, a.k.a SPIO SCLK) on the raspberry pi
  • DOUT pin is connected to GPIO9 (pin #21, a.k.a SPIO MISO) on the raspberry pi
  • DIN pin is connected to GPIO10 (pin #19, a.k.a SPIO MOSI) on the raspberry pi
  • CS pin is connected to GPIO5 (pin #29) on the raspberry pi. You could choose any other GPIO pin that has no other function, e.g., GPIO 6, GPIO 17, GPIO27, ...
  • DGND pin is connected to the ground rail on the breadboard

Still, there is no connection between the chip and raspberry. In order to do so, one has to connected both, power and ground grails to the raspberry pi:

  • Ground rail can be connected to any of the ground pins on the raspberry pi. In our scheme, we chose pin #34
  • Power rail can be connected to any of the 3v3 power pins on the raspberry pi. In our scheme, we chose pin #17

With all those steps done, now it's time to hook up the moisture sensor into the breadboard. The three outputs of the sensor need to be connected as follow (jumper cables are used for convenience here):

  • The black cable (ground) is connected to the ground rail on the breadboard
  • The red cable (VCC) is connected to the power rail on the breadboard
  • The yellow cable (signal) is connected to any of the MCP3008 chip channel inputs. In our scheme, we chose channel #5 for no particular reason

That's it for the moisture sensor!

Relay and water pump

If we want to water the plants according to the signal readout by the moisture sensor, we'll need a mechanism that allows a water pump to start and stop watering. This is what a relay allow us to do.

The relay is connected directly to the raspberry pi as follows:

  • JDVCC pin can be connected to any 5V power pins on the raspberry pi. In our scheme, we chose pin #2
  • VCC pin can be connected to any 3v3 power pins on the raspberry pi. In our scheme, we chose pin #1
  • Ground pin can be connected to any ground pins on the raspberry pi. In our scheme, we chose pin #39
  • In1 pin can be connected to any GPIO pin on the raspberry pi. In our scheme, we chose GPIO21 (pin #40)

The relay could be tested and you should hear a "click" sound everytime the circuit opens/closes (every second if you use the script test_relay_on_off below).

Once tested, you can attach the water pump to the relay. This step is fairly straighforward (see picture above):

  • The red cable (power) from the pump is connected to the rightmost input of the relay
  • The black cable (ground) from the pump is connected to the negative input of the female DC adapter (which is connected to the power supply)
    • The positive input of the female DC adapter is connected to the central input of the relay, closing the circuit

At this point, everytime the relay closes the circuit, apart from the "click" sound, the water pump will start to pump some water until the circuit opens :)

Testing the moisture sensor

Notice that we're using GPIO5 in the board when creating the cs object and channel #5 on the MCP chip when creating the analog_ic object, respectively:

Note: The MCP3008 allows up to 8 different sensors in its 8 different channels. One only has to create:

  • another digitalio.DigitalInOut object using the same pin on the raspberry pi (GPIO5 in our case)
  • another MCP.MCP3008 object using the new DigitalInOut
  • another AnalogIn object with the correspondig MCP channel.

import adafruit_mcp3xxx.mcp3008 as MCP
import board
import busio
import digitalio
from adafruit_mcp3xxx.analog_in import AnalogIn


def test_sensor_in_out_water():
    # create the spi bus
    spi = busio.SPI(clock=board.SCK, MISO=board.MISO, MOSI=board.MOSI)
    # create the chip select
    cs = digitalio.DigitalInOut(board.D5)
    #cs_2 = digitalio.DigitalInOut(board.D5)
    # create the mcp object
    mcp = MCP.MCP3008(spi, cs)
    # mcp_2 = MCP.MCP3008(spi, cs_2)
    # create an analog input channel on pin 5
    analog_ic = AnalogIn(mcp, MCP.P5)
    # analog_ic_2 = AnalogIn(mcp_2, MCP.P6) 
    try:
        while True:
            print(f"ADC Voltage value: {analog_ic.voltage:.3f}")
            time.sleep(.5)
    except KeyboardInterrupt:
        return

By running this function, we're getting the following values:

  • Air: 2.153 V
  • Water: 0.677 V

Testing the water pump

import RPi.GPIO as gp
import time


def test_relay_on_off(rly=None):
    # use GPIO numbering
    gp.setmode(gp.BCM)
    gp.setup(rly, gp.OUT)
    gp.output(rly, gp.HIGH)
    try:
        while True:
            gp.output(rly, gp.LOW)
            print("Relay 1 ON")
            time.sleep(1)
            gp.output(rly, gp.HIGH)
            print("Relay 1 OFF")
            time.sleep(1)
    except KeyboardInterrupt:
        gp.cleanup()

To-Do

[] Integrate Telegram bot to allow water-on-demand

[] Monitor moisture levels in Grafana