Home Greenhouse Controller

Low Cost Greenhouse Automation


Tom Schmidt






In 2012 I designed a simple system to manage greenhouse ventilation and thermal storage. This paper describes the various features and the tradeoffs implementing them.  The brain of the system is a low cost programmable logic controller (PLC) that includes a web server allowing remote access to greenhouse status.



Table of Contents


Greenhouse Basics. 3

Automation Goals – the Wish List. 4

Roof Ventilation. 5

Thermal Storage – Stone Floor. 5

Thermal Storage – Water Barrels. 6

Freeze Protection. 6

Humidity Control 7

Solar Batch Water Heater. 7

Lighting. 9

Switched Receptacles. 9

Sensors. 9

Temperature. 9

Outside Air. 10

Greenhouse Air. 10

Water Thermal Mass. 10

Domestic Hot Water. 11

Humidity. 11

Door Monitoring. 11

Alerts. 11

Freeze Warning. 11

Basements Fan Door Closed. 11

Temperature Sensor Failure. 11

Daily Status Email 12

Min/Max Temperature Logger. 12

UROM Bounds Check. 13

System Implementation. 15

WebControl PLC. 16

Interface PCB. 17

Temperature Display. 17

AC Power. 18

DC Power. 18

Sensors. 18

Web Interface. 19

Modifying Set Points. 20

To-do List. 21

Conclusions. 21

Appendix A Schematics. 22

Chassis Wiring. 22

Front Panel Wiring. 23

PLC Wiring. 24

Interface PCB – Logic. 25

Interface PCB – Switch Conditioning. 26

Sensor Wiring. 27

Appendix B PLC code. 28

Appendix C PLC Configuration. 37



Greenhouse Basics

We have an 8 x 16 foot lean-to greenhouse.  The lean-to design reduced cost and minimizes heat loss through the north greenhouse wall. The house has a walkout basement facing almost due south. The greenhouse floor is at basement level with a concrete frost wall extending 4 feet below and rising about 4 feet above the floor.  The frost wall is insulated with 2” of foam board and much of it is below ground level minimizing heat loss.

Greenhouse structure is comprised of 2x6 and 2x4 pressure treated lumber routed to accept 8mm dual wall polycarbonate panels.  The inspiration for this construction technique came from a New Yankee Workshop episode where they featured a small standalone greenhouse. I struggled with the problem of using fixed size glazing panels. Because this is a lean-to greenhouse roof height is determined by the bottom of the first floor windows. Standard sized panels did not fit in the available space.  The polycarbonate panels are ideal as they can be easily cut to size. Routing channels in the framing lumber eliminated the cost of aluminum extrusions normally used to mount the panels.  Since the panels are retained in routed channels the structure is not completely watertight so there are a few drips during heavy rain. This would be a problem if we were using it as a sun room but not as a greenhouse.  The leaks did however affect how the electrical system was installed.

Ventilation is provided by three windows, one each on the east and west wall and a central roof vent.  They were custom built for the greenhouse. I built the frames out of pressure treated lumber and used polycarbonate panels for glazing. The windows are controlled by Bayliss Autovent passive openers. A temperature sensitive cylinder forces the window open as it heats up. A knurled knob at the top adjusts opening temperature.  The openers work great but unfortunately simply opening windows does not move enough air to maintain reasonable temperature during full summer sun. The solution was to add forced air movement to reduce inside temperature.

To keep the two wall windows tightly closed I used 3 lb. cable tensioners to augment the Autovent openers. These were government surplus devices made by John Evan’s Sons Inc. I removed the Velcro and hooks and mounted them at the bottom of each window.  They do a great job keeping the window closed. The Autovent is able to lift 14 lbs. so works fine counteracting the tensioner. The roof window is heavy enough that gravity keeps it sealed.

There are two entrance doors one from the basement and one to the outside. The basement door has a dual pane fixed glass center section to let light into the basement. The exterior entrance door is a Larson storm door with a large movable screened opening to provide additional ventilation during the summer. During the winter we add an inside storm panel to minimize heat loss. 

Due to the large amount of glazing greenhouse solar gain is high but so are loses.  Without a large thermal mass temperature fluctuates rapidly, dropping at night and overheating during sunny days. This requires venting excess heat during the day and adding makeup heat at night. Adding thermal mass helps moderate temperature swing by absorbing heat during the day and releasing it at night.  We opted for water barrel storage. Used 55 gallon drums are cheap and water to fill them even cheaper.  We use 6 55 gallon plastic drums placed along the north wall. When I was searching for a local supplier was surprised to discover how many folks are selling them.  Each barrel is painted black to maximize heat absorption. Ideally I should have used an additional 6 stacked on top but that would consume too much valuable space. Insufficient thermal storage means temperature fluctuation is higher than desired and we often needed to open the basement door to keep the greenhouse above freezing.  

The floor of the greenhouse is filled with 4 feet of pea stone. Stone and masonry are great ways to store heat, the trick is to warm up the stone during the day and extract heat at night.

These limitations prompted me to embark on a project to automate greenhouse ventilation, energy storage and if needed to automatically steal heat from the basement to maintain adequate temperature. The resulting controller is described in this paper.

Automation Goals – the Wish List

1.       Control summertime overheating and prevent freezing in winter.

2.       Manage humidity during the winter when greenhouse is buttoned up.

3.       If a problem occurs want to be notified without having to go to the greenhouse. 

4.       Override automatic functions in case the controller fails or we encounter unusual conditions.

5.       Manage multiple indoor and outdoor temperature sensors.

6.       Flexible programming interface.

7.       Built in web server so greenhouse functions can be monitored remotely.

8.       Local display of greenhouse air temperature.

9.       The controller is on 24/7/365 so low power consumption is important.

