skip to Main Content

Mini Grow Tower Control System Pi Configuration

Authors: Dayne Broderson, Gabriel Low

Goal:
Configure a Raspberry Pi to become a Vertical Hydroponic Grow Tower control system and GUI.

What you will learn:
How to configure Node-Red, as well as configure MQTT and cron, to set up an automatic on/off timer for grow-lights and pumps and Node-Red dashboard as a user-friendly graphical user interface for users to interact with.

The full list of materials are linked below

What you will need:

– Raspberry Pi 3 Model B
– Raspberry Pi Official 7in Touchscreen
– Case for RPi and touchscreen (SmartPi Touch)
– BME280 Sensor
– AC Relay
– Built Grow Tower (pdf instructions here)
Full list of Grow Tower materials

 

Introduction:

This lesson will go through step-by-step instructions on how to set up and configure a control system for a hydroponic grow tower using a Raspberry Pi. The lesson goes through basic Dashboard configuration, BME280 configuration and visualization, and incorporating AC relay controllers, as well as an introduction to MQTT and cron.

Automating grow towers with Raspberry Pis was spearheaded by the UAF upward bound program during the summer of 2019. Many places in rural Alaska where the UB students are from, fresh greens are at times impossible to come by. Automated grow towers address this issue by providing year-round fresh produce.

This tutorial assumes that all materials are available, and the grow tower has already been built.

Getting Started:

Connect the Pi that you will use to a screen, mouse, and keyboard.

It is recommended to set up your Pi right away in the SmartPi Touch Casing with the 7 inch touch screen. To see setup instructions watch this video.

After completing Step 1 on the touch screen, you can VNC into the Pi to complete the process below.

The BME280 should be connected to the SDA and SCL GPIO pins, and the Relay connected to Pin 8. Remember that the “-” on the relay is ground, and the “+” is to GPIO Pin 8.

Step 1: Change the hostname of the Pi & password for the pi user 

  • Raspberry Menu -> Preferences -> Raspberry Pi Configuration
  • Enable VNC and SSH access to the Pi

               

Step 2: Enable Node-Red on Boot

  • Enter the command below into the terminal
sudo systemctl enable nodered.service

Step 3: Enable an auto-launcher web browser in kiosk mode, that automatically opens to the Node-Red Dashboard UI.

  • Type the following commands into the terminal
mkdir -p .config/lxsession/LXDE-pi/

nano .config/lxsession/LXDE-pi/autostart

#Add the following content to the autostart file
@lxpanel --profile LXDE-pi 
@pcmanfm --desktop --profile LXDE-pi 
@point-pi 
@chromium-browser --kiosk http://localhost:1880/ui --start-fullscreen
  • To save the file, first exit pressing command-X, then confirm by pressing the Y key, and then enter to save.

Step 4: Install MQTT servers and clients to send and receive control commands for lights

  • MQTT is a protocol to send and receive data over a network. In this scenario with the grow towers, MQTT is being used in combination with the timer software utility cron.
sudo apt install mosquitto mosquitto-clients

Step 5: Install Cronjob to control lights on a timer

export EDITOR=nano
crontab -e
#Add the following content to the end of the existing file
55 17 * * * mosquitto_pub -h localhost -t/control/lights -m on
5 0 * * * mosquitto_pub -h localhost -t/control/lights -m on
55 5 * * * mosquitto_pub -h localhost -t/control/lights -m off

#The above turns the lights on at 5:55pm and 5 after midnight. Lights off at 5:55am
#This assumes the Pi has the correct date-time set. If not, connect the Pi to the internet

Step 6: Node-Red flows

  • Copy the code at the bottom of this page and past it into Node-Red and import from clipboard. It is recommended that students and instructors go through every node to understand its function.

Step 7: Test the system

  • Reboot the Pi and verify chrome UI launches
  • Connect BME280 sensor, and verify sensor is being read
  • Use dashboard “About” tab to try turning lights on & off
  • Open terminal and turn lights on and off using MQTT:
mosquitto_pub -h localhost -t /control/lights -m on
mosquitto_pub -h localhost -t /control/lights -m off

 

Hint: Close UI web page with Control-W. If no keyboard available connect via SSH or VNC. 

Node-Red flow:

