Difference between revisions of "Tomat-O-Mat"
(→How It Works) |
|||
(54 intermediate revisions by the same user not shown) | |||
Line 1: | Line 1: | ||
=== The Idea === | === The Idea === | ||
− | Since I'm too lazy<ref>...and I tend to forget...</ref> to water my tomatoes, I thought it would be nice if a [[Pi]] would take care of that. | + | Since I'm too lazy<ref>...and I tend to forget...</ref> to water my tomatoes<ref>And I'm planning to fly to Texas, so something has to tend to the tomatoes…</ref>, I thought it would be nice if a [[Pi]] would take care of that. |
=== How It Works === | === How It Works === | ||
− | A [[RaspberryPi]] is connected to a Sony Playstation Camera, a DHT11, some level switches, a relay and a | + | A [[RaspberryPi]] is connected to a Sony Playstation Camera, a [[DHT11]], some level switches, a relay and a solenoid valve.<br> |
− | [[Image:TomatOMatSchematics.png]] | + | [[Image:TomatOMatSchematics.png|800px]]<br> |
+ | ==== Parts list ==== | ||
+ | * [[RaspberryPi]] Rev 2 | ||
+ | * Power supply for the [[Pi]] | ||
+ | * Power supply for the pump/solenoid valve (12V, 2A) | ||
+ | * Sony Playstation Camera | ||
+ | * [[DHT11]] (side project [[RaspberryPi Humidity and Temperature Sensor]]) | ||
+ | * [[DS18B20]] (side project [[RaspberryPi Temperature Sensor]]) | ||
+ | * Lower watermark level switches like [http://cgi.ebay.de/ws/eBayISAPI.dll?ViewItem&item=270774716317 this] (vertically mounted) | ||
+ | * Upper watermark level switches like [http://cgi.ebay.de/ws/eBayISAPI.dll?ViewItem&item=251231748848 this] (horizontally mounted) | ||
+ | * <del>Pump (bought on eBay, model DC40A-1215 (12V, 350mA, 400l/h (6l/min), 1.5m delivery head, 30.000h lifetime) like [http://cgi.ebay.de/ws/eBayISAPI.dll?ViewItem&item=350785299632 this])</del>, better yet<ref>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 reservoir is lower than flowerbed -> use pump.</ref>: Solenoid valve like [http://www.magnetventile-shop.de/magnetventile-2/magnetventile-messing/magnetventil-direktgesteuert/elektro-magnetventil-g1/2-zoll-nc-direktgesteuert-v45.html this] | ||
+ | * Relay board (5V, low-triggered, 2-channel, [http://cgi.ebay.de/ws/eBayISAPI.dll?ViewItem&item=390517868081 this]) | ||
+ | * some resistors, cables, wires, boards, and the usual soldering equipment | ||
− | === | + | === Sources === |
− | + | ==== <tt>00_check_and_init.sh</tt> ==== | |
+ | #!/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 | ||
+ | |||
+ | ==== <tt>01_check_init.sh</tt> ==== | ||
+ | #!/bin/bash | ||
+ | #set -x | ||
+ | |||
+ | # Author: tomatomat at 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 | ||
+ | |||
+ | ==== <tt>02_init.sh</tt> ==== | ||
+ | #!/bin/bash | ||
+ | #set -x | ||
+ | |||
+ | # File: 02_init.sh | ||
+ | # Author: tomatomat at 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 | ||
+ | |||
+ | ==== <tt>04_check_uninit.sh</tt> ==== | ||
+ | #!/bin/bash | ||
+ | #set -x | ||
+ | |||
+ | # Author: tomatomat at 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 | ||
+ | |||
+ | ==== <tt>09_uninit.sh</tt> ==== | ||
+ | #!/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 | ||
+ | |||
+ | ==== <tt>10_check_level.sh</tt> ==== | ||
+ | #!/bin/bash | ||
+ | #set -x | ||
+ | |||
+ | # File: 10_check_levels.sh | ||
+ | # Author: Heiko Kretschmer, tomatomat 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`" | ||
+ | RESERVOIRMIDDLEWATERMARKVALUE="`cat /sys/class/gpio/gpio8/value`" | ||
+ | RESERVOIRLOWERWATERMARKVALUE="`cat /sys/class/gpio/gpio22/value`" | ||
+ | |||
+ | # Read from level-input (lower water mark of flowerbed) | ||
+ | FLOWERBEDLOWERWATERMARKVALUE="`cat /sys/class/gpio/gpio24/value`" | ||
+ | FLOWERBEDUPPERWATERMARKVALUE="`cat /sys/class/gpio/gpio23/value`" | ||
+ | |||
+ | # Say what's up! | ||
+ | echo "" | ||
+ | echo "Reservoir water level:" | ||
+ | echo "----------------" | ||
+ | echo "RESERVOIRUPPERWATERMARKVALUE: ${RESERVOIRUPPERWATERMARKVALUE} (0=water higher, 1=water lower than watermark)" | ||
+ | echo "RESERVOIRMIDDLEWATERMARKVALUE: ${RESERVOIRMIDDLEWATERMARKVALUE} (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 "FLOWERBEDUPPERWATERMARKVALUE: ${FLOWERBEDUPPERWATERMARKVALUE} (0=water higher, 1=water lower than watermark)" | ||
+ | echo "FLOWERBEDLOWERWATERMARKVALUE: ${FLOWERBEDLOWERWATERMARKVALUE} (0=water higher, 1=water lower than watermark)" | ||
+ | echo "" | ||
+ | |||
+ | # EOF | ||
+ | |||
+ | ==== <tt>16_pump_10s_if_necessary.sh</tt> ==== | ||
+ | #!/bin/bash | ||
+ | #set -x | ||
+ | |||
+ | # Script: 16_pump_10s_if_necessary.sh | ||
+ | # Author: tomatomat at wurst-wasser.net | ||
+ | # Purpose: Set GPIO pins to start pump | ||
+ | |||
+ | # Globals | ||
+ | GFOLDERBASE="/home/pi/Development/giess-o-mat" | ||
+ | GTIMESTAMPFORMAT="%H:%M:%S" | ||
+ | #GTIMESTAMPFORMAT="%Y-%m-%d_%H:%M:%S" | ||
+ | GTIMESTAMPDATE="`date +%Y-%m-%d`" # ISO8601 | ||
+ | GFOLDERLOGS="${GFOLDERBASE}/logs" | ||
+ | GLOGPUMP="${GFOLDERLOGS}/pump_${GTIMESTAMPDATE}.log" | ||
+ | |||
+ | # Check if we already set up the GPIOs | ||
+ | "${GFOLDERBASE}/"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 | ||
+ | |||
+ | # Read levels | ||
+ | FLOWERBEDLOWERWATERMARKVALUE="`\"${GFOLDERBASE}/\"11_read_FLOWERBEDLOWERWATERMARKVALUE.sh`" | ||
+ | FLOWERBEDUPPERWATERMARKVALUE="`\"${GFOLDERBASE}/\"12_read_FLOWERBEDUPPERWATERMARKVALUE.sh`" | ||
+ | RESERVOIRLOWERWATERMARKVALUE="`\"${GFOLDERBASE}/\"13_read_RESERVOIRLOWERWATERMARKVALUE.sh`" | ||
+ | RESERVOIRMIDDLEWATERMARKVALUE="`\"${GFOLDERBASE}/\"14_read_RESERVOIRMIDDLEWATERMARKVALUE.sh`" | ||
+ | RESERVOIRUPPERWATERMARKVALUE="`\"${GFOLDERBASE}/\"15_read_RESERVOIRUPPERWATERMARKVALUE.sh`" | ||
+ | #echo "RESERVOIRLOWERWATERMARKVALUE: ${RESERVOIRLOWERWATERMARKVALUE}" | ||
+ | |||
+ | # Check water level in reservoir, so we don't run dry! | ||
+ | if [ "${RESERVOIRLOWERWATERMARKVALUE}" -eq 0 ]; then # 0=higher than mark, 1=lower than mark | ||
+ | |||
+ | # Check water level in flowerbed, so we don't drown it (and the tomatoes start to rot) | ||
+ | if [ "${FLOWERBEDUPPERWATERMARKVALUE}" -eq 1 ]; then # 0=higher than mark, 1=lower than mark | ||
+ | |||
+ | # Check water level in flowerbed, so we don't drown it (and the tomatoes start to rot) | ||
+ | if [ "${FLOWERBEDLOWERWATERMARKVALUE}" -eq 1 ]; then # 0=higher than mark, 1=lower than mark | ||
+ | |||
+ | # Start pump | ||
+ | echo "0" > /sys/class/gpio/gpio17/value # start pump | ||
+ | |||
+ | # Log it so we can generate nice graphs afterwards | ||
+ | GTIMESTAMP="`date +${GTIMESTAMPFORMAT}`" | ||
+ | printf "${GTIMESTAMP}\t1\n" >> "${GLOGPUMP}" | ||
+ | |||
+ | # Run for 10 Seconds | ||
+ | sleep 10 | ||
+ | |||
+ | # Stop Pump | ||
+ | echo "1" > /sys/class/gpio/gpio17/value # stop pump | ||
+ | |||
+ | # Log it so we can generate nice graphs afterwards | ||
+ | GTIMESTAMP="`date +${GTIMESTAMPFORMAT}`" | ||
+ | printf "${GTIMESTAMP}\t0\n" >> "${GLOGPUMP}" | ||
+ | echo "`date '+%Y-%m-%d, %H:%M:%S'`: Pumped for 10 seconds (approx. 1l)" | ||
+ | |||
+ | else | ||
+ | echo "`date '+%Y-%m-%d, %H:%M:%S'`: Flowerbeds's lower watermark already reached, pump not started, we don't want to drown the tomatoes..." | ||
+ | fi | ||
+ | |||
+ | else | ||
+ | echo "`date '+%Y-%m-%d, %H:%M:%S'`: Flowerbeds's upper watermark already reached, pump not started, we don't want to drown the tomatoes..." | ||
+ | fi | ||
+ | |||
+ | else | ||
+ | echo "`date '+%Y-%m-%d, %H:%M:%S'`: Reservoir's lower watermark reached, pump not started." | ||
+ | fi | ||
+ | |||
+ | # Just for the logs, not necessary for this script | ||
+ | FLOWERBEDLOWERWATERMARKVALUE="`\"${GFOLDERBASE}/\"11_read_FLOWERBEDLOWERWATERMARKVALUE.sh`" | ||
+ | FLOWERBEDUPPERWATERMARKVALUE="`\"${GFOLDERBASE}/\"12_read_FLOWERBEDUPPERWATERMARKVALUE.sh`" | ||
+ | RESERVOIRLOWERWATERMARKVALUE="`\"${GFOLDERBASE}/\"13_read_RESERVOIRLOWERWATERMARKVALUE.sh`" | ||
+ | RESERVOIRMIDDLEWATERMARKVALUE="`\"${GFOLDERBASE}/\"14_read_RESERVOIRMIDDLEWATERMARKVALUE.sh`" | ||
+ | RESERVOIRUPPERWATERMARKVALUE="`\"${GFOLDERBASE}/\"15_read_RESERVOIRUPPERWATERMARKVALUE.sh`" | ||
+ | |||
+ | #EOF | ||
+ | |||
+ | '''''MORE LATER''''' | ||
+ | ToDo-List: | ||
+ | * Scripts 11..15 | ||
+ | * cronjobs | ||
+ | |||
+ | === 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<ref>Okay, if you need more exact timing, shell is not the environment of choice, but in this case it fits perfectly.</ref> | ||
+ | ===== GPIO protection ===== | ||
+ | *Q: Why do you connect the GPIOs directly? You should use something like [http://www.heise.de/hardware-hacks/meldung/Raspberry-Pi-Erweiterung-Gertboard-wieder-verfuegbar-1789239.html GertBoard] to protect your [[Pi]]! | ||
+ | *A: You are so right. I see this as a [[PoC]], next time I will do better, I promise. Next winter comes[TM]. | ||
---- | ---- | ||
− | * The live cam: http://www.wurst-wasser.net/tomatomat/ | + | * More... |
− | * How the temperature sensor works: [[RaspberryPi Temperature Sensor]] | + | ** The live cam: http://www.wurst-wasser.net/tomatomat/ |
− | * How the humidity and temperature sensor works: [[RaspberryPi Humidity and Temperature Sensor]] | + | ** How the temperature sensor works: [[RaspberryPi Temperature Sensor]] |
+ | ** How the humidity and temperature sensor works: [[RaspberryPi Humidity and Temperature Sensor]] | ||
* Footnotes: | * Footnotes: | ||
<references/> | <references/> | ||
+ | * Tags: RaspberryPi, Raspberry Pi, RasPi, GPIO, Farm, Farming, Tomato, Tomatoes, Water, Flowerbed, Level, Water, Grow, Robot, Automatic, Automated, Valve, Lines, Fertilizer | ||
[[Category:Development]] | [[Category:Development]] | ||
[[Category:RaspberryPi]] | [[Category:RaspberryPi]] |
Latest revision as of 11:43, 18 December 2016
Contents
The Idea
Since I'm too lazy[1] to water my tomatoes[2], 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 solenoid valve.
Parts list
- RaspberryPi Rev 2
- Power supply for the Pi
- Power supply for the pump/solenoid valve (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), better yet[3]: Solenoid valve like this- Relay board (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 at 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 at 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 at 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_levels.sh # Author: Heiko Kretschmer, tomatomat 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`" RESERVOIRMIDDLEWATERMARKVALUE="`cat /sys/class/gpio/gpio8/value`" RESERVOIRLOWERWATERMARKVALUE="`cat /sys/class/gpio/gpio22/value`" # Read from level-input (lower water mark of flowerbed) FLOWERBEDLOWERWATERMARKVALUE="`cat /sys/class/gpio/gpio24/value`" FLOWERBEDUPPERWATERMARKVALUE="`cat /sys/class/gpio/gpio23/value`" # Say what's up! echo "" echo "Reservoir water level:" echo "----------------" echo "RESERVOIRUPPERWATERMARKVALUE: ${RESERVOIRUPPERWATERMARKVALUE} (0=water higher, 1=water lower than watermark)" echo "RESERVOIRMIDDLEWATERMARKVALUE: ${RESERVOIRMIDDLEWATERMARKVALUE} (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 "FLOWERBEDUPPERWATERMARKVALUE: ${FLOWERBEDUPPERWATERMARKVALUE} (0=water higher, 1=water lower than watermark)" echo "FLOWERBEDLOWERWATERMARKVALUE: ${FLOWERBEDLOWERWATERMARKVALUE} (0=water higher, 1=water lower than watermark)" echo "" # EOF
16_pump_10s_if_necessary.sh
#!/bin/bash #set -x # Script: 16_pump_10s_if_necessary.sh # Author: tomatomat at wurst-wasser.net # Purpose: Set GPIO pins to start pump # Globals GFOLDERBASE="/home/pi/Development/giess-o-mat" GTIMESTAMPFORMAT="%H:%M:%S" #GTIMESTAMPFORMAT="%Y-%m-%d_%H:%M:%S" GTIMESTAMPDATE="`date +%Y-%m-%d`" # ISO8601 GFOLDERLOGS="${GFOLDERBASE}/logs" GLOGPUMP="${GFOLDERLOGS}/pump_${GTIMESTAMPDATE}.log" # Check if we already set up the GPIOs "${GFOLDERBASE}/"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 # Read levels FLOWERBEDLOWERWATERMARKVALUE="`\"${GFOLDERBASE}/\"11_read_FLOWERBEDLOWERWATERMARKVALUE.sh`" FLOWERBEDUPPERWATERMARKVALUE="`\"${GFOLDERBASE}/\"12_read_FLOWERBEDUPPERWATERMARKVALUE.sh`" RESERVOIRLOWERWATERMARKVALUE="`\"${GFOLDERBASE}/\"13_read_RESERVOIRLOWERWATERMARKVALUE.sh`" RESERVOIRMIDDLEWATERMARKVALUE="`\"${GFOLDERBASE}/\"14_read_RESERVOIRMIDDLEWATERMARKVALUE.sh`" RESERVOIRUPPERWATERMARKVALUE="`\"${GFOLDERBASE}/\"15_read_RESERVOIRUPPERWATERMARKVALUE.sh`" #echo "RESERVOIRLOWERWATERMARKVALUE: ${RESERVOIRLOWERWATERMARKVALUE}" # Check water level in reservoir, so we don't run dry! if [ "${RESERVOIRLOWERWATERMARKVALUE}" -eq 0 ]; then # 0=higher than mark, 1=lower than mark # Check water level in flowerbed, so we don't drown it (and the tomatoes start to rot) if [ "${FLOWERBEDUPPERWATERMARKVALUE}" -eq 1 ]; then # 0=higher than mark, 1=lower than mark # Check water level in flowerbed, so we don't drown it (and the tomatoes start to rot) if [ "${FLOWERBEDLOWERWATERMARKVALUE}" -eq 1 ]; then # 0=higher than mark, 1=lower than mark # Start pump echo "0" > /sys/class/gpio/gpio17/value # start pump # Log it so we can generate nice graphs afterwards GTIMESTAMP="`date +${GTIMESTAMPFORMAT}`" printf "${GTIMESTAMP}\t1\n" >> "${GLOGPUMP}" # Run for 10 Seconds sleep 10 # Stop Pump echo "1" > /sys/class/gpio/gpio17/value # stop pump # Log it so we can generate nice graphs afterwards GTIMESTAMP="`date +${GTIMESTAMPFORMAT}`" printf "${GTIMESTAMP}\t0\n" >> "${GLOGPUMP}" echo "`date '+%Y-%m-%d, %H:%M:%S'`: Pumped for 10 seconds (approx. 1l)" else echo "`date '+%Y-%m-%d, %H:%M:%S'`: Flowerbeds's lower watermark already reached, pump not started, we don't want to drown the tomatoes..." fi else echo "`date '+%Y-%m-%d, %H:%M:%S'`: Flowerbeds's upper watermark already reached, pump not started, we don't want to drown the tomatoes..." fi else echo "`date '+%Y-%m-%d, %H:%M:%S'`: Reservoir's lower watermark reached, pump not started." fi # Just for the logs, not necessary for this script FLOWERBEDLOWERWATERMARKVALUE="`\"${GFOLDERBASE}/\"11_read_FLOWERBEDLOWERWATERMARKVALUE.sh`" FLOWERBEDUPPERWATERMARKVALUE="`\"${GFOLDERBASE}/\"12_read_FLOWERBEDUPPERWATERMARKVALUE.sh`" RESERVOIRLOWERWATERMARKVALUE="`\"${GFOLDERBASE}/\"13_read_RESERVOIRLOWERWATERMARKVALUE.sh`" RESERVOIRMIDDLEWATERMARKVALUE="`\"${GFOLDERBASE}/\"14_read_RESERVOIRMIDDLEWATERMARKVALUE.sh`" RESERVOIRUPPERWATERMARKVALUE="`\"${GFOLDERBASE}/\"15_read_RESERVOIRUPPERWATERMARKVALUE.sh`" #EOF
MORE LATER ToDo-List:
- Scripts 11..15
- cronjobs
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[4]
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 a PoC, next time I will do better, I promise. Next winter comes[TM].
- More...
- The live cam: http://www.wurst-wasser.net/tomatomat/
- How the temperature sensor works: RaspberryPi Temperature Sensor
- How the humidity and temperature sensor works: RaspberryPi Humidity and Temperature Sensor
- Footnotes:
- ↑ ...and I tend to forget...
- ↑ And I'm planning to fly to Texas, so something has to tend to the tomatoes…
- ↑ 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 reservoir is lower than flowerbed -> use pump.
- ↑ Okay, if you need more exact timing, shell is not the environment of choice, but in this case it fits perfectly.
- Tags: RaspberryPi, Raspberry Pi, RasPi, GPIO, Farm, Farming, Tomato, Tomatoes, Water, Flowerbed, Level, Water, Grow, Robot, Automatic, Automated, Valve, Lines, Fertilizer