10.   Low price and cost of ownership.

The design I ultimately came up with meets these requirements and I was able to add a few other features to boot.


Roof Ventilation

The passive actuators work great to open and close the vents so I decided to augment them with a roof mounted fan. I used a dual fan assembly designed to cool server racks mounted under the roof vent.  In the picture you can see the Autovent adjustment knob poking out behind the middle of the fan. The fan is designed to fit a standard 19”rack, so it was easy to install within the ceiling joists supporting the roof vent.  The controller monitors internal greenhouse air temperate to control the fan. A couple of degrees of hysteresis minimize short cycling the fan. 

The fan assembly is plugged into a ceiling mounted receptacle. Because it is upside down I used a Twist-Lock receptacle to make sure the plug does not fall out.

Thermal Storage – Stone Floor

The floor of the greenhouse consists of several feet of pea stone.  This represents a large underutilized thermal mass. A stone floor by itself is not a very effective storage medium because not much heat is transferred to and from the stone.   To better utilize the rock mass I mounted a squirrel cage blower near the roof, connected to a pair of 3” PVC DWV pipes to conduct air to two flexible perforated pipes embedded in the stone.  Centrifugal blowers are a good choice for this task because backpressure is high.

The controller monitors outside air temperate and turns the blower on when temperate falls below the set point.  This way the blower does not run needlessly during warm times. During the day warm air is blown into the stone heating it up and reducing the need to vent excess heat. At night air blown through the stone extracts heat to help maintain temperature. As with the ceiling fan a couple of degrees of hysteresis is used to minimize short cycling the blower.


Thermal Storage – Water Barrels

Six plastic barrels are lined up against the north wall of the greenhouse. They are under the boards on the left of the picture. 

One of the temperature channels is used to monitor water barrel temperature. The water barrels are a passive thermal mass. The controller simply monitors water temperature to provide an idea of how much energy is being absorbed and released by the water.




Freeze Protection

If air temperature cannot be maintained the controller turns on a fan that blows air in from the basement. This fan assembly is identical to the one mounted in the roof vent. The basement is heated so this infuses the greenhouse with 70ish degree air. A filter keeps greenhouse insects from entering the house.

During the summer a door covers the fan to keep high temperate greenhouse air from infiltrating the basement. When greenhouse temperature drops below the set point and if the door is open the basement fan is turned on and the rock blower disabled. No reason to warm up the rock floor if we are trying to prevent inside air temperature from falling.

The PLC monitors door state by reading a magnetic sensor.  If the fan door is closed the basement fan is not turned on, the PLC sends out a warning email, and the rock blower is left running. If the door is closed the controller is unable to move warm air from the basement to the greenhouse. Leaving the rock fan on is the best fallback strategy to reduce the possibility of greenhouse freezing as warm air cannot be brought in from the basement.  In addition to sending a warning email the basement fan status LED flashes indicating the door is closed.


Humidity Control

In the initial design I neglected to consider the problem of excessive humidity during winter. With the greenhouse closed humidity was 100% on some days causing mold to grow on colder surfaces. To address the problem I added a small DC fan on the East wall exhausting through a high quality metal dryer vent. The vent flapper seals well preventing cold air from blowing back into the greenhouse.  The PLC includes a humidity sensor so I used that for primary control of the fan.  The algorithm disables the fan if outside temperature is high, no sense running the fan if the vent windows are open. The fan is also disabled when inside temperature is low to reduce the rate of temperature fall and minimize how much air needs to be brought in by the basement fan.     

The fan is powered from the same 9V 1A supply used by the controller. The fan draws about 500ma and the controller and external logic another 250ma safely within the limits of the supply.  A FET switching transistor is used to control power to the fan. As with the other outputs an LED on the front panel indicates state and toggle switch can be used to override the controller.

Solar Batch Water Heater

The greenhouse provided a convenient location to install a passive batch water heater. Batch heaters are simply water tanks heated directly by the sun. Normally they are mounted in a sealed enclosure to maximize temperature gain. I did not have enough room for an enclosure so mounted a couple of 30 gallon tanks, painted black, as high as possible on the back wall of the greenhouse. This is less efficient than putting them in an insulated box but any increase in water temperature reduces summer hot water cost. Water from the well varies from 45-55F during the year.  The electric water heater is set to 120 degrees. Just reaching normal summer daytime air temperature of 80-90 degrees reduces energy consumption by half.   An advantage of this arrangement is during winter the tanks provide an extra 60 gallons of thermal mass.

Domestic hot water is produced by a 55 gallon electric water heater located in the basement. Many years ago I augmented it with heat from our wood stove. I plumbed an insulated tank into the cold water feed to the electric heater and installed a heat exchanger in the stove plumbed to the preheat tank using a thermo siphon loop. Whenever the stove is in use it heats the water in the preheat tank. As hot water is used the “cold” water being feed into the electric water heater is warmer than the water coming directly from the well thus saving electricity.

The solar batch heater acts as a second preheater. When hot water is used cold well water flows through the two greenhouse tanks. Temperature rise depends on sun intensity and water usage. The hot output is plumbed into the cold inlet of the wood stove heater storage tank. Water from the wood stove tank flows into the electric water heater to bring it up to the desired temperature.   The wood stove tank can be bypassed but it is pretty well insulated so being lazy I typically just leave it in the system during the summer.

I was a little concerned all the extra plumbing and tanks would impact hot water flow rate but that has not been a problem.

A Pressure Temperature Relief Valve (PTRV) valve is plumbed into the “hot” tank. It dumps water if the tank overheats or experiences excessive pressure. If water is turned off to the greenhouse and the PTRV opens there is a possibility of creating a partial vacuum when it cools, potentially collapsing the tanks.  A vacuum breaker is installed on the pipe connecting the two tanks. It opens letting in air if the tanks are depressurized.

