beginnings of greenhouse automation

Last year I bought a new larger greenhouse (lwh: 6x4x2.8m). Currently it looks like this:
greenhouse in winter

Which means that I don’t have to deal with actually growing things at the moment and now is a good time to make preparations for the next season.

My ideal is to automate it as much as possible, so first I will try to automate the obvious things like watering and ventilation. In the future things like heating and growlights might be added too.
I have spent several weekends on that project with my friend Kalle who helps me on the electrical engineering front and finally we have something that more or less works.

The current solution consists of controller board & sensor board in the greenhouse. Controller is run by Arduino and controls 220V power outlet & gathers information from various sensors. Bidirectional datalink with the house is done over ZigBee radio. In the house I have a Beagleboard which logs data, draws nice graphs, serves these over the internet and can control Arduino.

The greenhouse controller looks like this:
It consists of:

Some of the Arduinos IO pins are connected to the CAT5 cable that runs to small external sensor board:
The sensor board has following sensors connected to it:

The sensors and connections are protected from the environment mainly by having them covered by a thick layer of hot glue.

First version of the sensor board used LM35 analog temperature sensors which were nice and easy to interface with but thanks to their analog nature were rather sensitive cable length and small voltage flux on the Arduino that was caused by the relay switching and other sensors. Besides LM35 outputs negative voltage for temperatures below 0 deg. C which you can’t measure in a direct way from Arduino.

I haven’t had time yet to document the schematics & connections but for similar well documented project you can take a look here and here.

And here’s how it’s currently “installed”:
The power socket/switch that you see right next to the controller box is meant for the water pump and switch is used to override Arduinos decisions if need be.

Software wise things are quite simple at the moment – controller periodically gathers data from all the sensors and prints them in a line similar to:

H121 T-28.8 T-10.0 L192

Where letter indicates sensor type and number is determined by the position. Since the arduinos serial output is really connected to the ZigBee module I can just read it from the other side of the radio link as though the devices were directly connected with serial cable.

So the code running on Arduino is just this:

#include <OneWire.h>
#include <DallasTemperature.h>
#define ONE_WIRE_BUS 2
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
int humidity_pin = 1;// input pin for the humidity sensor
int light_pin = 5; // input pin for the light sensor
int relay_pin = 12;   // relay switch
float val = 0; // variable for storing sensor value
void setup() {
  pinMode(relay_pin, OUTPUT);  
  digitalWrite(relay_pin, LOW);
float get_temp(int pin) {
  float val;
  return sensors.getTempCByIndex(pin);
void show_temp(float v) {
  Serial.print(" ");  
void loop() {
  val = get_temp(0);
  val = get_temp(1);
  val = analogRead(humidity_pin);
  val = analogRead(light_pin);
  Serial.print(" L");

And on the Beagleboard it’s even simpler:

import serial
import os
import time
import traceback
DATA_DEVICE = "/dev/ttyUSB0"
to create the RRD file:
rrdtool create temperature.rrd --step 300 \
  DS:temp1:GAUGE:600:-273:5000 \
  DS:temp2:GAUGE:600:-273:5000 \
  DS:light:GAUGE:600:0:1000 \
  DS:humidity:GAUGE:600:-273:5000 \
  RRA:AVERAGE:0.5:1:1200 \
  RRA:MIN:0.5:12:2400 \
  RRA:MAX:0.5:12:2400 \
last_ts = None
ser = serial.Serial(DATA_DEVICE, 9600)
def calculate_relative_humidity(raw_humidity_val, temperature_c):
    """converts raw HIH4030 output to relative humidity %"""
    # see for discussion
    if __debug__:
        print raw_humidity_val,temperature_c
    max_voltage = (3.27-(0.006706*temperature_c))
    relative_humidity = ((((raw_humidity_val/1023)*5)-ZERO_PERC_VOLTAGE)/max_voltage)*100
    if relative_humidity > 100.0:
        # if it's  saturated/frozen it outputs raw values around 920 which would lead to
        # RH% in the range on 120 which is theoretically possible but probably just an
        # measurement error / problem with the equation
        return 100.0
    return relative_humidity
def write_sample():
    global last_ts
    l = ser.readline()
    # input is expected to be similar to "T-23 T-10 H100 L20\n"
    if __debug__:
        print "raw:",l,
    temp1, temp2, humidity, light = [float(x[1:]) for x in l.strip().split()]
    humidity = calculate_relative_humidity(humidity, temp2)
    if __debug__:
        print temp1,temp2,humidity,light
    if last_ts is None or (last_ts + SAMPLE_WRITE_TIME) < time.time():
        cmd = "rrdtool update temperature.rrd N:%f:%f:%f:%f" % (temp1, temp2, light, humidity)
        last_ts = time.time()
        if __debug__:
            print "cmd:",cmd
while 1:
    except KeyboardInterrupt:
        print "write failed"

Here’s some sensor data from today:

live data available through Pachube feed

And here’s a picture of the Beagleboard at the garage that gathers data & serves the graphs

Actually getting the Beagleboard working in a suitable manner turned out to be the most complicated part of the whole project. It took 3-4 days in total over a month or so while I reinstalled different distributions, replaced broken SD card, tried more than 10 different versions of the kernel and u-boot and finally removed a capacitor from the Beagleboard to get it stable. Hopefully I will write a separate post about that in the near future 🙂

5 thoughts on “beginnings of greenhouse automation

  1. gabriel

    wonderful idea that auto control ur greenhouse

    but what is ur use for senior control? sth like a ipad?

  2. hadara Post author

    Control software runs on the beagleboard. It provides XMLRPC bindings that both local and remote programs can use to control actuators in the greenhouse. Most of the control logic runs directly on the beagleboard too and doesn’t have a UI. I have also written a very simple application for my N900 that I can use to override default logic for the window and pump controller.
    See later posts for example for more up to date description.

  3. Rudi


    I’m quite interested in your greenhouse project and have a question for which I can’t seem to get a clean answer.

    Where do you place the temperature sensor, inside the greenhouse? And how do you protect it from the sun, and moisture / wind?
    i.e. how do you know the temperatures reported are accurate, and not affected by the elements?

  4. hadara Post author

    In a professional setting Stevenson Screen is used to house temperature and moisture sensors. has a picture of one that can probably built at home with reasonable effort.

    Inside the greenhouse I just used the closest thing to Stevenson screen that I could think of — an largish electric junction box with all the cable holes opened for good ventilation. Something similar to this ->

    Outdoor temperature sensor was placed behind a steal beam on the norther side of the greenhouse, where it doesn’t get any direct sunlight.

    I have no idea how accurate the readings were because I did not require great precision.

  5. FirstLinnea

    I have noticed you don’t monetize your page, don’t waste your traffic, you can earn additional cash
    every month because you’ve got high quality content. If you want to know how to make extra money, search for:
    Boorfe’s tips best adsense alternative

Leave a Reply

Your email address will not be published.