Happy New Year everyone!
Similarly, my basic flight planning spreadsheet now has no restrictions and can be updated or changed however you like.
All files and tools are provided “as is” with no express or implied warranty for accuracy or accessibility. Use at your own risk. All calculations should be checked before being relied upon for flight planning purposes.
Almost six months ago I posted an article on reverse engineering the communication protocol of a Worcester-Bosch DT10RF wireless thermostat using a soundcard as a logic analyser. The aim of the project was to be able to take control of my Worcester-Bosch Greenstar 30CDi combi-boiler and hopefully improve on the quality and efficiency of the existing DT10RF Optimising Digistat.
Now that we are well into winter, I can report on the progress and effectiveness of the project.
I’ve never been particularly satisfied with the DT10RF. The “optimising” feature only works to delay the on-time of the first time-slot of the day – only the morning start-up is optimised. The optimisation will only delay the heating coming on in the morning for up to one hour, and it does nothing to optimise the time the heating switches off. You still need to basically guess what time the heating should be on or off to obtain the desired comfort levels.
We can do better than that.
Even modern intelligent thermostats such as Nest don’t seem to be that intelligent. Sure, they can learn your schedule and notice automatically if the house is empty. But I don’t need that. I’m more than capable of programming my schedule into a device. I don’t want to set a time at which the heating should come on, I want to be able to set a time at which the house is up to temperature and have the thermostat itself work out when to start heating. And I want it to work out what time it can stop heating based on prior knowledge of how quickly the house will cool.
Having tested the proof of concept it was time to build a prototype device.
I used an Atmel AVR ATmega328 micro-controller as the base of the system. It controls the 433MHz transmissions, and also monitors the local temperature using an analogue LM35.
The LM35 produces a signal of 0V + 10mV/C. It is connected to a non-inverting op-amp with the gain configured to be 12.497. This increases the LM35 output to 124.973mV/C. The ATmega328 has a 10-bit ADC with a 0-5V scale. This means each step of the ADC is 4.883mV. Our resolution is thus 4.883mV / 124.973mV/C which is 0.039C per ADC step with a range of 0-40C. This should be more than sufficient for standard indoor temperatures in the UK. There is also a fixed 2.5V reference supply used to ensure accurate calibration of the ADC between each temperature reading. The ATmega328 has a built-in 1.1V reference that can be used for ADC calibration, but it is not that accurate and so an external reference is preferred.
The controller also uses a Nordic nRF24L01+ 2.4GHz RF transceiver so that it can communicate with other temperature nodes, and obtain an overview of the total house environment.
An internal view of the device is shown below. It doesn’t look that impressive since it’s built on Veroboard, but at least it works! The two red LEDs indicate when the associated RF module is transmitting, and the green LED indicates when the thermostat is “calling for heat” and the boiler is firing.
So far I have just one temperature “node” that communicates with the “base”. This is currently sensing the living room temperature. As time allows I’ll be adding more “nodes” so that the system can measure the temperature of the entire house.
The nodes are almost exactly the same design as the base controller, except it doesn’t need to have the 433MHz module, and I’ve added an LCD display to read out the date, time, current local temperature, and a repeater of the “calling for heat” status. Instead of the green LED, the nodes show a clear “on” or “off” in text using the display. Neat!
The controller-base is connected to a PC where a Python script is used for the main decision making. This is purely for ease of coding whilst testing different heating and cooling algorithms. Once a final system is perfected, this could easily be migrated to the micro-controller and the whole thing become self-contained.
The heating schedule is read from an XML file, a section of which is shown below. There is an entry for each day of the week, and every day can have any number of heating “phases” throughout the day. At the moment I am using only two – for morning and evening.
<tuesday> <phase> <node>1</node> <high_at>6.25</high_at> <high_setpoint>17</high_setpoint> <low_at>7.5</low_at> <low_setpoint>17</low_setpoint> </phase> <phase> <node>1</node> <high_at>17</high_at> <high_setpoint>19</high_setpoint> <low_at>22</low_at> <low_setpoint>18</low_setpoint> </phase> </tuesday>
Shorly after midnight, the system loads the heating schedule for the required day. It then enters the “READY” state where it monitors the temperature of a given “master” temperature node and works out when it needs to start heating. Which node is the “master” node can change as required and could be, for example, a bedroom in the morning and then the living room in the evening.
0.006111 STATE==START 0.006111 Loading the daily schedule. 0.006111 Today is Tuesday. 0.006111 Node: 1. High Temp 17.0C at 6.25 hours. Low Temp 17.0C at 7.5 hours. 0.006111 STATE==READY
The first heating phase, above, says that we want the house to be at 17C at 06:15, and we want to maintain that temperature until 07:30.
Using its model of the heating coefficients of the house and the overall system, it monitors the current temperature and determines that 0.9 hours of heating is required, and that the boiler needs to fire at 05:21. This time will vary day-to-day based on how quickly the house is cooling, and how quickly the boiler can push heat into the house. Rather than have to guess what time to turn the heating on, this system has worked it out for us automatically.
5.360833 Heating required: 0.90 hours. Heating on at: 5.35hours. 5.360833 STATE==HEATINGSTART 5.360833 Calibration curve stopped. 5.361111 Cooling coefficients updated. 5.361111 Calibration curve started. 5.361111 STATE==HEATING
You’ll notice in the log above, just before actually entering the heating state there is an interesting line “cooling coefficients updated”. The system has been logging temperatures all night while everyone is in bed and the house is cooling.
We can now fit these data to an exponential decay function and calculate our cooling coefficients. These will change day-to-day depending on the external ambient temperature – the house obviously cools more quickly when the ambient temperature is lower. We need to calibrate the system cooling curve every night. An example is shown below.
Now we start heating.
6.253611 STATE==HEATINGCOMPLETE 6.253611 We were 0.00 hours away from target. 6.253611 Calibration curve stopped. 6.253611 Heating coefficients updated. 6.253611 STATE==STABLE
Just as expected, 54 minutes later the master node is up to temperature. We hit our target to the minute. Great!
Again, you’ll see another interesting line in the log – heating coefficients updated. If we had missed our target, then that means our estimate of how quickly the house would heat up was wrong, and so we need to recalibrate. An example is shown below.
We start logging a heating curve as soon as the call-for-heat flag is raised. It takes a little while for the temperature to go up, since the boiler has to heat up the whole system first. Likewise, the radiators gradually become less efficient as the house warms up and the temperature difference between the house and radiators themselves reduces. Fitting a simple straight line function through these data seems to be sufficient to average-out the variations. I might try some more sophisticated functions and see if they work better.
7.505000 Phase 0 completed. 7.505000 Node: 1. High Temp 19.0C at 17.0 hours. Low Temp 18.0C at 22.0 hours. 7.505000 STATE==READY
At 07:30 the first phase is complete and everyone is leaving the house. The system loads up the next heating phase and the cycle repeats.
This time we would like the system to be at 19C at 17:00, and we are happy for the temperature to have dropped to 18C by 22:00. No point heating the house until it’s time for bed, and then having the temperature comfortable until the early hours of the morning. We may as well stop heating earlier, accept a tolerable drop in temperature, and save some money.
15.461667 Heating required: 1.54 hours. Heating on at: 15.46hours. 15.461667 STATE==HEATINGSTART 15.461667 STATE==HEATING
The system estimates 1.54 hours of heating required, and starts firing at 15:28.
17.321389 STATE==HEATINGCOMPLETE 17.321389 We were 0.32 hours late. 17.321389 STATE==STABLE
We reach our set-point at 17:19. Oops, we are 19 minutes late. Oh well. I consider that to be acceptable performance, and at 17:00 we were only 0.2C below target. That’s basically perfect. Maybe the ambient temperature today was a little lower than yesterday. The heating coefficients will soon be recalibrated again automatically to take care of that.
18.347222 Topup required: 0.3C. 18.347222 STATE==TOPUP 18.597500 Topup: Maximum duration reached. 18.597500 STATE==STABLE
Once up to temperature, we need to maintain the set-point. Using simple timed burns seems to be the most effective. A fifteen minute top-up burn based on a 0.25C hysteresis below set-point works well. It prevents the temperature dropping too much, without resulting in an unacceptable level of over-shoot.
All the while maintaining the temperature, the system is calculating how soon it can stop heating based on the cooling coefficients it determined this morning.
21.266389 Cooling required: 0.74 hours. Cooling start at: 21.26 hours. 21.266389 STATE==COOLINGSTART 21.266389 Calibration curve started. 21.266389 STATE==COOLING
We stop topping-up the heat at 21:16 since the system has calculated that it will take 0.74 hours for the current temperature to drop to 18C.
22.000278 STATE==COOLINGCOMPLETE 22.000278 We are still 0.1C too warm. 22.000278 Phase 1 completed. 22.000278 All phases complete. 22.000278 STATE==DONE 22.000278 Waiting for next day.
We get to 22:00, our cooling set-point, and the temperature is 18.1C. We are still 0.1C above our set-point. Again, that is basically perfect. All phases are done, and the system enters standby while it waits for the next day to begin.
Here is the temperature plot for the evening phase.
The period between 17:00 and 22:00 when the system was supposed to be maintaining a fixed temperature looks to be a little random. This is due to normal human activity – people moving around, opening and closing doors etc. Even so, the system still manages to maintain the set-point to within ±0.5C which I consider to be quite impressive.
Here is the whole 24 hour period.
Since we are logging data, we now also have access to details that a normal thermostat can’t tell us – such as exactly when the heating was on and how long the boiler has been burning for today.
Interestingly, if we look at a different day where the system was left to get on with its job without human activity messing things up, then the temperature can be maintained to remarkable accuracy. The amplitude of the temperature variation in the plot below is just ±0.2C. Hopefully, with some further work, the stability will be improved for when random human activity is also present.
In summary, the system is capable of taking a fixed schedule and calculating the variable schedule required to compensate for changing weather conditions. We eliminate excessive heating due to guessing when to programme the boiler to fire, whilst at the same time without sacrificing comfort levels.
The next stages are to add more temperature nodes to increase the overview of the entire house system, and also add a web interface for updating the schedule.
Thanks for reading! I hope you found something interesting, and maybe even something to help you along with your own projects.
Arto Nupponen has a particularly interesting case, and I’ve reproduced his photos here with his permission. Arto had a Molex-SATA adapter where only the 5V rails were being used. As with all the others, this eventually started to burn up and melt the plastic housing. Arto was using a better quality PSU than the average consumer units, and so it possibly cut-out more quickly which could explain why this one hasn’t burned quite so badly as the others.
These adapters generally split a Molex power connector into two SATA power connectors. Arto even experienced some SATA connectors burning up when they weren’t connected to a device! Interestingly, his company were able to put some of the adapters into an x-ray machine, and here is what they look like:
It seems the copper somehow “grows” through the plastic and eventually shorts the conductors together. The cause may be impurities in the plastic, but I’m not really sure exactly how the process occurs.
Anyone have any comments on what might be happening here?
Recently several customers have been having trouble downloading purchases from the shop. I’ve spent some time looking into the fault, and decided to simply replace the eCommerce solution I have been using.
I have never been very happy with WP eCommerce, the backend layout was basically broken and did not display properly, and the customer experience wasn’t great either. A couple of years have passed since then and there is now a much greater range of WordPress eCommerce plugins available.
I’m now using WooCommerce which it is safe to say is miles ahead of WP eCommerce. The admin pages are beautifully designed and easy to use, and the customer facing pages look great.
I’d like to take the opportunity to apologise to everyone that experienced problems over the last few weeks. Hopefully everything will be much more smooth from now on. If anyone does have any troubles, please do let me know!
Way back in 2007 I had a new boiler and central heating system installed. I chose the Worcester-Bosch Greenstar 30CDi combi-boiler as the heart of the system since the manufacturer has a very good reputation for reliability and efficiency.
This boiler has various control systems that can be used to operate the heating and direct hot water. I selected the DT10RF Optimising Digistat since, although it was quite expensive, it was the best Worcester-Bosch offer and promised further cost-savings through the use of its “optimising” feature.
The DT10RF controls both the operation of the central heating, and also the timing of the hot-water pre-heat function which allows the boiler to deliver hot water more quickly. When running the heating, the optimiser function calculates the time the boiler needs to start in order to reach the correct temperature at the programmed times.
You can set up to four different time periods for each day of the week for heating. You can set the room temperature for each of these four periods. The timing for hot water can be different for each day of the week. The wall-mounted room thermostat is wireless and uses the standard 433MHz band. This controls the temperature for the heating, and the boiler mounted receiver controls the timings of the hot-water pre-heat.
Right from the beginning I’ve never been very satisfied with this control system. Firstly, the “optimising” feature only works to delay the on-time of the heating, and does nothing to optimise the time the heating turns off which it could do by learning the time it takes the house to cool down. Not only that, but it only optimises the first time-slot of the day so only the morning start-up is optimised. The time at which the temperature set-point changes from day-time to evening is not optimised. Also, the optimisation will only delay the heating coming on in the morning for up to one hour. Since it takes my heating at least one hour to warm the house up, the optimiser basically never did anything at all.
While it is true that you can set four different time periods each day for the heating, you can’t change the temperature set point. The set point for each of the four time slots is set once, and then applies every day. So you can’t have complete flexibility in how the heating is configured.
Even the wireless side of the thermostat has never been very reliable, with the signal constantly dropping out and requiring the transmitter to be temporarily moved closer to the boiler and the set point manually turned up and down to give the system a kick and get the communication going again. It’s certainly not fun waking up on a cold winter morning to find the heating hasn’t come on because, yet again, the wireless communication has failed over night. This is with a house of normal construction, and not a huge distance between the transmitter and receiver. I did have the control system replaced under warranty, but the new one was no better. There are lots of posts on the internet where people are experiencing the same problems with the DT10RF. Worcester-Bosch blame anything from too-thick walls to interference from WiFi access points. That is simply not acceptable, and the design of the wireless system is frankly not fit for purpose.
Since purchasing this thermostat Worcester-Bosch have released a new version, the DT10RF Digistat optimiser (MK II). From what I can tell, aside from having six time slots rather than four, it is simply a cosmetic change. I don’t expect this version to be any more reliable, and from forum posts it looks like the same problems still exist.
The last straw was when, during the previous winter, the thermostat simply refused to work when it was any further than about two metres away from the boiler. This was with a fresh set of batteries, and the whole thing reset and reprogrammed from scratch. Hardly any point in it even being wireless.
Time to start looking for a new heating control system.
Ideally I would like something that connects to my local network, either WiFi or Ethernet. This would make it easy to programme, and also remotely adjustable over the internet. This would mean that when I’m out somewhere and I’m going to be back home later than expected, I can easily change the timing of the heating so that it comes on later and does not burn gas unnecessarily.
I would also like something that is far more intelligent than the current heating control systems. I want it to learn how long it takes the house to warm up and cool down, and decide for itself when the heating needs to be on. Rather than saying “I want the set point to change from 12C to 20C at 4pm”, I want to be able to say “I want the house to be 20C at 5pm” and have the system work out itself when to fire the boiler, based on the outside temperature and its own knowledge of how quickly the house warms up. Likewise, I want to say “I’m happy for the temperature to have dropped to no less than 18C by 11pm” and have the system work out itself when it can stop heating, based on its knowledge of how quickly the house cools.
I want to have multiple temperature sensors around the house, to get an overall view of the system, rather than just the temperature state in one room. It could decide which sensor gets to control the heating based on the time of day. For example, in the mornings I only care about the temperature of the bedrooms. I’m not worried about the temperature of the downstairs open-plan area that typically takes a lot longer to warm up, since I’ll very shortly be leaving to go to work. So the master bedroom could control the system in the morning, while the lounge controls the system in the evening.
It could also do other nifty things, like if the current temperature is below the set point at 8am, but the local weather forecast pulled from the internet predicts that it is going to be a lovely day and warm up by 10am, then it could decide to not turn on the heating at all. I don’t want it to burn gas for two hours just because the morning is a little chilly, and then end up having to open a window once the sun comes out.
Looking around the central heating market, I see several manufactures are now producing WiFi enabled thermostats, such as the Heatmiser PRTHW-TS WiFi. However, not only are they very expensive and get some poor reviews, they also don’t appear to do what I want. They allow only programming over WiFi, they don’t do anything clever regarding heating control. If you’ve managed to find one that does – please do tell me about it in the comments section below!
I decided what I really want to be able to do is control the boiler from my PC. If I could send a command to turn the heating on or off, I could then write my own code to control it and have it do whatever I want.
I know that the DT10RF uses the 433MHz band to transmit the on/off signal. If only I could capture the signal it sends, I could then reproduce it and take control. I decided to purchase a 433MHz transmitter and receiver pair from eBay. At a price of just £2.80 it was worth a gamble as to whether I would be able to receive anything from the thermostat.
One slightly annoying thing about these cheap 433MHz receivers is that when there is no signal present, their Automatic Gain Control circuit gets ramped up and all you get is receiver noise on the data pin. This makes it rather difficult to actually pick out any data from the noise. Luckily, you get about 100mS of “radio silence” after a signal has been received before the AGC winds back up again. So it is possible to look for this silence, and then look for the data immediately before it in order to “sniff” the signal.
I hooked up the data pin of the receiver to an oscilloscope, and sure enough when I turned the thermostat up I could see a signal go through. Likewise when I turned it back down, another signal was visible. It was impossible to capture the signal to analyse it since it was far too fast. Since I didn’t have access to a storage-oscilloscope, I decided to make use of a “soundcard logic analyser” that I had made previously.
By feeding the signal from the receiver into the soundcard on my computer, I could capture the data continuously and then look at the signals at my leisure. I connected it all up, and turned up the thermostat until it started calling for heat. It visibly sent an “on” signal three times. I then turned it back down again, and it sent an “off” signal three times. You can see the data in the screenshot below. The 100mS periods of “radio silence” make the data stand out easily from the receiver noise. In the data below there are three on-pulses separated by approximately 1.9 seconds, followed by three off-pulses separated by 1.9 seconds.
Zooming in on one of the “on” transmissions we can see the following pulse train.
Zooming in on one of the “off” transmissions we can see the following pulse train.
As you might expect, the signals are nearly identical except for the last few pulses. I haven’t made any attempt to work out what it is actually sending, except to recognise that there appears to be a “preamble” that is used to give the receiver time to adjust its AGC, followed by a series of pulses that represent the boiler/thermostat ID, followed by either the “on” or “off” message.
By simply writing down the lengths of the high and low pulses it is possible to reproduce them using a microcontroller and 433MHz transmitter. I’ve been using Atmel AVR ATMega328P microcontrollers in a lot of projects lately, so I decided to use one here as well. This one is mounted on an Arduino Uno board. It’s simple to connect up the transmitter, just power and ground, and the data pin connected to pin 2 of the Arduino (PORTD, PD2, pin 4 of the IC).
It works! I can turn the central heating on and off again using my PC. Now that I have full control of the system I can work on writing some algorithms that optimise comfort and, most importantly, minimise gas usage. Helpfully it also seems to have much better range than the transmitter in the commercial thermostat – I can easily activate the heating using my laptop over on the other side of the house from the boiler. If I find that I need even more range, the transmitter can be operated from up to 12V with increased transmission power. At the moment I am powering it with the normal 5V logic supply to the microcontroller.
The following code-snippet shows how I control the 433MHz transmitter. It’s only intended to be an example, you probably wont be able to just cut and paste it into your own Arduino sketch since I don’t use the Arduino framework. But it is simple enough to follow and can easily be made to work in your own application.
rf.cpp (3.2 KiB, 1,264 hits)
If you want to try to control your own Worcester-Bosch boiler and have a DT10RF thermostat, you should be able to use the same RF messages as me provided you put your boiler into “learn” mode and then transmit the “on” signal so that the boiler knows what messages to expect. If, like me, you want to be able to switch seamlessly between computer control and the thermostat whilst you develop your heating control application then you’ll need to follow the procedure I have detailed and capture the code your own thermostat is sending.
In the next tutorial, I’ll detail how to build your own inexpensive wireless temperature sensors for distributing all over your house. After all, what use is having control of the heating system if we don’t know what the temperature is?
Have you ever needed to capture a logic signal to check that your Arduino or Raspberry Pi project is doing what it’s supposed to be doing, but you don’t have an oscilloscope? Or maybe you do have a ‘scope but it doesn’t have a storage mode, so the signal goes past far too quickly to see.
No need to shell out loads of money on an expensive logic analyser, when you have one with virtually unlimited storage capability right in your PC! You can use the sound card to capture logic signals as they pass through the bus, and then investigate the signal timing at your leisure.
The only problem is logic signals are generally +5V or +3.3V, whilst the line-in on your soundcard is designed to capture only voltages between plus and minus 2V at most. We can easily get around that by making a voltage divider out of a couple of resistors. I used an 82K and an 18K resistor giving me a 1/5 voltage reduction. That makes my +5V logic signal just 0.9V which is well within the range of the soundcard input. The resistor values don’t matter too much, so long as they have a ratio that brings your logic level down to something appropriate for the soundcard. Although it’s best to try to keep the total impedance as high as possible to prevent the connection interfering with you circuit.
First, get an old stereo cable with a 3.5mm jack plug. Cut off one end and strip the insulation to reveal the shield braiding and the two conductors.
Unbraid the shielding, and solder on your 18K resistor, and a length of wire that will form the “ground” connection for your logic probe. I’ve used two since I’m making up both channels. Use the left and right stereo inputs to make a two-channel logic analyser!
Put a bit of heat shrink over the joint to isolate the connection. Next, solder your 82K resistor onto the other side of the 18K resistor, and attach the left and right signal cables to the centre point of the voltage divider.
Attach your signal probe wires to the far side of the 82K resistor. Again, isolate the connections with some heat shrink.
Finally, put some more heat shrink over the whole thing to secure it all together. Nice tidy job!
Now you’re ready to feed it some signals and capture them. I used Audacity under Linux which is a free, open source, cross-platform application for recording and editing sounds. It’s perfect for this task. Did I mention it was free?
Here we are capturing two square waves at 192kHz sampling frequency. You’ll notice that the square waves are not very square, especially at lower frequencies. This is because the soundcard has a high-pass filter and tries to reject DC offsets. As soon as the square-wave pulses to a positive or negative level, the soundcard starts to pull the signal back to zero and the signal “droops”. That’s not too much of a problem, since we’re only aiming to look at the pulses and be able to measure the timing and synchronisation with other logic channels. For this, it’s perfect for the job!
Don’t make the mistake of thinking you can use this as a replacement for a proper multi-meter or an oscilloscope. If you decide to try to measure the frequency of your mains electricity you will destroy your soundcard and probably your whole PC.
But for the purpose of capturing logic signals – it’s perfect!
Pi power! The project is coming along nicely. It’s got a #raspberrypi for communication with the outside world, and a custom-made #arduino board for controlling the steering servo and L298-based DC motor driver. I’ve hacked a standard RC receiver to obtain the PPM signal which is decoded using the Input Capture function on pin 14 of the ATMega328.
I’ve had to move away from a lot of the Arduino framework since I wanted to use Timer1 for uS timing of the PPM signal. This meant I couldn’t use the standard Servo library either, so I had to write my own. Turns out it’s pretty easy.
I’m now considering ditching the Arduino framework completely given the only functions I really use are timekeeping and Serial communications. I’m intending to use SPI for communication with the Pi in order to free up the UART for connecting to a GPS module. The Arduino code can only work as a SPI master, and I want to set the uC up as a slave, so that’s something else I’ll have to write for myself anyway. I’ve also just had a bad experience with the String library, which it turns out is a pile of junk and I should have just stuck to char arrays – I’ve now got to rewrite a whole chunk of code. So all-in-all I may as well just ditch Arduino completely and simply use avr-gcc and avrdude directly with a makefile.
Now that I have full manual control of the car, it’s time to start adding sensors and writing the autopilot …
These look like a good set of ingredients for fun!
This is a Marui Ninja RC buggy.
It must be at least 20 years old. I dug it out the loft last night. I quite like the idea of taking a really old car, and upgrading it with a brushless motor, new ESC, LiPo battery etc. And then working on the Arduino automation to give it collision avoidance and the ability to follow a preset route using GPS.
It’s kinda a pre-quadcopter practise for when I’m ready to try something airborne!
#arduino #arduino-based #drones