Since I needed to supply cold water to the batch heater it was a simple matter to extend the cold water feed to a ¼ turn hose bib. I made up a short section of garden hose to water greenhouse plants. Any excess water runs down the stone floor.   To keep dirt from clogging the stone we stretched filter fabric over the stone. This allows water to drain but prevents dirt from getting into the rock.

During heavy ice and snow storms we can experience extended power outage lasting several days. Without electricity we lose well water and obviously the controller no longer functions. The system is designed to be easy to drain. Pipes slope toward drain valves and the tanks can be emptied.

Three ball valves and two ¼ turn boiler drains, located in the basement, allow flexible control of the batch heater.  Three additional valves, located in the greenhouse, are used to drain the tanks.

·         Mode 1 during summer the bypass valve is closed and the feed and return valves open. This causes water to flow through the tanks as hot water is used.

·         Mode 2 during winter the bypass valve is open as is the feed valve, the return valve is closed. This bypasses the batch tanks but leaves water to the greenhouse turned on to water plants and provide additional thermal mass.

·         Mode 3 is used to drain the system. The bypass valve is open and feed and return valves closed. Two boiler drains allow air into the feed and return lies to the greenhouse so they can be purged. Three valves in the greenhouse let air into the system and drain the tanks. The tanks are higher than basement plumbing so they need to be emptied first before letting air into the basement feed pipes or water will back up into the basement.

Water heating is completely passive the controller is not involved except to monitor temperature. I dedicated four of the eight temperature channels to monitor the hot water system.

v  Well pressure tank

v  Solar batch heater hot outlet temperature

v  Wood heat storage tank hot outlet

v  Electric water heater hot outlet

With the exception of the solar batch heater the temperature sensors are attached to the outside of the respective pipe. With the batch heater I had an unused fitting so was able to locate the temperature sensor in direct contact with water. Temperature accuracy is affected by water usage. Temperature reading is more accurate if water is following through the pipe. If water has not been used for a while the reading is somewhere between tank internal temperature and ambient air temperate.


The controller is used to control lighting. This allowed me to run low voltage wiring to light switches located by each door. As a plus the web interface allows lights to be turned on/off by remote control. Pretty cool, how many greenhouse let you turn the lights on or off from a web page? The switches are SPDT momentary contact.  The controller latches the last switch state to turn lights on or off. Being monetary contact allows an unlimited number of switches to be used in parallel.

Two Leviton CFL fixtures are mounted on the ridge beam between the two roof pitches. The fixtures are not waterproof so I was careful to mount them in the middle of the polycarbonate panels. For extra water protection cut circular section of automotive gasket material and placed it between the fixture and plastic electrical box.  They are not intended as grow lights just used to provide general purpose lighting.

Switched Receptacles

There are thee duplex receptacles on the south wall and two on the north. I split the outlet so the left side is constantly on and the right one is controlled by the PLC. I have not implemented PLC code for the outlets. At present the switched outlets are controlled by the manual override toggle switch on the controller panel.


The controller supports multiple temperature sensors and a Honeywell solid state humidity sensor. In addition two of the digital inputs are used to monitor the external entry door and the door covering the basement fan.


The controller implements the Maxim/Dallas 1-wire protocol and supports up to 8 DS18B20 temperature sensors.  1-wire is a single line wired OR bidirectional communication protocol.  This supports multiple sensors over only three connections: 5 volts, ground and data. Most of the sensors are mounted in the metal tip of a flexible cable assembly. The exception is the two ambient air sensors (controller and display). They are located in a small ventilated chassis on the South wall protected from direct sunlight.  The sensors output temperature in digital format and are all powered from the controller’s 5v supply.

Currently 7 of the 8 channels are used:

1.       Outside air

2.       Inside air (a 2nd dedicated sensor drives the controller’s digital temperature readout)

3.       Water barrel storage

4.       Not used

5.       Well water

6.       Solar batch preheater

7.       Wood stove preheater

8.       Electric water heater


Outside Air

The outside air sensor is located on the North wall of the house to provide outdoor temperature readings. This required running a cable from the greenhouse at the front of the house to the North wall at the back. Mounting was an issue as I needed the probe to measure outside air temperature but not be easily damaged. The ideal location for highest accuracy is several feet above the ground and away from the building. That was impractical so the sensor is mounted a couple of feet above grade. To protect the sensor I used a small plastic pet food dish. The sensor is mounted through a hole in the center of the base.  This allows air flow around the sensor while keeping it behind the edge of the building.

Greenhouse Air

The greenhouse air temperature sensor is located in a small ventilated box located on the South wall of the greenhouse. This location keeps it out of direct sunlight for more accurate air temperature readings. The humidity sensor is also located in this box as well as a terminal block if we need a cabled sensor at that location.

I wanted to display greenhouse air temperature on the controller but unfortunately the unit does not provide a way to drive a locally attached display. To work around this limitation I installed another 1-wire temperate sensor near the one used by the controller and mounted a standalone digital thermometer in the controller chassis. The close proximity insures both sensors accurately track temperature. The 1-wire protocol is an open collector master slave. This allows both controller and display sensors to be powered by the controller. Only the data line from each sensor needs to be kept separate and routed to the respective device. 

Water Thermal Mass

To track the temperature of the water barrels I connected a 1-wire sensor and dropped it into the drum through a hole in the bung cap.

Domestic Hot Water

Four of the eight sensor channels are used to monitor the hot water system.