[{"id":"c2e4b40d.d1c788","type":"comment","z":"36ab9592.b3aaaa","name":"Date  & Time","info":"","x":130,"y":60,"wires":[]},{"id":"98405817.1cb5a8","type":"ui_text","z":"36ab9592.b3aaaa","group":"95d05e8a.33217","order":1,"width":"7","height":"1","name":"","label":"Date:","format":"{{msg.payload}}","layout":"col-center","x":490,"y":80,"wires":[]},{"id":"1695bc99.4c6623","type":"inject","z":"36ab9592.b3aaaa","name":"","topic":"","payload":"1","payloadType":"num","repeat":"1","crontab":"","once":true,"onceDelay":0.1,"x":150,"y":120,"wires":[["45922151.d1f1","9d13170.94fa5e8"]]},{"id":"fb8c2aea.b785e8","type":"debug","z":"36ab9592.b3aaaa","name":"","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":510,"y":120,"wires":[]},{"id":"45922151.d1f1","type":"function","z":"36ab9592.b3aaaa","name":"date","func":"var ts = new Date();\nmsg.payload = ts.toLocaleDateString();\n\nreturn msg;","outputs":1,"noerr":0,"x":310,"y":80,"wires":[["98405817.1cb5a8","fb8c2aea.b785e8"]]},{"id":"9d13170.94fa5e8","type":"function","z":"36ab9592.b3aaaa","name":"Time","func":"var ts = new Date();\nmsg.payload = ts.toLocaleTimeString();\n\nreturn msg;","outputs":1,"noerr":0,"x":310,"y":160,"wires":[["fb8c2aea.b785e8","d5187332.e171e"]]},{"id":"d5187332.e171e","type":"ui_text","z":"36ab9592.b3aaaa","group":"95d05e8a.33217","order":2,"width":"7","height":"1","name":"","label":"Time:","format":"{{msg.payload}}","layout":"col-center","x":490,"y":160,"wires":[]},{"id":"a2506f7b.5cd1e","type":"mqtt in","z":"36ab9592.b3aaaa","name":"","topic":"/control/lights","qos":"2","datatype":"auto","broker":"eca9355f.429c98","x":130,"y":260,"wires":[["4964cbd2.cf8714"]]},{"id":"f55d0604.ccf7a8","type":"inject","z":"36ab9592.b3aaaa","name":"","topic":"","payload":"on","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":150,"y":320,"wires":[["4964cbd2.cf8714"]]},{"id":"5535e805.1c1f98","type":"inject","z":"36ab9592.b3aaaa","name":"","topic":"","payload":"off","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":150,"y":360,"wires":[["4964cbd2.cf8714"]]},{"id":"4964cbd2.cf8714","type":"change","z":"36ab9592.b3aaaa","name":"","rules":[{"t":"change","p":"payload","pt":"msg","from":"on","fromt":"str","to":"1","tot":"num"},{"t":"change","p":"payload","pt":"msg","from":"off","fromt":"str","to":"0","tot":"num"}],"action":"","property":"","from":"","to":"","reg":false,"x":360,"y":320,"wires":[["261ae99d.7c11c6"]]},{"id":"5aed108e.1d8db","type":"comment","z":"36ab9592.b3aaaa","name":"valid output is a string of \"on\" or \"off\"","info":"","x":220,"y":220,"wires":[]},{"id":"b2a69b42.abecf8","type":"comment","z":"36ab9592.b3aaaa","name":"convert to 1 or 0","info":"","x":360,"y":280,"wires":[]},{"id":"261ae99d.7c11c6","type":"rpi-gpio out","z":"36ab9592.b3aaaa","name":"","pin":"8","set":true,"level":"0","freq":"","out":"out","x":580,"y":320,"wires":[]},{"id":"afd25877.2cef98","type":"comment","z":"36ab9592.b3aaaa","name":"control lights GPIO","info":"","x":610,"y":280,"wires":[]},{"id":"70f441f3.08756","type":"ui_button","z":"36ab9592.b3aaaa","name":"","group":"d3dc56c9.643a18","order":2,"width":0,"height":0,"passthru":false,"label":"Lights OFF","tooltip":"Turn the lights off","color":"white","bgcolor":"black","icon":"fa-repeat","payload":"off","payloadType":"str","topic":"","x":130,"y":400,"wires":[["4964cbd2.cf8714"]]},{"id":"a5be28f5.8affc8","type":"ui_button","z":"36ab9592.b3aaaa","name":"","group":"d3dc56c9.643a18","order":1,"width":0,"height":0,"passthru":false,"label":"Lights ON","tooltip":"Turn the lights ON","color":"black","bgcolor":"grey","icon":"fa-repeat","payload":"on","payloadType":"str","topic":"","x":120,"y":440,"wires":[["4964cbd2.cf8714"]]},{"id":"e51d6774.7bfec8","type":"ui_text","z":"36ab9592.b3aaaa","group":"e513e3ea.5fa9e","order":1,"width":"7","height":"4","name":"splash text","label":"<center><h3>Upward Bound Mini Tower</h3> <br/><p>Created by UAF the Upward Bound and Teaching Through Technology team.</p><br/><p> http://t3alliance.org</p> </center>","format":"{{msg.payload}}","layout":"col-center","x":130,"y":520,"wires":[]},{"id":"3414caa7.d44106","type":"inject","z":"36ab9592.b3aaaa","name":"","topic":"","payload":"","payloadType":"date","repeat":"6","crontab":"","once":false,"onceDelay":0.1,"x":130,"y":700,"wires":[["fdae6e59.51a79"]]},{"id":"fdae6e59.51a79","type":"exec","z":"36ab9592.b3aaaa","command":"hostname -I","addpay":false,"append":"","useSpawn":"false","timer":"","oldrc":false,"name":"","x":310,"y":700,"wires":[["5c52cb2c.73c394"],[],[]]},{"id":"5c52cb2c.73c394","type":"ui_text","z":"36ab9592.b3aaaa","group":"e513e3ea.5fa9e","order":2,"width":0,"height":0,"name":"","label":"IP Address:","format":"{{msg.payload}}","layout":"row-spread","x":490,"y":700,"wires":[]},{"id":"bab02a36.df0f28","type":"exec","z":"36ab9592.b3aaaa","command":"sudo shutdown -h now","addpay":true,"append":"","useSpawn":"false","timer":"","oldrc":false,"name":"","x":340,"y":640,"wires":[[],[],[]]},{"id":"7c371336.2ecbcc","type":"exec","z":"36ab9592.b3aaaa","command":"sudo reboot","addpay":true,"append":"","useSpawn":"false","timer":"","oldrc":false,"name":"","x":330,"y":580,"wires":[[],[],[]]},{"id":"4569b108.986d","type":"ui_button","z":"36ab9592.b3aaaa","name":"","group":"d3dc56c9.643a18","order":3,"width":0,"height":0,"passthru":false,"label":"!!REBOOT!!","tooltip":"A safe way to reboot the pi.","color":"black","bgcolor":"green","icon":"fa-repeat","payload":"1","payloadType":"str","topic":"","x":130,"y":580,"wires":[["7c371336.2ecbcc"]]},{"id":"f6c1419f.493ce","type":"ui_button","z":"36ab9592.b3aaaa","name":"","group":"d3dc56c9.643a18","order":4,"width":0,"height":0,"passthru":false,"label":"!!SHUTDOWN!!","tooltip":"A safe shutdown that turns the pi off requiring a manual startup after.","color":"black","bgcolor":"red","icon":"fa-power-off","payload":"1","payloadType":"str","topic":"","x":120,"y":640,"wires":[["bab02a36.df0f28"]]},{"id":"1781c949.3b3ea7","type":"inject","z":"36ab9592.b3aaaa","name":"","topic":"","payload":"","payloadType":"date","repeat":"6","crontab":"","once":false,"onceDelay":0.1,"x":130,"y":820,"wires":[["879fc2ce.36d5b"]]},{"id":"879fc2ce.36d5b","type":"exec","z":"36ab9592.b3aaaa","command":"hostname","addpay":false,"append":"","useSpawn":"false","timer":"","oldrc":false,"name":"","x":300,"y":820,"wires":[["4f0f4bbe.d300d4"],[],[]]},{"id":"4f0f4bbe.d300d4","type":"ui_text","z":"36ab9592.b3aaaa","group":"e513e3ea.5fa9e","order":3,"width":0,"height":0,"name":"","label":"Hostname:","format":"{{msg.payload}}","layout":"row-spread","x":470,"y":820,"wires":[]},{"id":"b761fd00.2ac1a","type":"inject","z":"36ab9592.b3aaaa","name":"","topic":"","payload":"","payloadType":"date","repeat":"6","crontab":"","once":false,"onceDelay":0.1,"x":130,"y":760,"wires":[["14f3fbda.256d04"]]},{"id":"14f3fbda.256d04","type":"exec","z":"36ab9592.b3aaaa","command":"cat /sys/class/net/wlan0/address","addpay":false,"append":"","useSpawn":"false","timer":"","oldrc":false,"name":"","x":370,"y":760,"wires":[["98597277.fdefc"],[],[]]},{"id":"98597277.fdefc","type":"ui_text","z":"36ab9592.b3aaaa","group":"e513e3ea.5fa9e","order":4,"width":0,"height":0,"name":"","label":"Mac:","format":"{{msg.payload}}","layout":"row-spread","x":590,"y":760,"wires":[]},{"id":"1268ad1.fc77053","type":"Bme280","z":"36ab9592.b3aaaa","name":"","bus":"1","address":"0x76","topic":"bme280","extra":true,"x":340,"y":980,"wires":[["9d010eab.8b56b","7fadad93.e77424","cec801b6.552e7","598e3e06.222db"]]},{"id":"b738ec8e.87007","type":"inject","z":"36ab9592.b3aaaa","name":"inject every second","topic":"","payload":"1","payloadType":"num","repeat":"5","crontab":"","once":true,"onceDelay":0.1,"x":140,"y":980,"wires":[["1268ad1.fc77053"]]},{"id":"7fadad93.e77424","type":"debug","z":"36ab9592.b3aaaa","name":"","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":510,"y":1100,"wires":[]},{"id":"9d010eab.8b56b","type":"change","z":"36ab9592.b3aaaa","name":"humidity","rules":[{"t":"set","p":"payload","pt":"msg","to":"payload.humidity","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":500,"y":980,"wires":[["a100191e.8e88b8"]]},{"id":"86511aca.753fe8","type":"comment","z":"36ab9592.b3aaaa","name":"BME 280","info":"","x":120,"y":920,"wires":[]},{"id":"9ace2303.a1a7b","type":"ui_text","z":"36ab9592.b3aaaa","group":"419ea195.7cf7b","order":4,"width":0,"height":0,"name":"","label":"Air Temperature","format":"{{msg.payload}}","layout":"col-center","x":740,"y":1040,"wires":[]},{"id":"b4d9e950.d8e3f8","type":"ui_text","z":"36ab9592.b3aaaa","group":"419ea195.7cf7b","order":3,"width":"0","height":"0","name":"","label":"Air Humidity","format":"{{msg.payload}}%","layout":"col-center","x":770,"y":980,"wires":[]},{"id":"a100191e.8e88b8","type":"function","z":"36ab9592.b3aaaa","name":"round","func":"var prev=msg.payload;\n\n\n    water=Math.round(prev);\n    \n\n\nvar newMsg={payload:water};\n  \n  \nreturn newMsg;","outputs":1,"noerr":0,"x":630,"y":980,"wires":[["b4d9e950.d8e3f8"]]},{"id":"cec801b6.552e7","type":"function","z":"36ab9592.b3aaaa","name":"format temp data","func":"var tempC=msg.payload.temperature_C;\n\nairC=Math.round(tempC*100)/100;\n\nvar tempF=msg.payload.temperature_F;\n\nairF=Math.round(tempF*100)/100;\n\nvar air =airC+\"°C : \"+airF+\"°F\";\n    \nvar newMsg={payload:air};\n  \nreturn newMsg;","outputs":1,"noerr":0,"x":530,"y":1040,"wires":[["9ace2303.a1a7b"]]},{"id":"95fbcff4.d1c54","type":"ui_gauge","z":"36ab9592.b3aaaa","name":"","group":"76bb364.3b709c8","order":2,"width":"7","height":"5","gtype":"gage","title":"Air Temperature","label":"F","format":"{{value | number:2}}","min":"0","max":"100","colors":["#ca3838","#008f00","#0200b7"],"seg1":"32","seg2":"90","x":660,"y":940,"wires":[]},{"id":"598e3e06.222db","type":"change","z":"36ab9592.b3aaaa","name":"Temp_F","rules":[{"t":"set","p":"payload","pt":"msg","to":"payload.temperature_F","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":500,"y":940,"wires":[["95fbcff4.d1c54"]]},{"id":"95d05e8a.33217","type":"ui_group","z":"","name":"Date and Time","tab":"51fedea1.b200f","order":2,"disp":false,"width":"7","collapse":false},{"id":"eca9355f.429c98","type":"mqtt-broker","z":"","name":"localhost","broker":"localhost","port":"1883","clientid":"","usetls":false,"compatmode":false,"keepalive":"60","cleansession":true,"birthTopic":"","birthQos":"0","birthPayload":"","closeTopic":"","closeQos":"0","closePayload":"","willTopic":"","willQos":"0","willPayload":""},{"id":"d3dc56c9.643a18","type":"ui_group","z":"","name":"Controls","tab":"70621cd1.e20124","order":2,"disp":true,"width":"6","collapse":false},{"id":"e513e3ea.5fa9e","type":"ui_group","z":"","name":"          ","tab":"70621cd1.e20124","order":1,"disp":true,"width":"6","collapse":false},{"id":"419ea195.7cf7b","type":"ui_group","z":"","name":"Date and Time","tab":"51fedea1.b200f","order":2,"disp":false,"width":"7","collapse":false},{"id":"76bb364.3b709c8","type":"ui_group","z":"","name":"Readings","tab":"51fedea1.b200f","order":1,"disp":true,"width":"7","collapse":false},{"id":"51fedea1.b200f","type":"ui_tab","z":"","name":"Home","icon":"dashboard","order":1,"disabled":false,"hidden":false},{"id":"70621cd1.e20124","type":"ui_tab","z":"","name":"About","icon":"fa-cogs","order":6,"disabled":false,"hidden":false}]

 

Back To Top