Monday 11 April 2016

Project: Heating timer/thermostat replacement with Arduino

This is something I've been planning on and off for many years now and finally managed to make a start on the planning and design of this.
(Sorry for the long wordy blog entry!)

The project goal is to have a system that runs alongside the original programmer (And can be removed without damaging/affecting the existing system) and will supplement it's operation with a more dynamic control system. By dynamic I mean, by taking temperature readings from the majority of rooms in the house, taking outdoor temperatures and by allowing remote devices (Smartphones) the ability to interact with it, we should have a smarter heating system, and in theory save money by only having heating and hot water on when we actually need it and not warm an empty house, or over-heat the house.

The downside to traditional heating systems: This is an easy one, most existing systems have one temperature sensor/thermostat, a timer and a boiler (We'll ignore the pump, valves, etc, as those are all semi-automated from the boiler itself). Since there is only one temperature sensor/thermostat then we 'assume' this is a good judge of the house temperature. If that room is warm or cold then it will influence the heat through the entire house. It also doesn't take into account the outside temperature, or whether the house is occupied or not. In addition to that the hot water is a 'set and guess' method. You set what times you think you'll need hot water (or more accurately 30 minutes before you want it) and then heat up the hot water tank and hope it holds heat long enough until you need it, otherwise the heat is wasted.

The improvement plan: To add a controller alongside the existing one. This one will take temperature readings from all over the house and outside and make a calculation based on the average temperature in the house and also the outside temperature. For example, if the outside temperature is 5oC and inside we're only on 18oC then we know it'll take the house longer to warm up, so bring the heating on at an earlier time that morning (Also checking if people are in the house, if not then don't bother).

The equipment: To do this I'm going to use several Arduino programmable I/O boards. These are cheap, easily programmed and flexible to do what I need. There will be one installed beside the existing timer/controller which is beside the boiler. This will be the master and will have two relays connected up, to control the two functions on the boiler (Heating and Hot Water). These relays will be switching the 240v mains boiler, the current programmer is rated at 3Amp switching so my relays need to be at least the same. I'll wire them into the same outputs as the current programmer with a common LIVE to switch. These relays will need to be opto-isolated from their inputs to protect my Arduino against the high voltage that would kill it. I would also like a mains voltage 'sense' coming back into the Arduino, the idea being I can sense these two functions and see if the existing programmer has the heating or hot water already on. (Not sure how to 'sense' this voltage safely yet. Possibly solid-state mains powered relays?) This Arduino will also have a plain 16x2 LCD display to show current status, and will talk to my network using an ESP8266 wifi module. I'll also put two buttons on there, one for BOOST (1hr) for heating and the same for hot water, so you can also manually force the system ON (A function lacking on my existing controller).

Testing: So far I've only done a few concept tests. Firstly removing the existing controller and checking what connections are there. On mine there are 8. First two are LIVE and NEUTRAL (supply), the next two are NC contacts (one for HTG and HTW) which are unused, then there are the NO HTG and NO HTW which are the contacts closed to LIVE when the heating or hot water are requested by the programmer. The remaining two wires are for the temperature thermistor in the hallway (The only temperature sensor the manufacturer fits/supports).
Then I tested the LCD module and ESP8266 wifi module. I've had a lot of trouble with the ESP8266 modules in the past, I'm sure I've burnt out two now. First thing to remember, they are 3v units, and the Arduino drives at 5v so trying to talk serial to them over the digital I/O will over-volt the ESP8266, so this time I'm using a 4-channel Bi-Directional Logic Level Shifter, which allows 3.3v to 5v and vice versa conversion. I'm also using a 5v to 3.3v step down supply to power the ESP8266 based on the AMS1117-3.3 chip. That should keep the ESP8266 running happily, though I'll power it from my separate 5v supply rather than the 5v pins on the Arduino as these aren't particularly high current and the ESP8266 suffers when fed with low current supplies.
Also to remember, when testing the ESP8266 I used a USB serial adapter FTDI232 that runs at 3v3 or 5v for testing. That lets me connect straight into my laptop and to the ESP8266 to send AT commands and make sure it's working, etc. One other thing to remember, minicom on linux doesn't send CR+LF at end of line. You have to force it by pressing Ctrl-M then J (Annoying!)
So, that meant I had a working LCD and ESP8266 ready for the next parts.


I was also running out of digital I/O, luckily I'm not using analogue here so can use those as digital I/O too.
So the pins I've allocated so far are:

 * A0  = D14 BUTTON - heating boost (Boost for 1hr)
 * A1  = D15 BUTTON - water boost (Boost for 1hr)
 * A2  = DHW sense
 * A3  = HTG sense
 * A4  =
 * A5  =
 * D0  = n/a (serial comms)
 * D1  = n/a (serial comms)
 * D2  = lcd(14)
 * D3  = lcd(13)
 * D4  = lcd(12)
 * D5  = lcd(11)
 * D6  = RELAY (DHW) Hot Water
 * D7  = RELAY (HTG) Heating
 * D8  = ESP8211 RX
 * D9  = ESP8211 TX
 * D10 =
 * D11 = lcd(6)
 * D12 = lcd(4)
 * D13 = heartbeat LED light

As you can see, I'm now a little low on pins, so cannot add much more to this unit, good job this should cover almost everything here!

The next stage is the code which will involve quite a bit of tweaking, as there are several conditions I need to handle:
Heating on/off from temperatures (average) around the house
Heating on/off from remote control (app/webpage)
Hot water on/off from remote control (app/webpage)
Boost button for heating
Boost button for hot water
When people are home (Detect they're home by checking for either bluetooth mac address ping, wifi association, or house alarm isn't turned on) then switch heating on if temperatures are needed, or turn on hot water if within certain times.

There are also several safeguards to build in:
If heating is on constantly for more than 2hrs, perhaps we should switch it off as maybe something got stuck (Perhaps Arduino should stop making change and wait for manual intervention?)
Don't switch on and off heating quickly within an hour
Don't switch on and off hot water quickly within an hour

So the Arduino code will need to take the above into account. My basic code plan is to run in loop and keep polling my home linux server for the current state request.

That's where I'm up to for now, I'll continue to add more as I write the code and build the hardware. The next part is to find suitable hardware to enclose it in, this needs to be able to sit alongside the existing heating controller and not look out of place, but contain all the required Arduino, space for the LCD front screen, Heating on, Hot water on and two buttons for manual boost.
I'll also need to figure out how to sense mains voltage safely.

Hopefully more updates soon!