The controller uses a Honeywell HIH-4000 sensor to measure relative humidity. This is an analog device powered from the controller’s 5V supply. The humidity sensor is mounted in the same chassis used for the temperature sensors. Being analog I wanted to make sure accuracy was not affected by digital noise generated by the temperature sensors so I ran separate power, ground, and data to the humidity sensor.

Door Monitoring

Magnetic reed witches are used to monitor the status of the main entrance door and the basement fan door.


No automation system is complete without alarm notification of dangerous or improper operating conditions. WebControl allows up to 8 preconfigured emails to be dispatched by user code.

Freeze Warning

The point of having a greenhouse is to extend the growing season by keeping air temperature above freezing. If the water, rock storage and basement augmentation functions are not adequate to maintain air temperature the controller flashes a freeze warning LED on the front panel and sends a warning email. A pushbutton on the controller resets the alarm. If the freeze warning is reset but temperature is still below the warning set point the LED is turned off for a couple of seconds and another freeze warning sequence begun.

A freeze event is likely to occur in the wee dark hours of the morning when no one is logged into their computer so some other alert method is needed. The success of the greenhouse project encouraged me to design a second generation wood heat controller using the same PLC I used for the greenhouse. The wood heat controller has an audible alarm that is trigged during overtemp conditions so it was a natural to allow the Greenhouse controller to use it for freeze notification. The 1-wire temperature sensors use three wires (power, ground, data). I wired the in house temp sensors with 4-wire telephone cable I had laying around so used the 4th wire to communicate freeze warning to the wood heat controller. During a freeze even the controller pulls this line low activating an optocoupler in the wood heat controller.

Basements Fan Door Closed

When the controller needs to turn on the basement fan it reads the state of the fan door closed switch. If the door is closed it flashes the basement fan status LED and sends a warning email.

Temperature Sensor Failure

If one or more sensors fail a notification email is sent. There was a bug in the original firmware I used that interferes with sensor failure monitoring on the last two sensors. This has been fixed in current firmware. It takes several seconds at boot time for the controller to initialize the temperate sensors. Testing is delayed when system powers up to eliminate spurious fault notification. The 1-wire bus is a wired OR open collector scheme. It is sensitive to noise ingress causing temporary failure of one or more sensors. To guard against unnecessary alerts sensor fault notification is debounced. When the controller reports a failed sensor a counter is set to 100. If the sensor is still bad after 100 passes through user code (about 5 seconds) the alert email is generated, if not the counter is cleared.

Once an alert has been sent sensors must return to the OK state to reset the warning. That way only a single email is sent per failure event.

Daily Status Email

The controller’s web interface is pretty limited and does not include logging capability. I added code to send out a morning and evening email.  The body of the email includes digital input and output status and current temperate sensor and humidity sensor readings. Currently this is set for 6AM and 6PM. The firmware does not compensate for daylight savings time but in this case that is actually a plus since the report occurs at the same “Sun” time throughout the year.


Text Box: GREENHOUSE     Sent at: 18:00:00 On the 02/07/2013

Digital Inputs:
I1=0 I2=0 I3=1 I4=0 I5=0 I6=0 I7=0 I8=0 

Counter VARs:
VAR1=970 VAR2=0 VAR3=0 VAR4=636 VAR5=399 VAR6=6 VAR7=100 VAR8=1 

Analog Inputs:
AIP1=2 AIP2=0 AIP3=0 AIP5=0 AIP6=0 AIP7=0 AIP8=0 

Temperature Sensors:
T1=28.2dF T2=50.1dF T3=50.7dF T4=unbound T5=45.6dF T6=60.8dF T7=100.9dF T8=122.3dF 

Humidity Sensor:

TTL Output States:
TTL1=1 TTL2=0 TTL3=1 TTL4=0 TTL5=0 TTL6=0 TTL7=0 TTL8=0












Min/Max Temperature Logger

The daily email feature has turned out to be pretty handy. I added code to log the minimum and maximum temperature between each email and report is in VAR4, max and VAR5, min.

Initially I had a problem getting the email to report history property. I triggered the email and then reset min/max temperature to current temp for the next 12-hour cycle.  The email always reported the reset value never the previous 12-hour history. In debugging discovered there is a lengthy delay between requesting email and it being sent.  I assume system code logs into the SMTP mail server first then it builds the email record and sends it. When sending an email a loop counter is set to 1,000. When count expires code assumes email has been sent and resets the temperate logger to current values for the next cycle.

User code is executed approximately every 50ms. I assume that varies with system code and user code workload. Setting the loop counter to 1000 gives the system approximately 50 seconds to send the email. During that period min/max extremes are not being captured, since we are measuring slowly changing temperature is of no importance. In my case it typically takes about 1.5 seconds to send the email.

UROM Bounds Check

The General Setup screen is a convenient way to change set points without the need to reload code. Unfortunately variable title and units of measurement cannot be configured.  To make setting user defined values more user friendly firmware checks for changes to UROM and sends an inbound or out of bound informational email. If the unit is power cycled and any UROM value is out of bounds an email is also sent.










System Implementation

The controller is mounted on the east wall near the rear of the greenhouse. The temperate and humidity sensors are mounted on the south wall in a small salvaged ventilated box. The Humidity control exhaust fan is mounted to the immediate right of the controller.



The controller is built into an 11” square electrical box.  I installed an aluminum separator between line and low voltage compartment. The bottom section contains solid state relays to control AC loads. Initially I used SSRs to control all loads but ran into a problem with the CFL ceiling lights. The CFLs draw so little current the snubber circuit used to protect the SSR output passed enough current to cause the lights to occasionally flash.  The solution was to replace the ceiling light SSR with an EMR. I mounted a small relay on perf board cut to the same size as the SSR and wired a diode across the coil.  The 7407 driver is able to control the relay directly so it made for a simple replacement.  A flexible plastic shield protects low voltage relay control wiring from accidental contact with mains voltage.

