My home automation systems use two mechanisms for communication: Ethernet (both wired and wireless) and 433MHz OOK radio.
433MHz transmitters are readily available and are cheap but unreliable. Wifi enabled MCUs such as the ESP8266 are also cheap (coming in at around the same cost as an Arduino clone, a 433MHz transmitter and a bag of bits to connect them together), they are reliable enough but extremely power hungry. If I can plug a project into the mains then I’ll use an ESP8266 and a mobile phone charger for power, if the project needs to run off batteries then a 433MHz equipped Arduino is the way I’ve gone.
A big capacitor on the transmitter. I saw the frequency and amplitude drifting massively during transmission. Adding a 470µF cap helps. Allow time for the cap to charge and the oscillator to stabilise, a few seconds delay seemed to do the trick.
mySwitch.setProtocol(2); // Much longer pulse lengths = much better range?
mySwitch.setRepeatTransmit(20); // Just brute-force it!
With this setup I can get receive a 24bit number from an Arduino running off 2 AA batteries and a coiled 1/2 wave antenna from about 5 meters indoors through walls. That’s still poor, but it does the job. Increasing the voltage to the transmitter would probably help.
Once you have a reliable 433MHz receiver setup then you can also buy off the shelf 433MHz enabled home automation gizmos like this smoke alarm or these door sensors. They have a set of jumpers inside where you can set an ID, which is essentially the same 24bit number that RCSwitch lets you transmit. For what it’s worth I also have kite-marked smoke detectors in my house, but from the testing I’ve done with a bit of smoldering paper the cheap imports work just fine.
You can barely notice it!
It’s certainly untidy, but it does the job. If I had PCB facilities at home I’m fairly sure it could be made to fit inside the alarm, along with some more holes in the case for ventilation.
The premise is simple enough. The Arduino is powered by the 3v3 regulator on the CO alarm PCB. The cathode of the red alarm LED is connected to pin 2 of the Arduino as an external interrupt. When the pin goes low the Arduino wakes up and sends it’s 24bit ID number over the radio which is picked up by the receiver which sends an SMS alert, switches the boiler off, etc. I’ve connected the radio transmitter to directly to the 3 x AA batteries (4.5 volts) via a transistor which is switched by a pin on the Arduino. In standy-by mode the additional equipment draws a fraction of a milliamp and so I’m not worried about draining the batteries faster.
As with the smoke alarms, this is not my only source of Carbon Monoxide detection. I’ve yet to test it’s sensitivity. This is considered to be a “well, if it works, and it turns the boiler off automatically then it’s certainly worth a go, but I’m not relying on it” project.
I’ve had all the parts hooked up on breadboard for a few weeks now, and in theory everything works. I haven’t actually tested the prototype with the real heating system yet as it’s been cold and I don’t want to risk blowing anything up and having to deal with a cold house and an angry family. Sometime in the next month or so I will do that, but as far as I can tell it will Just Work (lolz).
In the meantime I’ve been thinking about the software to drive the thing.
My programming skills are pretty basic so I have been trying to keep everything as simple as possible. It became apparent that I was going to need some inter-process communication so that I could handle switching things on and off from outside the controller program (for web control etc). This presented me with a problem as all the basic reading from files/FIFOs were blocking – in that they would sit and wait for a “command” to be received before continuing – and that was too limiting for my needs. I was going to have to deal with some kind of threading. This troubled me deeply. The good people of Google+ suggested a few options and in the end I decided a RESTful interface was the way to go as it should be accessible from the widest range of other languages I might have to use, and especially easy from a web browser.
That way, I figured, I could just write one script and each function could interact with each other function very easily. But following a conversation with Mark S. a few years ago, and then more recently with Stuart L. I was starting to think that the monolithic architecture was not the way to go and instead I should push the intelligence out to the edges and the main loop should just deal with the basic on/off functionality. I was worried that if something went wrong with the electronics, for example the heating turned on but never off, then it would be difficult to spot from outside the main loop. But, given that the heating system has a lot of built-in safety features like room stats, boiler stats and hot water stats which are all wired in series with the mains that won’t be a problem, and besides the current controller doesn’t do anything more intelligent than ON or OFF.
The Relay Controller would handle switching the power on and off in the right order to the right outputs, it would handle the switches for manual override, provide feedback via LEDs, and it would provide a REST interface for anything else to control the system or find out what the current state is. This way I can write a much more simple script to manage the scheduler for example. It can run independently and then simply poke the relay controller at the right time. I also decided that the relay controller would only have the ability to switch off after a certain period of time. The default will be 60 mins. This further simplifies things and puts just the right amount of intelligence in the core. The scheduler just says “switch on now, and off again in 90 minutes”. If the scheduler crashes the correct state is maintained by the controller and things just pick up from where they were when the scheduler starts again. If the controller crashes then the power is removed from the system and it “fails safe”.
I used the Python SimpleHTTPServer, the ThreadedHTTPServer and threading.Thread.
Next on the agenda is to draw a PCB and get it made (once I’ve tested the circuit properly) and work on the scheduling engine. At this rate I should be finished right around the time when we don’t need to use the heating any more.