DEV Community

Cover image for Watering System ๐Ÿ’ฆ with web interface on Raspberry Pi
BorisKlco
BorisKlco

Posted on

Watering System ๐Ÿ’ฆ with web interface on Raspberry Pi

Alright, alright I know what you thinking... Oh jeepers ๐Ÿ˜ฃ yet another raspberry watering tutorial with 4 lines of while loop... But hA! I will do it differently! I will make it "harder" on purpose! ๐Ÿ˜…

What about ๐Ÿค” somehow nice box, cam module for creating time lapse video AND web interface?

If you rlly want, something like this can be amazing project for learning basic electronics. Running linux on own HW, even learn little bit of soldering!

In this article I will describe my thought process, links and articles that helped me understand what is and how to use GPIO pins...


Table of Contents

  1. Schematic and thought process
  2. Code review
  3. Images, web site, github
  4. Component breakdown

Schematic and thought process

My idea was do something "fancy" but not too much, main reason was that I dont have any experiences with custom design like 3D printed casing.

MacGyver time! I chose an old box from my GPU as a case, and used the internal anti-shock foam to hold the components in place.

Final product just unwraped itself! Only thing I did before setting it into case was inform myself about GPIO pins and what and how I need to connect tham.
For this I chose to use online graphic tool Excalidraw...
And after few rectangles, lines and dream later I have basic schematic for my watering system...

Watering System Schematic


Code review

Path of least resistance

best choice for Raspberry Pi is Python... Quick, simple, and many things like GPIO, Cam driver is build for us. Bonus? do web interface in Flask. Do you need some fetching? Do htmx! You dont even need htmx... Flask will do everything for you... Building this with something like next.js is just... overkill.. But you do you ๐Ÿ˜…

Main reason why I split watering code and flask code is that I wanna run frontend on my VPS.
After watering, Pi will send data about it, as time, photo taken to my VPS.

VPS will resize photo, create new time lapse video, add record into db and serve all of it in frontend...

Let's write controller class for somehow manageable GPIO control..

controller.py

First we define how we wanna let our code know what GPIO pin we want to control.
We have 2 options, GPIO.BCM, GPIO.BOARD, difference is, BCM refers to literal name of pin, and BOARD is physical location on board.

ALL ABOUT PINS, and info for every pin can be found on https://pinout.xyz/

# GPIO/BCM Number
GPIO.setmode(GPIO.BCM)

# Physical/Board pin
# GPIO.setmode(GPIO.BOARD)
Enter fullscreen mode Exit fullscreen mode

  • GPIO(General-purpose input/output) have 2 modes.. Input and Output.
  • after setting up how we wanna refer to our pin. We need pick what pin we wanna use and what mod will be used.

For more info how relay works, pleas read end of article Component breakdown

Relay class:

  • We will not read data from relay, we want control relay by sending low/high state of pin.
  • init will setup pin to GPIO.OUT
  • we will control On/Off state of relay by sending GPIO.output()
  • to power on relay we need send GPIO.LOW/0/False
  • to power on relay we need send GPIO.HIGH/1/True

Why Low to On and High to Off? Again, pleas refer to Component breakdown

class Relay:
    def __init__(self, pin):
        self.pin = pin

    def init(self, name):
        GPIO.setup(self.pin, GPIO.OUT)
        print(f"{name} - GPIO.OUT - pin {self.pin} - init...")

    def on(self):
        GPIO.output(self.pin, GPIO.LOW)

    def off(self):
        GPIO.output(self.pin, GPIO.HIGH)
Enter fullscreen mode Exit fullscreen mode

Sensor class:

  • After powering on Relay what control voltage to Sensor, we want to read data from it.
  • Now we setup init class as GPIO.IN
  • We will read data from it just by calling GPIO.input(pin)
class Sensor:
    def __init__(self, pin):
        self.pin = pin

    def init(self, name):
        GPIO.setup(self.pin, GPIO.IN)
        print(f"{name} - GPIO.IN - pin {self.pin} - init...")

    def output(self):
        return GPIO.input(self.pin)
Enter fullscreen mode Exit fullscreen mode

Setting up app.py to run code

  • We import controller
  • We define 2 relays and reading for sensor data
from controller import Relay, Sensor