The top portion has an 18-position terminal strip to connect low voltage field wiring; an Ethernet jack links the controller to our home network. A 9V 1A DC “wall wart” style switching power supply powers the system.

The controller, interface PCB, override switches, status LEDs and temperature display are mounted on the hinged front panel. The humidity fan DC switching circuitry is mounted on small board attached to the fan toggle switch and LED. This minimizes interconnect between front panel and logic board and kept high current fan load off the interface board.

WebControl PLC

The heart of the system is a low cost web server and programmable logic controller manufactured by CAI networks and available, like many of the other items used in this project, from eBay vendors.

The controller was primarily designed to monitor and control temperature in a data center environment, but its low cost and PLC capability made it ideal for my purpose.




WebControl Features

1.       8 1-wire temperature sensors inputs

2.       Humidity sensor input.

3.       8 digital outputs

4.       8 digital inputs

5.       3 analog inputs (expandable to 7) (not used in our implementation)

6.       UTP 10/100 Ethernet port

7.       Web server

8.       Programmable logic controller

9.       Real Time Clock (RTC) synced via Network Time Protocol (NTP)

10.   Low power

Interface PCB

I designed a simple interface board to provide external logic functions and ESD protection. The control panel has toggle switches to select how the various outputs are controlled. Each output except lighting can be set to Off, On, or Auto. Normally switch overrides like this would be read by the controller and processed in software. However since there are only 8 inputs and 8 outputs I needed to implement these functions in hardwired logic.

I wanted the Freeze warning LED and Basement fan LED to flash when there is a problem. To eliminate the need to create time dependent PLC code I implemented the flash function in hardware.  The controller has a status LED that flashes’ indicating the controller is alive. That signal is brought into the interface board to flash the appropriate LEDs.

The other function of the interface board is to protect the controller from ESD damage. I would much rather replace a SSI DIP TTL chip on the interface board then the entire controller. The protection scheme is pretty basic. Digital inputs are feed through a series resistor then to a pull-up.   The output of the pull-up is clamped to Vcc and Ground by a pair of diodes. The 1-wire interface to the controller and display are bidirectional so I used the clamp diodes but not the series or pull-up resistor. The humidity sensor is run barefoot. Being an analog signal did not want to risk affecting accuracy. I did not add protection to outputs as they do not leave the chassis.

Temperature Display

I wanted to display air temperature locally, but the controller does not have the ability to drive a display. I purchased a self-contained LED thermometer module.  I chose a unit that uses the same 1-wire temperature sensor as the WebControl and located it in the same box as the controller’s temperature and humidity sensors. Using two sensors for the same reading is not ideal since tolerances may cause measurement to may vary slightly but they will be close enough for our purposes.  As a plus the LED provides a nice night light and confirmation the controller is powered up.

AC Power

The greenhouse is powered by a dedicated 20 Amp 120 volt circuit protected by a GFCI. This is an important safety consideration given the close proximity of electricity and water.  I choose to use a GFCI circuit breaker rather than GFCI outlet because I wanted to split each receptacle into a switched and unswitched side.

Since the unit is powered 24/7 power consumption is important. I chose a “wall wart” style 9 volt 1 amp DC switching supply. The supply is mounted on the divider panel between low voltage and line voltage compartments.  It powers the WebControl, digital display, and interface board.

The National Electrical Code (NEC) requires water protection both when receptacle is both in use and not in use.  With the exception of the twist-lock receptacle used to power the ceiling vent fan outlets have a plastic protective cover.

PVC conduit protects exposed wiring on the east, south, and west walls.  Plastic conduit is inexpensive, does not rust, provides mechanical and water protection of exposed wiring. The north wall separating the basement from greenhouse is an insulated stud wall. Wiring in that wall is NMC cable. 

DC Power

The 9V 1A switching power supply output is connected to the low voltage field wiring terminal strip. It plugs into a receptacle located on the LV mains separator bracket.  9 volts is feed directly to SSR control inputs, front panel LEDs, humidity fan, and the front panel temperature display. To minimize power dissipation of the controller’s 5 volt linear voltage regulator added a series diode to reduce the supply voltage a little.

The PLC, interface PCB, SSRs, and LEDs draw 220 -250ma from the 9 volt supply. The humidity fan draws 500ms. The switching supply is very efficient minimizing waste heat dumped into the enclosure.


I used two Cat5e cables to interconnect the various sensors. The preferred topology for 1-wire devices is a daisy chain. A daisy chain minimizes the negative effects of reflections due to the unterminated nature of the bus.  Temperature sensors are located both in the greenhouse and the house. Within the greenhouse I looped the sensor cable to all the locations that require temperature sensors, or other inputs, and then back to the controller. This allowed me to terminate both ends of the cable within the controller. This provides several benefits. One end of the 1-wire temperature data lead is terminated at the PLC the other end is extended into the house along with power and ground to power those sensors, maintaining the optimum daisy chain configuration through both wire segments. I terminated both ends of greenhouse cable’s power and ground conductors effectively doubling the wire gauge, reducing voltage drop. Currently I’m only using 7 of the 8 wires in the loop cable, having access to both ends of the cable means if I need to add more than one new input or output I can cut the loop to allow switches and sensor to feed one end or the other. The loop also provides some measure of fault tolerance.

A single 8 wire cable does not have enough conductors to connect everything so I ran a second Cat5e cable from the controller to the sensor box. This cable provides point to point wiring for the display temperature sensor and the humidity senor.

Two Cat5e cables provide dual Ethernet LAN drops, only one of which is being used. These cables connect to an Ethernet patch panel within the house. Lastly another cable is used to connect temperature sensors located within the house. This is an 18-gauge 4-wire cable I had laying around. The outside air temp, well water temp, the wood stove and electric water heater temp sensors as wells as freeze warning are connected to this cable. 

