Introduction: 2nd Gen Arduino Hot Water Solar Collector Controller
I have a significant home hot water solar system and needed to replace aging system controllers. Commercially built replacements are available for $2-300 but are still old technology. I wanted something from this century and found a number of Arduino implementations of basic solar controllers on the web, including two Instructables - one from some guy in Lithuania: user alv001's Hot water solar collector controller with thermostat v1.2 and another from user Cbiblis Solar collector & Radiant heat controller. These were a great examples, but I wanted a what I refer to as a "second generation" solution, one that's got "IoT" so I could view temperatures and control pumps from a web page. And, I needed many other features as outlined below that I hadn't seen tackled yet.
With a full dozen 1970's era copper plate, glass enclosed panels and 1000 gallons of hot water storage, my home has one of the larger homeowner maintained hot water collection systems to have been in continuous operation since installation in 1972. This system has 3 pump circuits that need to be controlled:
- a collector circuit to drive the Panel-to-Storage pumps
- a circulation pump to extract stored heat for DHW (domestic hot water)
- a circulation pump to extract stored heat for house heat
After living with this system for many years, I knew it was complicated enough that the simple minded controllers worked, but were very approximate in terms of really getting the most out of it. In looking at an update, one of the biggest problems is accurately measuring temperatures at many points in the system. Most of the existing Arduino solar controllers I found use what is to me, an amazing technology - the Dallas Semi one-bus digital thermometer (DS18B20) - it is really inexpensive, really accurate and incredibly easy to use. Unfortunately you can't put them inside solar panels which sit idle in the summer, as they reach temperatures far beyond what these things are able to tolerate. Modern high temp sensor applications use pt1000 or pt100 thermistors so I wanted to read these with the Arduino's A-D inputs. Further, my system already has older style 10k thermistors installed everywhere, so I wanted to be able to read those as well so I could install the system and then gradually change them out with newer technology.
I outlined what I really wanted to deal with this big mess and came up with a list of goals for this project.
First I needed all the sensor inputs I would encounter:
- Read pt1000 analog RTD sensor for measuring solar panels that can get too hot for digital sensors
- Read old-style 10k Thermistors to accommodate existing equipment (i.e. sensors deep in storage tank)
- Read DS18B20 1-wire bus digital sensors for all other temps - cheapest, simplest and most accurate
- Connect any sensor to any function easily
Other functions I needed for a solution for this system:
- Control a secondary extraction circuit pump for domestic hot water
- Control a third extraction pump circuit for forced air heat exchanger
- Alarm out and stop pumps when it is too cold outside, or when the storage is at a max hot level
- Use an LCD Display to display main system temperatures; use attached buttons to control operations with simple user input to manually switch pumps
- Control the main solar panel circuit pumps at 2 levels, reducing water flow as temperature delta decreases via lead and lag pumps (lets the system collect solar more efficiently)
- Publish Temperatures and Pump Status to a web page and provide the same pump control as available on LCD User interface
Ultimately, I want this Arduino to collect data periodically with a time-stamp and to display it in graphs on the web page so I can see what it is doing over time... but I haven't figured that part out yet (leave a comment if you have a recommendation for it). I'm posting now as it already works great!
Step 1: Put Together the Arduino Stack
I chose the Arduino Mega for this project so I'd have plenty of I/O and memory. That turned out to be a good decision for both those reasons and with all the I/O, it made the connections very convenient. On to that, I plugged a WizNet style Ethernet Module and on top of that, a DF Robot LCD display. I also wanted a digital clock module so I could eventually time-stamp data (right now, it just displays time on the web page) and for this installed a DS1307 RTC (Real Time Clock) module. And of course it needs power so I used a nice efficient switching style 9v wall-wart power supply.
I picked up these parts very inexpensively from GearBest.com (following are description, SKU and price):
- XD104 5V 4 Relay Module Shield for Arduino ARM PIC AVR DSP Electronic 125677201 $4.62
- LCD1602 Character LCD Keypad Shield V1.0 for Arduino DIY Projects 139528601 $3.97
- HCY - 6888 9V 1A AC / DC Power Supply Adapter 143495801 $3.46
- Arduino Compatible Mega 2560 R3 Microcontroller Board EC0365201 $10.75
- Ethernet Shield with Wiznet W5100 Ethernet Chip Support Micro SD Card NZ0000801 $8.65
- DS1307 Based RTC IIC / I2C Real Time Clock Module with Calendar NZ0016001 $2.50
In addition to these items I needed a mounting board (a simple piece of plywood worked fine), some miscellaneous screws and standoffs and a few minor components procured from eBay and listed in the next step.
Some notes about plugging all this stuff together I discovered as I was developing it :
During testing, each of the LCD and the Ethernet cards worked when plugged in separately but not as a stack until I discovered that the LDC backlight Control interferes with the Ethernet use of I/O pin 10 - so I bent that pin out of the way on the LCD which means it's always lit up (I hadn't planned on turning it off anyway and it makes a nice night light for the solar storage room too)
- I ran out of ground and power pins so I used the empty holes on the front of the LCD shield to access those lines covered up by the stack (visible in the photos - red and green wires)
- The stack also covered up Analog Reference which I wanted to use as the reference supply for all my analog sensor pull-ups (3rd pin over in the back row of the Mega) so I soldered a pin on the LCD for that as well (yellow wires)
- You can't plug an LCD shield onto an Ethernet shield without using pin extenders as the RJ-45 jack is too tall - I found long-legged female connectors to make this extension on ebay (shown in parts list next step).
- I was going to cable up the RTC until I discovered a hack somewhere on the web that showed how you can just plug it into pins 18-21 of the Mega (also visible in the photos). The DS pin hangs off the end (not needed) and you simply set the two power pins to be outputs one high and one low in software.
Step 2: Dealing With the Temperature Sensors
Connecting up, testing and figuring out how to read all the sensors I would be using was the biggest challenge on this project. The Dallas Semi digital sensors are really easy to use but still had to be hooked up conveniently. The thermistors needed to be read by the A-D's and there are a variety of amplifier and constant current solutions out there for this. Through using a calibrated digital thermometer and a lot of time with excel spreadsheets, I discovered that simple pull-up voltage divider circuits were good enough for both the pt1000 and the 10k sensors when appropriate curves are fitted (expressed finally in the Arduino Sketch that follows). Terminal blocks to easily attach each of the various sensors would be required.
Connections for all of this was achieved with really cheap and easy to solder up prototype boards. I did up schematics on Eagle Cad and could have fabricated real PCBs but it was so easy and inexpensive to simply hook it up on the proto boards using the sensor terminal blocks, a few resistors and pins, with a bit of wire and solder. One board was built up to accommodate 4 digital sensors and the pt1000. A second board was built up to connect 5 different 10k sensors.
The Arduino stack, the two sensor boards and a relay card to control the pumps (an XD104 5V 4 Relay Module Shield) were all screwed down onto a piece of plywood using small wood screws and 1/4" standoffs. Aside from the Arduino items listed in the previous step, the other bits and pieces needed for this came came from eBay and were shipped for free from China at unbelievably cheap prices - see the image for my parts list and what I payed.
Step 3: Wiring It Up
With most of the connections taken care of through plugging the Arudino assembly together, it was very easy to handle all the rest using ribbon cables with female pin connectors on each end that I found on eBay (listed on the previous step). 3 groups of wires handled the 10k sensor board, the Digital/pt1000 sensor board and the Relay board. Where I needed male ends to plug into the Mega, as can be seen in the photos, I simply used pins cut out of a right angle male header and used a 3pin chunk of male header shorted together to distribute analog reference. The selection of which Mega pins to be used for this were chosen for proximity to where they needed to go and ease of connecting the wires. The following lists are what I chose and what is expressed in the sketch.
Connections for the 10k sensor board were as follows:
- Mega pin A14 - A10k Sensor
- Mega pin A13 - B10k Sensor
- Mega pin A12 - C10k Sensor
- Mega pin A11 - D10k Sensor
- Mega pin A10 - E10k Sensor
- - nc
- Mega pin AREF - Analog Reference
Connections for the other sensor board were as follows:
- Ground - in from Mega
- Ground - out to 10k board
- - nc
- Mega pin AREF - Analog Reference
- Mega pin A15 - pt1000 Sensor
- Mega pin 47 - One Wire Bus for digital sensors
- - nc
- VCC - power from Mega for digital sensors
Connections to the relay card were as follows:
- Ground - in from Mega
- Mega pin 39 - relay 1 control (Panel Lead Pump)
- Mega pin 41 - relay 2 control (Panel Lag Pump)
- Mega pin 43 - relay 3 control (Hot Water Pump)
- Mega pin 45 - relay 4 control (House Heat Pump)
- VCC - power from Mega for relay card
Other than this list, of course the relays had to be connected to pumps and AC power and the terminal blocks had to be connected to the various sensors. I connected up extra sensors that happened to be available and display all values on the web page. A little software 'patch bay' provides a place to connect up which physical sensor I want to use for which function.
Step 4: Code It Up
The image for this step shows the web page output by the finished sketch in operation. Actual temps as measured and pump states as reported are shown. Note that the pt1000 and several digital sensors are not yet hooked up so report spurious values.
The software I wrote for this project is not the most elegant that's for sure, but it does work! Full disclosure: I'm an old guy who used to code 8 bit microprocessors in the late 1970's thus my skills are both rusty and behind the times. Plenty of bad practices throughout, like I used a lot of global variables rather than passing values because it was just plain easier for me. But at least the code is pretty well documented and straightforward so anyone reading through it should be able to modify it for their purposes.
I've divided it up into 3 parts.
- The basic sketch is the main loop that calls all the functions that need to happen periodically - make calls to check the button controls on the LCD display and to check the web page buttons, then to read analog temps, read the digital temps, see if any alarm conditions exist and finally update the LCD and serial monitor. Also in the basic sketch is a "patch bay" that lets me easily swap which sensor is reading what temperature.
- The Functions.h file has all the pin declarations, the settings for what temperature differentials and alarm values the system uses, and separate functions to do all the work. These are called one by one in the main loop to read buttons, update LCD, read sensors, detect alarm conditions and control the pumps.
- Finally, once I had everything working with the basic hardware, I added the web stuff which is all in the Ethernet.h file. NOTE: if you are going to use this, be sure to set your IP address appropriately for your network and use the MAC address on your Wiznet board if you have it.
I'm not going to go into detail on the code because it is pretty well self documented and not novel. If anyone has questions about any part of it, please ask and I'll be happy to help.
Once I had actually gone through the efforts of building and testing all this and had finally gotten it installed, I was confronted with the ultimate challenge of putting theory to practice. Power it all up and see if it works, which of course it doesn't. After troubleshooting a few issues, when it actually started displaying actual temperatures and running pumps appropriately, I have to say was a personal moment to remember (ok... I was whooping, jumping around and fist pumping in the solar room).
...and there you have it!
Step 5: Some Background
This isn't a step, just some additional info about the system.
There's a diagram of the basic electrical and hot water flow of the entire system. The next two photos are the old '70's era controllers that were in place before I replaced them - they were still working but were way off as to the actual temps they reported (the Arduino is spot on). I also included a photo of the new system going in during install, and a final photo as it currenty sits (the ladder leans against the 1000gal storage tank). If you really want to geek out, I've also included my meandering excel work figuring out how to read the analog sensors - there's lots of data on a variety of different thermistors on the various sheets.
I hope you have enjoyed reading about my journey into bringing a old solar system into the 21st century... and if you did, please vote for this project in the upper right corner!