You are on page 1of 13

Homebrew Solar Project

Home

This page describes a system for collecting hot water using hydronic solar panels (they
circulate antifreeze and have nothing to do with the collection of electricity). Collecting
heat with solar panels is several times more efficient than collecting electricity for a given
size of array.
The system uses two Atmega328s programmed using the Arduino IDE to process sensor
information to decide when it is appropriate to collect hot water from a rooftop hydronic (hot
water) solar array. If conditions are suitable, the pump runs. If too much household hot water is
collected (it rises above a temperature threshold), the solar-heated water is routed through the
basement hydronic slab, which is a great heat sink even in the summer time. Other features
include extensive logging (with timestamps) of data (maximums, minimums, various kinds of
events). There's also some logging of information from the oil-fired boiler, which hopefully will
allow me to tweak its settings for more optimized fuel savings.
I log every time the boiler turns on and the time it runs for, as well as the outdoor temperature
and the fuel level. Fuel level is determined using an ultrasonic rangefinder attached to the
controller's I2C bus. Since the rangefinder is 12 feet from the boiler room and at the end of a long
cable (which tends to make I2C flakey), I connect that part of the I2C bus via a 4016 CMOS quad
bilateral switch. This means that the only time a long cable is electrically attached to the I2C bus
is when I am attempting to read the fuel level (which only happens on the hour and every time
the boiler runs).
Behavior is different between season settings (winter and summer). In winter (generally four
months of the year), it just circulates hot water from the panels through the basement slab,
assuming the household boiler is heating hot water. In summer (generally eight months of the
year), it heats water using the sun, but if the water gets too hot, it sends water through the
basement slab. The system is smart enough to know that if the boiler kicks on, it's winter, and so
it changes the season setting automatically. If it's above freezing at night in certain months of the
year, it attempts summer mode once per night (which automatically resets to winter mode should
the boiler turn on).
Here's the block diagram.

Those who are curious might want to look at an early pre-Arduino solar sufficiency controller I
was using in 2005. It depended on flip flops, a ULN2003, a pair of comparators, and four
potentiometers to set analog cut-on and cut-off temperature values.
Next I'll illustrate the low-tech relay-and-switch-based circuitry, which is still in use to switch
120 volt circuits and send mid-voltage signals capable of opening and closing valves. It also has
rotary switches to manually select whether or not the oil burner should be a fallback heating
system for the two zones (slab and hot water). "Solar Panel Water Heater Sufficiency
Thermostat" is now actually controlled by the Atmega-based controller diagrammed above (from

pin 14 of the Master controller). "Solar Panel Slab Sufficiency Thermostat" is also controlled by
the Atmega-based controller diagrammed above (from pin 15 of the Master controller).

Here's the part of the electrical system describing how valves are opened and closed by the
preceding circuit:

Here's the hydrodynamic diagram:

Here's a video of me showcasing the LCD menu system:

Controller board (this was before I added the I2C expansion buses and the quad bilateral switch),
consisting of an Olimex 28-pin AVR development board and some generic expansion place (you
can never have too much of that). Note the blue switch, which allows me to connect either the
master or slave Atmega328 to the board's serial bus to program (or otherwise interact with)
remotely. I have to use serial instead of USB to communicate with this controller because it is
too far away from the computer for USB's limited range. The copper thing is a makeshift
heatsink I added to the 7805 voltage regulator. Eventually I transitioned to a regulated five-volt
supply, which is more energy efficient (the whole system, including LCD backlighting, uses less
than a watt). The connector in the upper left corner is where I plug in a DB-25 (old-style parallel
printer) port, which is how I run the various thermistor and control signals to and from my

controller. Just to the right of that are two brick-red connectors. This is where I plug in resistors
to form the other half of the voltage dividers that also include the thermistors. The value of the
resistors should be about the same as the mid-range value of the thermistors.