Maxim/Dallas 1-wire application notes provide recommendations to deal with signaling problems over long networks.  Even though total cable length is about 35 meters the system operates flawlessly without needing any of those tweaks. By 1-wire standards this is a medium sized network.

Web Interface

The web interface is primitive at best but gets the job done.

System Status page displays inputs and outputs as well as 8-varables used by the code. Being able to display values facilitates troubling shooting. VARs 1 & 7 are loop counters to add time delay to email and temp sensor monitoring respectively. VAR 4 is high air temperate since last email, VAR 5 same for low.  VAR 6 is used to track the next hour to send daily email update.  The controller has another 8 variables (RAM) accessible to user code but they are not displayable.

The screenshot (old FW) is a winter day when the wood stove is operating.  Sensor 1 measures outside air temperature. Sensor 2 is air temperature within the greenhouse and sensor 3 is the temperature of one of the water barrels. Temperature sensor 5 is the well pressure tank; ground water temperature varies little throughout the year. Sensor 6 is the hot outlet of the batch solar water heater. Temperature sensor 7 is the thermo siphon storage tank plumbed to the wood stove. Sensor 8 is the electric water heater. The water heater thermostat is set to 120 F. Because the sensor is attached to the hot water outlet pipe, rather than being immersed in water, the reading varies significantly depending if hot water has been used recently. The screenshot shows higher then set point reading indicating hot water has been used recently and water from preheat tank was greater than 120 degrees.

Modifying Set Points

The controller’s General Setup page allows 4 values to be set from the web interface. These are used as inputs by the PLC code to change temperature set points without the need to modify and reload code. The PLC operates on temperature in .1 degree increments; therefor to set 82.0 degrees need to enter 820. Humidity is set in 1% increments.

Ø  UROM1 – Ceiling fan on inside temperature

Ø  UROM2 – Rock fan on outside temperature

Ø  UROM3 – Basement fan on inside temperature

Ø  UROM4 – Humidity fan on relative humidity

To-do List

I’m very pleased with the results but as typical with projects have no shortage of ideas for future modifications.

1)      I plan to add another temperature sensor embedded into the stone floor to monitor its temperature.

2)      Better status communication with wood heat controller. Currently the wood heat controller reports greenhouse controller health status based on the presence of 5V on the temp sensor lead.  The firmware I’m now using on both systems enables IP based communication between the controllers. Taking advantage of this will improve heath reporting. 


This has been a fun project and has greatly improved the performance of our greenhouse.

For anyone considering this type of project it is important to think about life cycle issues. The greenhouse structure and wiring have an extremely long life expectancy compared to the individual electronic modules. Think about how to handle a module failure 5 or 10 years down the road. Perhaps it is the packrat in me but given the inexpensive nature of the major components I’ve purchases spares that can be placed in service without mechanical, electrical, or software modification in the event of failure.  


Appendix A Schematics

Chassis Wiring

A 16-position DIP plug connects the interface board to sensor inputs and SSR DC control. Power and ground use 22 AWG wire to minimize voltage drop. Temp 5V is obtained from the PLC and used to power the PLC and display temperature sensors.  Power and ground for the humidity sensor is connected directly to the PLC to minimize digital noise pickup.

A .5 amp fuse limits fault current to the 9 volt power supply.


Front Panel Wiring

Front panel wiring picks up all the switches and LEDs in addition to the 1-wire temperature display module. The power switching circuitry for the humidity fan is located on a small perf board mounted to the rear of the fan toggle switch and status LED. FET low side switch is used to minimize fan voltage drop. Fan is rated for 12 volts but operates fine at 9, with obviously lower air flow. 


PLC Wiring

Two ribbon cables connect the PLC to the Interface board. A 16-pin header to header cable connects analog and digital inputs. Note: the PLC number’s the header sequentially. Conventional practice is to alternate pin numbers on ribbon cable headers so numbers are sequential across the cable. The other cable terminates at small barrier strips. The flash lead is soldered to the flashing health LED on the PLC.

5V for temp sensors is picked up directly from the controller and routed to the terminal strip to minimize noise pickup. 


Interface PCB – Logic

The Interface board is the central interconnect between the various portions of the controller and provides simple hardware logic and ESD protection. The PLC interface consists of a 16 and 20 pin header. Front panel wiring terminates to a 20-pin header providing lots of spares. And lastly a 16-pin DIP plug connects to the LV terminal board and SSR control.


Interface PCB – Switch Conditioning

This page shows switch conditioning and termination of unused spare gates.


Sensor Wiring

The loop cable originates at the controller and travels along all four greenhouse walls then returns to the controller. Loop wiring is routed through the light switches by each entrance door and connected to the magnetic door sensors. A four conductor cable connects the 1-wire temperature sensors in the house and provides freeze notification to the wood heat controller.

At various locations I installed 4-postion terminal bocks (old style telephone 42A junction blocks) to facilitate adding additional temperature sensors.

A small ventilated chassis is located on the western end of the south wall. It houses two temperature sensors, the humidity sensor and a 4-position terminal block to allow attachment of an additional cabled temperature sensor.

The point to point cable originates at the controller, runs across the south wall of the greenhouse and terminates at the ventilated chassis. The display temperature sensor and the controller humidity sensor use this cable.


Appendix B PLC code


Greenhouse Controller

T. Schmidt


*********** Change Log *********************

7/7/2013            Added range check to UROM values, email sent after each value

                        change indicating in range or out of range.

                        indicating out of range or in range.


