Now autumn is setting in, I’ve started doing some work on my control algorithms for my home temperature control system.

I had been using a simple On-Off (“bang-bang”) control system, but as expected, I was getting quite large temperature overshoots above the desired temperatures. In some cases, I was getting an overshoot of about 2C, which at times made things quite uncomfortable.

Since I had already done quite a bit of work on temperature control in other systems, I decided to improve on the system using a control methodology that has worked well for me in the past: PID control.

PID controller

For those that don’t know what PIC control is, there’s plenty of tutorials and examples on the internet, but a simple explanation is that is uses Proportional, Integral, Derivative errors between the desired state (temperature) and the actual state (temperature) to decide the input of the system. For my controller, the input is the amount of time the boiler is on for (I’m using PWM and will explain that more later), so the higher the number (the greater the errors), the greater the time the boiler is one for.

  • Proportional – the output is proportional to the error. For this controller, if the temperature error is higher, the boiler is switched on for longer.
  • Integral –  the output is proportional to the integral of the error. If the temperature stays too low for a long period, the integral of the error will go up, so the boiler will start to stay on for longer. This helps get rid of steady state errors.
  • Derivative – the output is proportional to the slope of the error. So if the error is getting small too fast (i.e. the temperature is rising too quickly) the boiler will switch on less. This will help reduce overshoot and to compensate for the time-delay, which can cause big issues in temperature control systems (when rooms can still get hot after the temperature source has been switched off).

For now, I’m only using P, effectively keeping D and I at zero (though in practice, I’m simply not calculating them to make life easy in the short term while I play with the system).

So, for my system, the output of the controller is simply

output = (desired temperature – actual temperature) * P

For now, I’ve got P = 100, D = 0, I = 0

PWM controller

However, my boiler doesn’t understand any of the numbers given by the PID controller above, instead only understanding ON or OFF. The control to the boiler simply consists of a esp8266 board controlling a mechanical relay, which then replaces the thermostat controller on the combi-boiler. In other words, I can only switch my heater on or off.

Therefore I’m using PWM (pulse width modulation) to convert the PID’s output into the on-off control that can be understood by the heater.

Again, I won’t go into too much detail into PWM controllers as there are better tutorials out there than I could write. When my PID controller gives out 100, the PWM system will have the heater on at 100% and when it’s at 0, the heater will be at 0. Anything else is simply a percentage between 0% and 100%.

For those interested, I chose a PRF (pulse repetition frequency) of 10 minutes and a period of 1 minute. Therefore, a PID out of 13% and 18% would have the heater stay on for 2 minutes, while a PID output of 2% would have the heater on for 1 minute. I’m sure I’ve done something wrong here and 13% should keep the boiler on for 1 minute (not 2 minutes), but it’s okay for now.


I’ve only had the new system up and running for about a week, but so far it seems to work well. I now only have an overshoot of about 0.2C compared to about 2C. The system seems quick enough and I’ve yet to notice any major problems with it.

Below you can see an example screen shot of the last 24 hours showing the desired temperature along with the actual temperature. This is only the temperature in my living room, which is currently the only room to contain a temperature sensor (though that will change soon enough). The bottom graph shows when the boiler is on or off (1 being on, 0 being off).


All the controlling is done through node-red and the user-interface is done via node-red-dashboard. If anyone would like more details on the node-red flows, feel free to ask.

Where next?

One thing I want to play with next is figuring out the best PRF value. I would like something smaller than 10 minutes, but I’m not sure how well the heater would cope with constantly being switched on and off. If anyone has any ideas or thoughts, I’d be happy to hear them.

I’m also going to look at introducing the D part of the PID controller to try and control any potential overshoots caused by big temperature changes.