• Requirement
  • Progress
  • Arduino Construction
  • Arduino Sketch
  • WLX-652
  • Raspberry Pi


THIS IS Work in progress.

Although the Solastat controller works perfectly well at controlling my Solar installation it does not do exactly what I would like so I thought I would make a list of requirements (below) and see if I could make my own controller.


1) Efficient use of Domestic Boiler and Electric Immersion heater and solar gain
I have a Oil fired boiler which heats the top two thirds of a 250 litre tank and an Electric immersion heater that heats the top third of the tank and the solar coil which heats all the tank, my electricity tarrif is economy 7 which means I get cheap electricty between the hours of 00:30 and 07:30 and by cheap I mean that it is currently less than the price of oil so it would be nice to input my electricty costs and have the controller pick the cheapest option.

2) Incorporate functionality:-
Diagnostics to ensure correct operation
etc, etc

3) Display the current temperatures and status on an LCD panel

4) Change parameters using a keypad

5) Perform 3 and 4 above with a web interface

5) Log statistics from the controller

6) Run as a stand alone Solar differential controller
By this I mean that in the absense of network connectivity; in this case no WLX652 or Raspberry Pi to function as purely aa a differential controller

7) Use industry standard 10k NTC thermistors
The reason for this is that my existing differential controller uses these and I did not want to have to run a second set of sensors, I intended to use an automated switch over so that in the absense of the new controller it defaults to my orginal controller without the need for swapping cables etc, this is just to make life easy for me during development.



THIS IS Work in progress.

Originally I decided on using an Arduino Uno; this relatively cheap (approx £10-20) and a WLX-652; I was using the WLX-652 as a torrent server before I upgraded to using a Raspberry Pi, both devices can connect to the usb port of the Arduino and when I first started thinking of adding network connectivity to the Arduino in 2009 it was more expensive than the Uno board I was connecting it up to but I purchased the W5100. I have since found a network sheilds for the Arduino have come down in price so I ordered a ENC28J60 (£3) to see which option gives me the functionality I need.

April 2013:-
Wrote basic code to:-
1) run diagnotics to make sure the sensors were working
2) operate the solar pump
3) display the status on the LCD Panel (on the I2C bus ( I used the I2C bus to keep the digital pins free for relays and ethernet sheild)

4) get the correct time from the RTC device

5) Add the ethernet shield to update COSM (a web site that allows you to feed logging info to and display graphs)


I used the W5100 as the COSM example sketch used the same libraries and the sketch in comparison to the ENC28J60 looked a lot simpler

Step 5 adding the ethernet in hindsite was a bridge to far the Uno locks up; I reduced my code to just updating the COSM site with my temperatures etc and it works fine, on further investigation I discovered I had ran out of memory to do all that I wanted, I was rather pushing it so I have ordered upa an Arduino Mega2560 for the princely sum of £11 from Hong Kong; all the shields I have purchased so are interchangeable between the Uno and the Mega2560 (In theory) so while I wait for it to arrvive, I will tidy up the code I have generated so far.


This is my first run and I wanted to get a time stamp of the temperatures so I combined and modified two sketches to check I was on the right track:-



* TimeSerial.pde
* example code illustrating Time library set through serial port messages.
* Messages consist of the letter T followed by ten digit time (as seconds since Jan 1 1970)
* you can send the text on the next line using Serial Monitor to set the clock to noon Jan 1 2010
* A Processing example sketch to automatically send the messages is inclided in the download

#include <Time.h>

#define TIME_MSG_LEN 11 // time sync to PC is HEADER followed by unix time_t as ten ascii digits
#define TIME_HEADER 'T' // Header tag for serial time sync message
#define TIME_REQUEST 7 // ASCII bell character requests a time sync message

#include <math.h>
// enumarating 3 major temperature scales
enum {

// manufacturer data for episco k164 10k thermistor
// simply delete this if you don't need it
// or use this idea to define your own thermistors
#define EPISCO_K164_10k 4300.0f,298.15f,10000.0f // B,T0,R0
#define ESI_EN3D103J_10k 3950.0f,298.15f,10000.0f // B,T0,R0

// Temperature function outputs float , the actual
// temperature
// Temperature function inputs
// 1.AnalogInputNumber - analog input to read from
// 2.OuputUnit - output in celsius, kelvin or fahrenheit
// 3.Thermistor B parameter - found in datasheet
// 4.Manufacturer T0 parameter - found in datasheet (kelvin)
// 5. Manufacturer R0 parameter - found in datasheet (ohms)
// 6. Your balance resistor resistance in ohms

float Temperature(int AnalogInputNumber,int OutputUnit,float B,float T0,float R0,float R_Balance)
float R,T;


switch(OutputUnit) {
case T_CELSIUS :

return T;

// Setup the Relay and intialize the temps
// this constant won't change:
const int pump_relay = 2;
const int imersion_relay = 3;
const int boiler_relay = 4;
// Variables will change:
float roof_temp = 0;
float inlet_temp = 0;
float tank_temp = 0;

void setup() {
setSyncProvider( requestSync); //set function to call when sync required
Serial.println("Waiting for sync message");
// initialize the relay pin as an output:
pinMode(pump_relay, OUTPUT);
pinMode(imersion_relay, OUTPUT);
pinMode(boiler_relay, OUTPUT);


void loop(){
roof_temp = Temperature(1,T_CELSIUS,ESI_EN3D103J_10k,10000.0f);
inlet_temp = Temperature(2,T_CELSIUS,ESI_EN3D103J_10k,10000.0f);
tank_temp = Temperature(3,T_CELSIUS,ESI_EN3D103J_10k,10000.0f);
SolarPump ();
if(Serial.available() )
if(timeStatus()!= timeNotSet)
digitalWrite(13,timeStatus() == timeSet); // on if synced, off if needs refresh

void SolarPump (){
if (roof_temp > (inlet_temp + 6))
digitalWrite(pump_relay, LOW); //Turn pump on
digitalWrite(pump_relay, HIGH); //Turn pump off

void digitalClockDisplay(){
// digital clock display of the time
Serial.print(" ");
Serial.print(" ");
Serial.print(" ");
Serial.print(" Roof: ");
Serial.print(" Inlet: ");
Serial.print(" Tank: ");
// Serial.println();

void printDigits(int digits){
// utility function for digital clock display: prints preceding colon and leading 0
if(digits < 10)

void processSyncMessage() {
// if time sync available from serial port, update time and return true
while(Serial.available() >= TIME_MSG_LEN ){ // time message consists of a header and ten ascii digits
char c = ;
if( c == TIME_HEADER ) {
time_t pctime = 0;
for(int i=0; i < TIME_MSG_LEN -1; i++){
c =;
if( c >= '0' && c <= '9'){
pctime = (10 * pctime) + (c - '0') ; // convert digits to a number
setTime(pctime); // Sync Arduino clock to the time received on the serial port

time_t requestSync()
return 0; // the time will be sent later in response to serial mesg






Arduino Uno Atmega328p

WLX-652 (snake os v1.3.2)
package chroot debian

Raspberry Pi Model B

Copyright © 2009 All Rights Reserved.