7/5/2013            1) Added powerup init delay for temp sensor

                        2) Fixed bug if temp sensor bad at powerup no email sent.

                        3) Fixed logger bug does not report min temp first cycle

                           after boot

                        4) Cleaned up humidity code

                        5) Replaced failed water drum temp sensor - T3


7/2/2013            Reinstalled controller

                        1) Using OP7 for humidity fan

                        2) Temp status fixed now testing all temp sensors

                        3) Changed logic state of freeze reset push button


7/1/2013            Modified hardware

                        1) Replaced freeze warning PB LS04 with 7407 to reuse inverter.

                        2) Added OP7 DC humidity fan control circuitry

                        3) Added freeze warning output to wood stove controller

                        4) Added TVS to 9v input


6/29/2013          WebControl PCB returned with updated firmware, 3.2.17d.


6/17/2013          Replaced light SSR with EMR to resolve problem with SSR

                        snubber causing CFLs to occasionally flash. Added gasket

                        to both ceiling CFLs to prevent water ingress.


3/21/2013          CAI Networks confirmed temp status bug. I submitted another

                        bug report developing wood heat controller. Same bug they

                        thought they fixed before. Confirmed temp status bits working

                        in FW version 3.2.17b.


1/5/2013            email does not report min/max temperature correctly, always

                        report current value. Unclear when email is sent relative to

                        user code request. Modified routine so temp reset to current

                        value is delayed Approx. 5 seconds after requesting email.

                        Looks like it takes about 1.5 seconds to send email. Assume

                        system code logs into SMTP server before creating email text



                        Added Hi temp logging in addition to low temp.


                        Changed bad sensor debounce to minimize spurious email.


1/4/2013            Added low temperature logging to morning and evening email.

                        Lowest temp since last email reported in VAR5. Moved


12/5/2012          Added humidity control exhaust fan. Small DC 100 cfm muffin

                        fan exhausting through high quality dryer vent. Temporarily

                        used switched AC outlet channel. Need to update hardware in

                        summer with FET controlled DC Fan power to free up outlets

                        for other use.


10/30/2012        Installed


9/26/2012          Temp status does not report Temp sensors 7/8 correctly.

                        Submitted bug report to CAI Networks, stated 3.2.11 FW is a

                        year old and that bug is fixed in ver 3.2.12, current FW is

                        3.2.15. Cost $15 to upgrade. Choose not to upgrade at this



6/25/2012          Code start


2/7/12               Project start



*************** PCB Hardware/Firmware version ****************

Hardware: 2.2.2

Firmware: 3.2.17d 


Customer loop executed every ~50ms

Email takes about 1.5 sec to send.

Per CAI Support Temp sensors take up to 2 sec to stablize at power up


9V power consumption:

            WebControl + interface 220-250ma

            Humidity fan: 500ma


***************** I/O Defs **********************



Analog Inputs


AIP1 - not used

AIP2 - not used

AIP3 - not used


Digital Inputs


IP1 - Light_on

IP2 - Light_off

IP3 - Ent_Dr_closed

IP4 - Bsmt_fan_dr_closed

IP5 - Spare_input

IP6 - /Freeze_pushbutton

IP7 - not used

IP8 - not used


Digital Outputs


OP1 - Rock_fan

OP2 - Ceiling_fan

OP3 - Outlets

OP4 - Basement_fan

OP5 - Light

OP6 - Freeze_warning

OP7 - Humidity_fan

OP8 - not used


Temperature Sensors


T1 - Outside_air (house Northeast corner)

T2 - Inside_air (GH southwest corner)

T3 - Water_drum (north wall east of door)

T4 - not used

T5 - Incoming_well_water

T6 - Solar_water_storage (east tank)

T7 - Wood_water_storage

T8 - Electric_water_heater


Temp Sensor status (1 = OK)











Humidity Sensor (GH southwest corner)




Email message Identifiers


EM1 - Freeze Warning

EM2 - Bsmt fan door closed

EM3 - Sensor failure

EM4 - UROM out of normal range

EM5 - UROM in normal range

EM6 -

EM7 - Morning daily status email (6AM)

EM8 - Evening daily status email (6PM)




VAR1 - Email delay state: 0=set min/max temp to current, 1-1000=temp reset delay, 1001 email sent

VAR2 - Sum previous UROM values. If match no email sent.

VAR3 -

VAR4 - High Temp since last status email

VAR5 - Low Temp since last status email

VAR6 - Status email next time flag 6AM and 6PM

VAR7 - Bad Sensor state: 0=send email, 1-100 debounce, 101=email sent

VAR8 -




RAM1 - Scratch: Temp status, fan hysteresis  

RAM2 - Basement fan door email once per occurrence

RAM3 -

RAM4 -

RAM5 -

RAM6 -

RAM7 -

RAM8 - Powerup init flag


Web constants


UROM1 - Ceiling fan on inside temp (.1 degree F increments 750-950)     (85F/83F)

UROM2 - Rock fan on outside temp (.1 degree F increments 350-600)      (43F/45F)

UROM3 - Basement fan on inside temp (.1 degree F increments 350-600) (45F/47F)

UROM4 - Humidity exhaust fan in inside RH (1% RH increments 60-90)    (75%/73%)





            Tracks UROM values. Whenever value changes upper and lower bound for each is

            tested and "in bound" or "out of bound" email sent. Runs before GHINIT, to

            suppress in bound email on powerup. At power up only out of bound email sent.

            Values are checked but FW does not override user entered value.


            NOTE: if one value is decreased by same amount another increased, sum does not

            change so email is not sent.


            Runs once at power up. Delay for temp sensors to stablise and sets RAM8 flag


            Ceiling light control, latches last state of door pushbuttons


            Ceiling exhaust fan, controlled by inside air temp


            Rock storage blower, controlled by outside air temp. Overridden if basement

            fan on. No reason to attempt to store heat in rock floor if we are blowing

            air in from the basement.


            Basement fan blows air in from basement if inside air too low. If fan

            door is closed, LED blinks and email warning sent.


            If inside temp drops dangerously low, email sent and wood stove controller

            activated to sound audible alert. Push button used to reset alarm. When reset

            attempted delay causes LED to flash off momentarily if reset while inside temp

            still too low.


            If outside temp low enough and inside temp within min/max and humidity high

            small exhaust fan on.


            Monitors health status of 1-wire temp sensors, email sent on bad sensor


            Min/max temperature logged. Status email sent 6AM and 6PM every day.



