Tomat-O-Mat

From Wurst-Wasser.net
Jump to navigation Jump to search
The printable version is no longer supported and may have rendering errors. Please update your browser bookmarks and please use the default browser print function instead.

The Idea

Since I'm too lazy[1] to water my tomatoes, I thought it would be nice if a Pi would take care of that.

How It Works

A RaspberryPi is connected to a Sony Playstation Camera, a DHT11, some level switches, a relay and a pump. TomatOMatSchematics.png

Parts list

  • RaspberryPi Rev 2
  • Power supply for the Pi
  • Power supply for the pump (12V, 2A)
  • Sony Playstation Camera
  • DHT11 (side project RaspberryPi Humidity and Temperature Sensor)
  • DS18B20 (side project RaspberryPi Temperature Sensor)
  • Lower watermark level switches like this (vertically mounted)
  • Upper watermark level switches like this (horizontally mounted)
  • Pump (bought on eBay, model DC40A-1215 (12V, 350mA, 400l/h (6l/min), 1.5m delivery head, 30.000h lifetime) like this)
  • alternatively[2]: Solenoid Valve like this
  • Relay (5V, low-triggered, 2-channel, this)
  • some resistors, cables, wires, boards, and the usual soldering equipment

Sources

00_check_and_init.sh

#!/bin/bash
#set -x

# File: 00_check_and_init.sh
# Author: Heiko Kretschmer, watering-o-matic at wurst-wasser.net
# Purpose: Checking wether the gpio are set up, and if not, setting 'em up.

# Globals
GDIRBASE="/home/pi/Development/giess-o-mat"

# UnMain
"${GDIRBASE}/"01_check_init.sh || sudo "${GDIRBASE}/"02_init.sh

# EOF

01_check_init.sh

#!/bin/bash
#set -x

# Author: tomatomat@wurst-wasser.net
# Purpose: Checking wether GPIO pins are set up

#############
# Check GPIOs
#############

if [ ! -f "/sys/class/gpio/gpio8/value" ]; then
  echo "control file for gpio8 is missing, need to call 02_init.sh!"
  exit 1
fi

if [ ! -f "/sys/class/gpio/gpio17/value" ]; then
  echo "control file for gpio17 is missing, need to call 02_init.sh!"
  exit 1
fi

#if [ ! -f "/sys/class/gpio/gpio21/value" ]; then
#   echo "control file for gpio21 is missing, need to call 02_init.sh!"
#   exit 1
#fi

if [ ! -f "/sys/class/gpio/gpio22/value" ]; then
  echo "control file for gpio22 is missing, need to call 02_init.sh!"
  exit 1
fi

if [ ! -f "/sys/class/gpio/gpio23/value" ]; then
  echo "control file for gpio23 is missing, need to call 02_init.sh!"
  exit 1
fi

if [ ! -f "/sys/class/gpio/gpio24/value" ]; then
  echo "control file for gpio24 is missing, need to call 02_init.sh!"
  exit 1
fi

if [ ! -f "/sys/class/gpio/gpio25/value" ]; then
  echo "control file for gpio25 is missing, need to call 02_init.sh!"
  exit 1
fi

exit 0

# EOF

02_init.sh

#!/bin/bash
#set -x

# File: 02_init.sh
# Author: tomatomat@wurst-wasser.net
# Purpose: Initiating GPIO pins for in-/output
# Important note: MUST be run as root at boot-time - the "device"-files disappear on reboot!

# GPIO numbers should be from this list
# 0, 1, 4, 7, 8, 9, 10, 11, 14, 15, 17, 18, 21, 22, 23, 24, 25

# Note that the GPIO numbers that you program here refer to the pins
# of the BCM2835 and *not* the numbers on the pin header. 
# So, if you want to activate Pin 07 on the header you should be 
# using GPIO4 in this script. Likewise if you want to activate Pin 11
# on the header you should be using GPIO17 here.

# Check permissions (Actually, just export as root, then set permissions for device files, done)
test "`whoami`" != "root" && echo "Must be root (or use sudo)." && exit 1

