Hack a wireless home automation system to be USB controlled using two AVR microcontrollers!
Check out the video! The system is really more responsive, but the browser on my phone is slow.
Skills and tools
There are two ways of hacking an RF remote to be controlled by a computer or a microcontroller.
The lame way:
Soldering wires onto the button pads on the remote and hooking them up to an Arduino.
The cool way:
Most RF remotes have a separate module for transmitting data. This device usually has a VCC and a GND line and a DATA line. You can easily transmit your own wireless data by connecting a microcontroller to the DATA line.
However, in order to transmit something that the wireless receivers can understand, you first have to figure out how the wireless data is formatted and transmitted.
To do this hack you will need a logic analyzer and optionally an oscilloscope.
I use the Logic from Saleae. This is an awesome tool and I have done a few reverse engineering hacks using this device!
Check it out at http://www.saleae.com/logic/
It costs 149 USD but it’s a good investment for any hacker!
You also need to be familiar and comfortable with microcontrollers and programming in C.
You will need:
- 1x wireless home automation kit
- 1x project box
- 1x USB type B connector
- 2x 3.6v zener diode
- 1x 8.2v zener diode
- 1x BC548 transistor
- 2x 22pF ceramic capacitor
- 2x 100nF ceramic capacitor
- 1x 4.7uF capacitor
- 1x 100uF capacitor
- 1x 470uF capacitor
- 1x 330uF capacitor
- 1x 12MHz crystal
- 2x LED with resistor (I used 1k ohm)
- 2x 68R resistor
- 1x 1k5 resistor
- 1x 2k2 resistor
- 1x 1m resistor
- 1x 270uH inductor
- 1x 1N4004 diode
- 1x ATmega8 microcontroller
- 1x protoboard. Solder eye type, not stripboard.
Don’t turn it on, take it apart!
I assumed that the remote had a separate RF module. Let’s crack it open and check if this is the case.
Eeey! It sure does! The little green board inside the remote is the RF module.
The board is even clearly labeled and has 3 inputs:
The connections were kinda hard to get to with my oscilloscope and logic analyzer probes, so I just extended the connections using some solid core copper wire.
Now I can push the buttons while sniffing the DATA line.
Figure out what’s going on inside
The remote is powered by a 9V battery. My logic analyzer is only rated for 5 volts, so I want to check out what’s going on with the DATA line before hooking it up to my logic analyzer.
If the signal on the DATA line is 9 volts, I have to do some tricks to get it down to 5V for the logic analyzer.
I connected an oscilloscope probe to the DATA line, and GND to the GND line on the remote. I set the trigger to two-ish volts and pushed a button. Out comes data! Sweet. This looks very hackable!
Turns out, the data line is only 3 volts. The distance between the horizontal dotted lines on the oscilloscope display is 2 volts.
The RF module looks like a pretty simple device, so I’ll just assume that it can handle 5 volts as well as 3. The micro controller will be running at 5 volts.
Reverse engineering: first glance
The oscilloscope is a great tool, but to see what’s really going on with that data signal, it’s a lot easier to use a logic analyzer.
The logic analyzer only reads 0 and 1, so I don’t get all the analog noise that i get on the oscilloscope, and it is connected to the computer via USB, so it’s a lot easier to read than the small oscilloscope display.
So I hook the DATA line up to channel 1 of my logic analyzer. I select 1 MHz capturing rate, that should be more than enough for this.
I start the logic analyzer and press the ON button for lamp 1 on the remote control.
The logic analyzer shows 4 distinct frames of data. At first it thought maybe this was going to be more complicated to reverse engineer than I had anticipated. But to my relief, all 4 frames was identical. The same was true for all the other buttons on the remote. The data is probably transmitted 4 times because the wireless link is inherently unreliable :p
So I zoom in on one of the frames and see that it consists of pulses of different length. At this point I have no idea what is 0 and what is 1.
Reverse engineering: diving into the data
Ok, so at this point I just have a bunch of short and long pulses, and I have no idea what it means!
The remote has a small button under the battery lid. If this button is pressed, I have to re-associate all the receivers with the remote. If you neighbor’s remote is interfering with your lights press this button to get a new random ID. I suspect that pushing this button creates some kind of randomized code specific to that remote.
If that is true, I can use it to identify at least some parts of the data.
I started the logic analyzer again and pushed ON for lamp one 5 times while pressing the reset button between every time i pressed lamp 1 ON.
To make it easier to see what was going on, I copy pasted the data frames into gimp and placed them under each other. In the logic analyzer they are represented side by side, which makes comparison pretty hard.
Luckily, the Saleae guys had thought of this. Ctrl+shift+m lets you copy a selecton of the screen to clipboard.
As I suspected, pushing the reset button changed a random number inside the remote that is transmitted with each data frame.
The first bit is always the same. This makes sense. It probably “wakes up” the receivers or tells it that “Hey, here comes data, be ready!”
The next 12 consecutive bits change every time i press the reset button. I marked the bits that changed in red and the constant bits in green.
Lets call the 12 random bits network address from now on.
It looks like the payload data for each frame is 8 bits.
Another great thing about doing this hack the cool way instead of just soldering wires onto the buttons, is that you can use the 12 bit random field as well. You can have 4 lights on one network ID, and 4 others on another network ID, and control them from the same remote! Actually, you can control (2^12)*4 = 16384 lamps with this hack!
Reverse engineering: what is 0 and what is 1
So I know which bits to ignore, the start bit and network ID bits. But I still don’t know how the remote represents 0 and 1.
The remote has buttons for 4 lamps. The most logical way to represent these in the data frame is with a 2 bit binary number.
I started the logic analyzer again and pressed the ON button for lamp 1, 2, 3 and 4. Then I copy-pasted it into Gimp to get an overview.
Ok, so four bits change when i press an ON button. Two of the bits seems to be counting in binary from 0 to 3. It is most likely that they are the lamp address bits.
For lamp 1 they are both long pulses. For lamp 2 there is one short and one long pulse. This means that the least significant bit is sent first. The opposite of they way you would normally write a binary number.
Because it looks like the bits marked in green seems to be counting fro 0 to 3, I will assume that this is the lamp address bits. I don’t know what the bits marked in blue are yet. Probably some kind of checksum to ensure error free communication.
Also, I have learned from this that in all likelihood, the bits are transmitted like this.
- Long pulse: 0
- Short pulse: 1
Reverse engineering: figure out the rest of the data
At this point I know how 0 and 1 is represented, and I think I know which bits represent the lamp address. I also think that the last two bits are some form of check sum.
To figure out the rest of the data frame, I had to capture data for all possible button presses.
I started the logic analyzer and pressed ON for all 4 lamps, then OFF, then ALL ON and ALL OFF, and finally DIM + and DIM -.
To make it a little easier to debug, I typed all the captured frames into OpenOffice. I left out the first 13 bits, since I already knew what they were. I also left out some lines for the DIM buttons so that the screenshot would fit in the Instructables default image size.
It looks like the payload data has two bits for lamp address, then 4 bits for command data.
The command bits were easy enough to figure out. In the second picture, I have split the data into 3 columns, lamp address, command bits and checksum.
As you can see command bit 2 is only on when I press the ALL ON or ALL OFF buttons. That means that this bit is a broadcast bits that makes all the receivers listen.
Bit 3 is only on when I press the ON button or DIM – button. Lets call this command bit ON/OFF.
Bit 4 is only on when I press the DIM +/- buttons. Let’s call it DIM.
Bit 5 is always low. Mystery bit. I have no idea what it does. Maybe it is just there because the checksum algorithm needs an even number of bits?
In the last picture, you can see that I have reverse engineered the entire data frame.
I assumed that the system had 4 lamp addresses, since there is 4 buttons on the remote. But another possibility is that the first three bits are lamp address, and that address 111 is broadcast. If this is the case, then you could have 7 lamps + broadcast on one network ID.
Reverse Engineering: Checksum Head-scratching
At this point I know what everything inside the data frame is. However, I have no idea how the checksum is calculated.
I started reading about checksums on Wikipedia, and tried applying all sorts of algorithms to the data. Nothing really seemed to work. Then I noticed that the checksum for any given button press was identical regardless of the random network ID. The checksum is only calculated based on the payload data.