******************* Code *************************



            CALLSUB         RANGECHK

            TSTEQ              RAM8 0

            CALLSUB         GHINIT

            CALLSUB         LIGHT

            CALLSUB         CEILING

            TSTEQ              OP4 0  

            CALLSUB         ROCK

            CALLSUB         BSMT

            CALLSUB         FREEZE

            CALLSUB         HUMFAN

            CALLSUB         SENSOR

            CALLSUB         EMSTATUS




            SET      RAM1 UROM1

            ADD     UROM2 RAM1 RAM1

            ADD     UROM3 RAM1 RAM1

            ADD     UROM4 RAM1 RAM1

            TSTEQ  VAR2 RAM1



            SET      VAR2 RAM1

            TSTLT   UROM1 750

            GOTO   BADUROM

            TSTGT  UROM1 950

            GOTO   BADUROM

            TSTLT   UROM2 350

            GOTO   BADUROM

            TSTGT  UROM2 600

            GOTO   BADUROM

            TSTLT   UROM3 350

            GOTO   BADUROM

            TSTGT  UROM3 600

            GOTO   BADUROM

            TSTLT   UROM4 60

            GOTO   BADUROM

            TSTGT  UROM4 90

            GOTO   BADUROM

            TSTEQ  RAM8 0



            EMAIL  EM5




            EMAIL  EM4




            SET      RAM8 1

            SET      VAR7 100

            DELAY 3000




            TSTEQ  IP1 1

            SET      OP5 1

            TSTEQ  IP2 1

            SET      OP5 0




            TSTGE  T2 UROM1

            SET      OP2 1

            SUB     UROM1 20 RAM1         

            TSTLE  T2 RAM1

            SET      OP2 0




            TSTLE  T1 UROM2

            SET      OP1 1

            ADD     UROM2 20 RAM1         

            TSTGE  T1 RAM1

            SET      OP1 0




            TSTLE  T2 UROM3

            CALLSUB         REALCOLD

            ADD     UROM3 20 RAM1         

            TSTLE  T2 RAM1



            SET      OP4 0

            SET      RAM2 0




            SET      OP4 1

            TSTEQ  IP4 0    

            SET      OP1 0

            TSTEQ  IP4 0



            TSTEQ  RAM2 0

            EMAIL  EM2

            SET      RAM2 1

            SET      OP1 1  





            TSTLE  T2 360

            CALLSUB         NEWFREEZE

            TSTEQ  IP6 0

            SET      OP6 0




            TSTEQ  OP6 1



            DELAY 2000

            SET      OP6 1  

            EMAIL  EM1




            TSTGE  T1 700

            GOTO   HUMOFF

            TSTEQ  OP2 1

            GOTO   HUMOFF

            ADD     UROM3 50 RAM1

            TSTLE  T2 RAM1

            GOTO   HUMOFF

            SUB     UROM4 2 RAM1           

            TSTLE  H1 RAM1

            GOTO   HUMOFF

            TSTGE  H1 UROM4

            SET      OP7 1




            SET      OP7 0





            AND     TS1 TS2 RAM1

            AND     TS3 RAM1 RAM1

            AND     TS5 RAM1 RAM1

            AND     TS6 RAM1 RAM1

            AND     TS7 RAM1 RAM1

            AND     TS8 RAM1 RAM1

            BZ        BADSENSOR

            SET      VAR7 100




            TSTEQ  VAR7 101


            DEC     VAR7

            TSTNE  VAR7 0




            EMAIL  EM3

            SET      VAR7 101





            TSTEQ  VAR1 0

            GOTO   NEWMINMAX

            TSTEQ  VAR1 1001

            GOTO   LOGGER         

            DEC     VAR1




            SET      VAR1 1001       

            SET      VAR4 T2

            SET      VAR5 T2




            TSTGT  T2 VAR4

            SET      VAR4 T2

            TSTLT   T2 VAR5

            SET      VAR5 T2

            TSTEQ  CH 6

            BNZ      MORNMAIL

            TSTEQ  CH 18

            BNZ      EVENMAIL       




            TSTEQ  VAR6 18



            EMAIL  EM7

            SET      VAR6 18

            SET      VAR1 1000




            TSTEQ  VAR6 6



            EMAIL  EM8

            SET      VAR6 6

            SET      VAR1 1000




******************* End **************************

Appendix C PLC Configuration

Screenshots of various WebControl configuration pages.



I/O setup page globally enables/disables PLC and individually enables output control on a bit by bit basis. This page is also used to define functionality of multipurpose I/O bits.



Notification page is used to set up email. Note current firmware is unable to use SSL to send mail.


Latest firmware allows email to be sent to multiple addresses and the body of the message customized.



At power up WebControl detects attached 1-wire temp sensors.  Sensors cannot be hot swapped. This page maps sensors and sets units.


WebControl defaults to static IP setting. During configuration DHCP can be left off and addresses manually configured or DHCP turned on for automatic configuration. If a different NTP time server is desired it can be specified on this page. Lastly for security access to WebControl can be limited to specific addresses.