sensor_data = Sensor(22)
pump = Relay(23)
sensor = Relay(24)
Enter fullscreen mode Exit fullscreen mode

Now create few functions to make while loop clean

  • init() to set up modes for devices
  • sensor_output() , Turn on relay to power up sensor --> Make reading --> Turn off relay --> return reading(True or False)
  • water(sec=5), Turn on relay to power up pump --> sleep for x sec while pump is going --> Turn off relay
def init():
    sensor_data.init("Sensor output data")
    pump.init("Pump Relay")
    sensor.init("Sensor Relay")


def sensor_output():
    sensor.on()
    time.sleep(2)
    reading = sensor_data.output()
    time.sleep(1)
    sensor.off()
    return reading


def water(sec=5):
    pump.on()
    time.sleep(sec)
    pump.off()
Enter fullscreen mode Exit fullscreen mode

While loop

  • call init() so we can control relay and sensor
  • create infinity while True: loop, we dont need to run code every sec,min or hour... Set up SLEEP_INTERVAL for something like 24h,48h.
  • to play it safe we can add GPIO.cleanup() to finally block to clear pins.
try:
    init()

    while True:
        time.sleep(SLEEP_INTERVAL)
        dry_soil = sensor_output()
        if dry_soil :
            print("WATERING!!!")
            water()

finally:
    print("\n-- END -- \ncleaning GPIO channels...")
    GPIO.cleanup()
Enter fullscreen mode Exit fullscreen mode

Images, web site, github

Web interface have temporary images while I gather more data to put there...

Website: https://pi.tricksofthe.trade/
Github: https://github.com/BorisKlco/pi.watering-system

Image of case
Image of case


Component breakdown

Here, I will list all components and aliexpress listing for it.

5v Relay 2 channel

Best video about relay what you can watch is from Brad Henson! Depends on you, what type of relay you will buy, but in my case I have Relay One in his video

In very short explanation, we will use voltage from Pi, 5v -> VCC to power relay and activating it. This is why we have jumper connecting VCC and JD-VCC.

Relay voltage, activation schematic - Brad Henson

This is reason why we have define ON state in our code as Low State or GPIO.LOW, when we set INC pin to Low, we have 0 volts potential on that pin. This will create ground option for our VCC and turn on LED and activate relay.

WARNING!!! - DON'T SWAP VCC and INC PINS ON PI TO USE HIGH STATE AS ON STATE... CAN DMG YOUR PI IF RELAY WILL NOT USE EXTERNAL POWER SOURCE...

    def on(self):
        GPIO.output(self.pin, GPIO.LOW)

    def off(self):
        GPIO.output(self.pin, GPIO.HIGH)
Enter fullscreen mode Exit fullscreen mode

Humidity Sensor

As with everything else you can buy several types of humidity sensor.

Andreas Spiess 10 min video explaining different type of sensors and how they works

Quick overview:

  • Two-legged sensor with controller PCB: Output is digital and analog but will be quicky destroyed after uninterrupted connection of power source...
    Two-legged sensor with controller PCB - Andreas Spiess

  • Capacitive, unexposed copper sensor: Legs can't be dissolved in water, no exposed cooper. 555 timer creates a square wave for one leg, another leg of sensor is Ground, after sensor is submerged into water, two legs will create capacitator... fuucking genius!
    Capacitive, unexposed copper sensor - Andreas Spiess

Best possible choice what you can do is buy Capacitive Soil Sensor, but be careful! Quality of sensor in this case matters.

For this part I can advice you to watch video from Flaura - Smart Plant Pot , amazing overview of Capacitive Sensor and what can go wrong. Link to video

Quick overview:

Check if 555 timer and 662k voltage regulator is present.
Capacitive Soil Moisture Sensors - Flaura - Smart Plant Pot
Check if hole is between resistors and not under.
Capacitive Soil Moisture Sensors - Flaura - Smart Plant Pot


Pump

Any 3v,5v pump ๐Ÿ’ช will do...


Cam

Buy Pi supported cam, you can even experiment with new python lib PiCamera2.


Tubes

Check Pump output width, from there you can pick "perfect" tubes for that...


Cables

1P-female to female will do...


Thank you for reading โ™ฅ My next project will be watering system but on STM32 ๐Ÿ˜ฎ

Top comments (0)