# The Pins we use, and how: (Details man gpio)
#
# GPIO 8 (Pin 24) - Input (k), reading signal upper water level measurement of reservoir
# GPIO 17 (Pin 11) - Output (c), delivering signal for the pump / solenoid valve
# GPIO 22 (Pin 15) - Input (e), reading signal for lower water level measurement of reservoir
# GPIO 23 (Pin 16) - Input (h), reading signal for upper water level measurement of flowerbed
# GPIO 24 (Pin 18) - Input (a), reading signal for lower water level measurement of flowerbed
# GPIO 25 (Pin 22) - Input (g), reading signal for middle water level measurement of reservoir

echo "Initializing GPIOs..."

#############
# Setup GPIOs
#############

# Set up GPIO 8 (Pin 24) and set to input (should read 0, if water over mark)
NR="8"
echo "${NR}" > /sys/class/gpio/export
echo "in" > /sys/class/gpio/gpio${NR}/direction

# Set up GPIO 17 (Pin 11) and set to output (Pump starts if 0)
echo 17 > /sys/class/gpio/export
echo "out" > /sys/class/gpio/gpio17/direction
chown pi /sys/class/gpio/gpio17/value

# Set up GPIO 25 (Pin 22) and set to input (should read 0, if water over mark)
NR="25"
echo "${NR}" > /sys/class/gpio/export
echo "in" > /sys/class/gpio/gpio${NR}/direction

# Set up GPIO 22 (Pin 15) and set to input (should read 0, if water over mark)
NR="22"
echo "${NR}" > /sys/class/gpio/export
echo "in" > /sys/class/gpio/gpio${NR}/direction

# Set up GPIO 23 (Pin 16) and set to input (should read 0, if water over mark)
NR="23"
echo "${NR}" > /sys/class/gpio/export
echo "in" > /sys/class/gpio/gpio${NR}/direction

# Set up GPIO 24 (Pin 18) and set to input (should read 0, if water over mark)
NR="24"
echo "${NR}" > /sys/class/gpio/export
echo "in" > /sys/class/gpio/gpio${NR}/direction

############
# Init GPIOs
############

# Set output to default (disabling pump/solenoid valve, since the relay triggers on low signal)
echo "1" > /sys/class/gpio/gpio17/value # Pin 11 -> High, Pump/solenoid valve disabled

# Clean up
#echo "17" > /sys/class/gpio/unexport
#echo "21" > /sys/class/gpio/unexport
#echo "22" > /sys/class/gpio/unexport
#echo "23" > /sys/class/gpio/unexport
#echo "24" > /sys/class/gpio/unexport

# EOF

04_check_uninit.sh

#!/bin/bash
#set -x

# Author: tomatomat:w@wurst-wasser.net
# Purpose: Checking wether GPIO pins are set up

#############
# Check GPIOs
#############

if [ ! -f "/sys/class/gpio/gpio8/value" -a ! -f "/sys/class/gpio/gpio17/value" -a ! -f "/sys/class/gpio/gpio22/value" -a ! -f "/sys/class/gpio/gpio23/value" -a ! -f "/sys/class/gpio/gpio24/value" ! -f "/sys/class/gpio/gpio25/value" -a ]; then
 exit 0 # All GPIOs are gone
fi

exit 1 # One ore more GPIOs are still there

# EOF

09_uninit.sh

#!/bin/bash
#set -x

# File: 09_uninit.sh
# Author: tomatomat at wurst-wasser.net
# Purpose: Un-Initiating GPIO pins for in-/output
# Important note: MUST be run as root!

# Globals
GDIRBASE="/home/pi/Development/giess-o-mat"

# UnMain
"${GDIRBASE}/"04_check_uninit.sh && echo "We already did uninit. Exiting." && exit 1

# Check permissions (Actually, just export as root, then set permissions for device files, done)
test "`whoami`" != "root" && echo "Must be root (or use sudo)." && exit 1

