Update: A newer version of this project has been released. Read More >>
There have been many initiatives undertaken to maximize mushroom cultivation productivity, and although variations exist between species, manipulation of environmental conditions has demonstrated some of the most dramatic effects on yield. Temperature, humidity, and carbon dioxide concentration have been identified as some of the most crucial factors for promoting mycelial colonization, primordia formation, and growth of fruiting bodies, or mushrooms. Additionally, each stage of development requires specific conditions for optimal growth. As such, the more precise these conditions can be controlled, the greater the yields that are possible.
In 2009 I created my first automated mushroom cultivator using an ATMega328 and networked Linux computer. It monitored and regulated the temperature and humidity of a growth chamber with the use of a humidifier and heater attached to individually-controlled 120-VAC relays, with a simple web control interface. In 2012 I redesigned the software to run entirely on the Raspberry Pi (RPi) and documented the build shortly after. Although the system worked, it was still very basic and lacked some crucial features I desired. Over the past couple months I’ve been redesigning both the hardware and the software. I’m writing to present the third milestone in development.
vX.0 (current version)
v3.0 (this article’s version)
Support for up to 8 simple timers (define on duration, off duration)
True PID control for temperature and humidity regulation
Support more humidity & temperature sensors (DHT11, DHT22, and AM2302)
Multi-sensors support to regulate multiple environments
TempFS to reduce writes to and extend the life of the SD card
Lock files to prevent sensor read and file access conflicts
New logs to view: login authorization, daemon, sensor, and relay logs
Generate new types of graphs
Combined: generate a graph combining all temperatures or humidities
Separate: generate a graph of the temperature, humidity, and dew point of each sensor
Define graph image width (custom graph only)
Acquire still image or stream live video using the Raspberry Pi camera module
Set relay (light) to be burned on while camera is capturing
New web interface
Tabs allow everything to be loaded on one page
Easy change any variable in the configuration file
Login Authentication (written by php-login.net)
Optional cookie to keep session authenticated
Guest account for viewing only (no config changes permitted) (user: guest, password: anonymous)
Authorization log of successful and unsuccessful login attempts
User profile, gravatar support (from email), lost/forgot email password reset
Support for the DHT22 digital humidity and temperature sensor
Manual or automatic switching of up to four 120-volt AC relays
Automatic operation by simple proportional temperature/humidity regulation
Temperature, humidity, and relay state-change logging
Basic web interface
Configure variables related to sensor reading, log writing, and graph generation
Generate custom graphs of current and past data
Presets of pre-defined time periods (past 1 hour, 6 hours, 1 day, 3 days…)
Specify specific time period to generate graph
ATMega connected by serial USB to a network-enabled computer running linux
Linux periodically read humidity/temperature sensor and write log
ATMega modulate relays for simple proportional humidity/temperature regulation
Simple web interface to view historical data and generate graphs with gnuplot
- Raspberry Pi (version 1, model B)
- RPi Camera module
- USB WiFi dongle
- 5-volt/2A DC power supply (CUI VOF-10-5)
- Relay module, 8 opto-isolated (Sainsmart)
- 2x Crydom D1240 40-amp relays
- DHT22 humidity/temperature sensor
- Electrical box enclosure
- 8-outlet power strip
- Nuts, bolts, standoffs, wire
- Terminal blocks (1×8, 1×6, 2×4)
- Terminal block jumpers
I started with a lockable electrical box with ground connections on the body and door. Holes were drilled and knockouts were removed to feed 12-gauge wire between the 8-outlet strip to the box. The relay board, RPi, and terminal blocks were bolted to the back plate, with the RPi and relay board raised off the plate with stand-offs. The 5-volt power supply was soldered into a circuit with and an in-line 2A fuse and screw-terminals. The terminal blocks were used to distribute power through the relay switches on the relay board, and the 5-volt DC to power the RPi and relay coils. I chose to use six of the eight 10-amp relays to directly switch six outlets, and the remaining two 10-amp relays to control the 40-amp relays, which were wired to switch the remaining two outlets. This allows up to six devices to be used that have a maximum current draw each of 10 amps and two devices to be used that may exceed 10. Last, the main box, door, outlet strip, and outlets were grounded.
2.2 Sensor and Relays
The DHT22 sensor has pins for ground, power, and data. Data connects to a GPIO and though a 10k resistor to DC+. I’m using a Sainsmart 8-relay module, however any opto-isolated relays should suffice. In the case of this relay board, JD-VCC should be connected to the power supply and VCC connected to the RPi VCC to ensures proper isolation of the RPi.
Each relay control pin on the relay board will need to be connected to a GPIO pin on the RPi. Ensure your relays are properly opto-isolated (or otherwise have a very low input current) to prevent drawing too much current from the RPi. Avoid connecting to GPIOs that are normally HIGH or LOW at boot, as this can inadvertently turn your relay on until the GPIO initialization script is executed. Depending on the relay board or custom circuit you end up using, your relays will turn on with either a HIGH (5-volts) or LOW (ground) signal from the RPi. This relay board energizes the relays when a LOW signal is provided. Upon bootup, the voltages of the GPIOs connected to the relays are floating, meaning they are neither HIGH nor LOW but somewhere in between. The initialization script sets all connected GPIOs to output, then sets them LOW from their floating state.
- Mycodo (source code on GitHub)
- php (>= 5.3.7)
- phpmyadmin (optional but recommended)
- python and modules (Adafruit_Python_DHT, LockFile, RPyC, WiringPi)
There are two main programs that run the system, a daemon and a client. The daemon performs all critical tasks, such as periodically reading sensors, writing logs, reading/writing the configuration file, turning relays on and off to regulate temperature, humidity, and airflow, among other functions. The client application issues commands for the daemon to carry out. This is the link from the web interface to the daemon, communicating configuration changes, manual relay switching, modifying automation, and other information. Common usage is to continually run the daemon in the background and use the client to communicate with the daemon.
mycodo.py: Reads sensors, writes logs, and operates relays to maintain set environmental conditions. Usage: mycodo.py [OPTION]... Options: -d, --daemon v/s w/i/d Start program as daemon that monitors conditions and modulates relays v enables log output to the console, s silences Log level: w: >= warnings, i: >= info, d: >= debug -h, --help Display this help and exit Default: mycodo.py -d s w Debugging: mycodo.py -d v d
mycodo-client.py: Client for mycodo.py (must be running in daemon mode -d) Usage: mycodo-client.py [OPTION]... Options: --modtempOR sensor state Temperature PID control: 0=enable, 1=disable --modtempPID sensor relay set p i d period Change Temperature PID variables --modhumOR sensor state Humidity PID control: 0=enable, 1=disable --modhumPID sensor relay set p i d period Change Humidity PID variables --modrelaynames name1 name2 name3 name4 name5 name6 name7 name8 Modify relay names (Restrict to a maximum of 12 characters each) --modrelaypins pin1 pin2 pin3 pin4 pin5 pin6 pin7 pin8 Modify relay pins Using BCM numbering) --modrelaytrigger trig1 trig2 trig3 trig4 trig5 trig6 trig7 trig8 Modify the relay trigger states (0=low, 1=high; turns relay on) --modsensor sensor name device pin period activated graph Modify sensor variables --modtimer timer state relay on off Modify custom timers, State can be 0=off 1=on, on/off durations in seconds -m, --modvar name1 value1 [name2] [value2]... Modify any configuration variable or variables (multiple allowed, must be paired input) -r, --relay relay state Turn a relay on or off. state can be 0, 1, or X. 0=OFF, 1=ON, or X number of seconds On -s, --sensor pin device Returns the temperature and humidity of of the DHT sensor on GPIO pin Device options are DHT22, DHT11, or AM2302 -t, --terminate Terminate the communication service and daemon -w, --writelog sensor Read from sensor number and append log file, 0 to write all.
The web interface provides a way to view and change all aspects of the system as well as generate graphs from current and past sensor data.
I’ve taken the install instructions out of this publication because this is an old version of Mycodo. To find the install instructions to install the latest version of Mycodo, go to github.com/kizniche/Mycodo.
5. The Fruits of My Labor
What project would be complete without some great mushroom photos? I haven’t had a chance to grow with this new controller yet, so these are from a previous harvest. I hope you enjoyed this trip though automated mushroom cultivation.
A Call for Experimentation
Well, you made it to the end of the page. I may end up regretting this, but for now, for science, you can log in to my control interface as a spectator with the user
guest and password
anonymous at [redacted]. If you notice any discrepancies or issues with any of the content, please leave a comment below or use the contact form in the top menu.
Update (4/12/2015 13:50EST)
As expected, my RPi has had an onslaught of attempts to breach the security since featured on hackaday.com. However, it has remained strong.
Here’s a small excerpt of my auth.log. It’s been steady like this for the past 8 hours, before unleashing fail2ban to monitor my auth.log and manage bans in iptables.
Apr 12 13:55:30 sshd: Failed password for root from 220.127.116.11 port 34509 ssh2 Apr 12 13:55:31 sshd: Failed password for root from 18.104.22.168 port 35661 ssh2 Apr 12 13:55:31 sshd: Failed password for root from 22.214.171.124 port 44507 ssh2 Apr 12 13:55:32 sshd: Failed password for root from 126.96.36.199 port 49051 ssh2 Apr 12 13:55:32 sshd: Failed password for root from 188.8.131.52 port 50272 ssh2 Apr 12 13:55:34 sshd: Failed password for root from 184.108.40.206 port 44507 ssh2 Apr 12 13:55:34 sshd: Failed password for root from 220.127.116.11 port 49051 ssh2 Apr 12 13:55:35 sshd: Failed password for root from 18.104.22.168 port 45633 ssh2 Apr 12 13:55:36 sshd: Failed password for root from 22.214.171.124 port 49051 ssh2 Apr 12 13:55:37 sshd: Failed password for root from 126.96.36.199 port 42025 ssh2
Here’s an excerpt from iptables after fail2ban:
Chain fail2ban-ssh (1 references) target prot opt source destination DROP all -- 188.8.131.52 anywhere DROP all -- 184.108.40.206 anywhere DROP all -- 220.127.116.11 anywhere DROP all -- 18.104.22.168 anywhere DROP all -- 22.214.171.124 anywhere DROP all -- 126.96.36.199 anywhere DROP all -- 188.8.131.52 anywhere DROP all -- 184.108.40.206 anywhere DROP all -- 220.127.116.11 anywhere DROP all -- 18.104.22.168 anywhere DROP all -- 22.214.171.124 anywhere DROP all -- 126.96.36.199 anywhere DROP all -- 188.8.131.52 anywhere DROP all -- 184.108.40.206 anywhere DROP all -- 220.127.116.11 anywhere
Here’s an excerpt from the Mycodo auth log. Its formatted by CSV, with the entry after NOUSER being the user name that the user attempted to log in with.
2015 04 12 08:16:31, NOUSER, fungi, 18.104.22.168 2015 04 12 13:39:44, NOUSER, #, 22.214.171.124, chello080109109080.16.15.vie.surfer.at 2015 04 12 13:39:50, NOUSER, --, 126.96.36.199, chello080109109080.16.15.vie.surfer.at 2015 04 12 13:40:02, NOUSER, ' or '1'='1, 188.8.131.52, chello080109109080.16.15.vie.surfer.at
Thank you to all who tested Mycodo while I enabled guest login on my system. I’ve received a lot of feedback that has greatly improved the system. Guest access is currently disabled while I test new features with the 3.5 experimental branch.