Controller board's wiring. I learned long ago that strain reliefs are essential for almost every end
of point-to-point wiring. You see them as little copper belt loops across the wires here and there.
Commands that can be sent to the controller via a serial terminal
? - Help
cb - Clear boiler log cursor (set it to zero).
ce - Clear extreme data (any data collected immediately afterward will be considered extreme).

cf - Clear "firing time" information for boiler.


ci - Clear forcing of solar insufficiency (forced solar insufficiency is used for debugging).
cv - Clear event log cursor (set it to zero).
d - Display byte value at the following EEPROM address of the Master (given in decimal)
db - Display the log of boiler activity.
dc - Display cursors for the logs (how far into the log they have progressed).
de - Display extremes of temperature, with dates, logged from several of the thermistors.
df - Display information about fuel use by the boiler.
dl - Display long value at the following EEPROM address of the Master (given in decimal)
dn - Display the number of seconds to be added to the real time clock weekly to minimize
drifting.
dr - Display the values of a number of important realtime variables.
ds - Display logs of 80 most recent morning beginnings of solar heat collection.
dt - Display the count of the number of times the boiler has fired for this tank of fuel.
dv - Display an event log (reboots, incidents of hydronic fluid too cold to flow, etc.).
fi - Force solar insufficiency (forced solar insufficiency is used for debugging).
gd - "Goad dog." Executes a 20 second delay to make the watchdog reboot the controller. Used
for debugging.
m - Show free memory.
rb - Reboot
sb - Set number of times boiler has fired.
sc - Set realtime clock with values in this order:
SECONDS,MINUTES,HOURS,DAYOFWEEK,DAY,MONTH,YEAR (no spaces, delimited by
commas).
sD - Set realtime clock date, with values delimited by dash: YY-MM-DD (use 2 digit year, Y2K
is over!).
sd - Set delay time before a change in thermistor readings leads to a change in collector behavior
(used to minimize too many on-off commands to the pumps and open/close commands to the
valves).
sf - Toggles the frozen state. Frozen means that the hydronic fluid is too cold to circulate. This
state is triggered automatically, sometimes erroneously. If so, it clears itself after an hour.
sm - Set minimum temperature (in degrees Fahrenheit) in the roof panel for collection to
commence in the summer season.
sn - Set the number of seconds to be added to the real time clock weekly to minimize drifting.
ss - Set season (1 is summer, 0 is winter). Season setting affects a number of behaviors. For
example, in the summer, the electromechanical thermostat on the hot water tank is bypassed and
maximum hot water temperature is instead handled by the sx setting (see below).
sT - Set realtime clock time, with values delimited by colon: HH:MM:SS (use 24 hour time, not
12 hour).
st - Set delay time of Master controller's loop (in tenths of a second, or deciseconds).
sW - Set day of week by integer (0 is Sunday).
sx - Set temperature (in degrees) of the maximum value for household hot water. Once that is
reached, solar-heated fluid is sent through the slab.
us - Update menu system on Slave with latest internal data on Master.
wb - Write a byte of Master EEPROM. First value is address, second value is decimal byte to
write.

wl - Write a long of Master EEPROM. First value is address, second value is decimal long to
write.
xf - Force a check of fuel levels.

Source code for both the slave


and the master Atmega328s:
Master/Slave Solar Controller Code (v2.0)
Other things you would need
to build/run this:
Ken Shirriff's IR Remote Library
optiboot (so the watchdog code will work).
(Be sure to replace optiboot_atmega328.hex with the green-backgrounded block of code on this
page, as optiboot has a rather serious bug that will occasionally throw your controller into a
reboot loop.)
electronic hardware I used
Atmega 328s (two)
Olimex 28 pin AVR development board
DS1307 realtime clock
24LC1025 EEPROM (two)
TSOP85 IR receiver on Sparkfun breakout board
SRF08 rangefinder module
20 by 4 character LCD
Various thermistors (10k and 100k values)
Questions? Answers? Job offers?
contact the author

You might also like