# Set output to default (disabling pump and putting safety on, since the relay triggers on low signal)
echo "1" > /sys/class/gpio/gpio17/value # Pin 11 -> High

# Clean up (Levels on GPIO output pins remain unchanged)
echo "8" > /sys/class/gpio/unexport
echo "17" > /sys/class/gpio/unexport
echo "22" > /sys/class/gpio/unexport
echo "23" > /sys/class/gpio/unexport
echo "24" > /sys/class/gpio/unexport
echo "25" > /sys/class/gpio/unexport

# EOF

10_check_level.sh

#!/bin/bash
#set -x

# File: 10_check_level.sh
# Author: Heiko Kretschmer, watering-o-matic at wurst-wasser.net
# Purpose: Reading GPIO pins to get current water level

# Globals
GDIRBASE="/home/pi/Development/giess-o-mat"

# Check if we already set up the GPIOs
"${GDIRBASE}/"00_check_and_init.sh

# Read from level-input (lower and upper water mark of reservoir)
RESERVOIRUPPERWATERMARKVALUE="`cat /sys/class/gpio/gpio25/value`"
RESERVOIRLOWERWATERMARKVALUE="`cat /sys/class/gpio/gpio22/value`"

# Read from level-input (lower water mark of flowerbed)
FLOWERBEDLOWERWATERMARKVALUE="`cat /sys/class/gpio/gpio24/value`"

# Say what's up!
echo ""
echo "Reservoir water level:"
echo "----------------"
echo "RESERVOIRUPPERWATERMARKVALUE: ${RESERVOIRUPPERWATERMARKVALUE} (0=water higher, 1=water lower than watermark)"
echo "RESERVOIRLOWERWATERMARKVALUE: ${RESERVOIRLOWERWATERMARKVALUE} (0=water higher, 1=water lower than watermark)"
echo ""
echo "Flowerbed water level:"
echo "----------------------"
echo "FLOWERBEDLOWERWATERMARKVALUE: ${FLOWERBEDLOWERWATERMARKVALUE} (0=water higher, 1=water lower than watermark)"
echo ""

# Reset pump
echo "1" > /sys/class/gpio/gpio17/value

# EOF

15_pump_10s.sh

#!/bin/bash
#set -x

# Script: 15_pump_10s.sh
# Author: Heiko Kretschmer, watering-o-matic at wurst-wasser.net
# Purpose: Set GPIO pins to start pump

# Globals
GDIRBASE="/home/pi/Development/giess-o-mat"

# Check if we already set up the GPIOs
"${GDIRBASE}/"00_check_and_init.sh

# Check permissions (Actually, just export as root, then set permissions for device files, done)
#test "`whoami`" != "root" && echo "Must be root (or use sudo)." && exit 1

# Start pump
echo "0" > /sys/class/gpio/gpio17/value # start pump

# Run for 10 Seconds
sleep 10

# Stop Pump
echo "1" > /sys/class/gpio/gpio17/value # stop pump

MORE LATER

Some thoughts

FAQ

Choice of programming language
  • Q: Why don't you use python, C or any other higher language?
  • A: I wanted to KISS. Shell is easy to code, easy to maintain, easy to learn, and easy to automate[3]
GPIO protection
  • Q: Why do you connect the GPIOs directly? You should use something like GertBoard to protect your Pi!
  • A: You are so right. I see this as PoC, next time I will do better, I promise. Next winter comes[TM].

  1. ...and I tend to forget...
  2. Ookay, why should you use a valve instead of a pump? The valve will use more power and is more expensive...but it has one big advantage: It is closed when inactive. What? Oookay. I admit it: My reservoir is on a higher level than the flowerbed, as a result the water kept running after the pump stopped. That lead to a bit much water in the flowerbed. In short: IF your reservoir is on higher level -> use solenoid valve. IF your reservoer is lower than flowerbed -> use pump.
  3. Okay, if you need more exact timing, shell is not the environment of choice, but in this case it fits perfectly.