Introduction: Reverse Engineering: USB Controlled Home Automation Hack

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.

If you like this, you may also like this:

Step 1: Skills Ans 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

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.

Step 2: Parts Required

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.

Step 3: 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:
  • VCC
  • DATA
  • GND
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.

Step 4: 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.

Step 5: 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.

Step 6: 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!

Step 7: 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

Step 8: 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.

Step 9: 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.

My guess is that it is hard-coded into the remote to make the chip design simpler.

So with this in mind, I tried some simpler stuff. I noticed that sequences of 01 and 01 would cancel each other out and produce a checksum of 00, and that sequences of 01 and 10 would produce a checksum of 11.

This hinted towards a simple XOR algorithm.

After some trial and error, I found a simple algorithm that always produced the correct checksum.

The first two bits are XOR'ed with the 2nd two bits. The result of this is XOR'ed with the last two bits.

Check the image to see how the hcecksum calculation is done:

Step 10: Reverse Engineering: Timing

So now we know what everything is, the only thing left to do is figure out the timing of the signals.

Each bit is made up of a period of low, and a period of high. The entire cycle is always 1.92-ish milliseconds. A long pulse is 1.3 ms and a short pulse is 0.62 ms.

Each frame, start bit excluded, is 38.4 ms. 38.4/20 = 1.92 ms. So 1.92 ms seems like a good starting point for creating the right timings.

Step 11: Reverse Engineering: Re-create the Result

I know how it works, now lets try to recreate the result.

I set up a timer on an ATmega8.

The ATmega is running at 12MHz.

A timer is set up with a 128 prescaler in CTC mode. In the CTC mode, the timer is reset and an interrupt is called when the counter reaches a given timer compare value.

The counter is updated every 128 clock cycle. This means that I have to use 120 and 58 as the counter values for the short and long pulses.
(1000/12000000)*128*121 = 1.29 mS
(1000/12000000)*128*59 = 0.62 mS

This is pretty close to the original timings.

I put together a simple function to fill a buffer with the delay times for a given RF frame. An interrupt routine then switches an IO pin on and off and sets the timer compare value to create the desired length pulse.

I hooked it up to the logic analyzer and copy-pasted the result into Gimp. Bingo! The resulting signal is identical to the one from the RF remote :D

Code is included in a later step.

Step 12: Hardware: RF-fail and Charge Pump

I was quite happy with the result from the timer interrupt function. I expected everything to work when i plugged in the RF module... but it didn't :/

But the remote used a 9v battery.. maybe the RF module needed 9v? I connected the VCC on the RF module to +9V and tried again. Success!

But I don't want to have a 9v battery inside my gadget

After some googling, I found out that charge pumps was the right solution.

The charge pump consists of an inductor, a transistor, a diode and a capacitor.

I am no guru on analog electronics, but I'll try to explain how (i think) it works.

When the transistor is activated, the inductor is shorted to ground. When the transistor is deactivated, there is a flyback effect in the inductor that releases a short burst of high voltage. This voltage goes through the diode and is trapped in the capacitor.

A PWM signal is supplied to the transistor to do this 23.000 ish times per second. Every time the transistor releases, the voltage in the capacitor increases a little.

To keep the voltage from rising to high, the voltage on the capacitor is fed back to the micro controller via a zener diode. The analog comparator checks if the voltage is higher than 1.2 volts + the zener voltage.

The main loop of the microcontroller continuously checks if the voltage is below the threshold level. If it is, the pwm signal is started. If the threshold level is reached, pwm is disabled. 

Step 13: Hardware: Circuit

The circuit is pretty simple. All the complicated stuff is inside the RF module.

The main part is an ATmega8 AVR microcontroller. A USB connector is connected via some resistors and zener diodes. USB signals are 3.3v, so we need zeners to reduce the voltage.

The DATA line of the RF module is connected to an IO pin. The charge pump transistor and status LED are also connected to IO pins.

The feedback signal from the charge pump circuit is connected to the analog comparator. It compares the voltage to an internal reference voltage. I think the reference voltage is 1.1 ish volts. Not that important.

The circuit has the regular support circuitry like filtering capacitors too, and a 12MHz crystal.

(I forgot resistors on the two LEDs in the schematic. You can add appropriate resistors yourself.)

Step 14: Hardware: Prototype

Before i turn on the soldering iron, I want to check if everything works the way it's supposed to.

I've only used USB one time before, and never with 5V system power and zener diodes like this design uses. Also, the box I'm putting the circuit inside is quite small, so there won't be any room for an ISP header. I'll program the AVR on the breadboard then move it over to the soldered circuit.

At this point, everything works. Let's hope it still works when everything is soldered in place ;)

Step 15: Software

Before the chip is removed from the breadboard, it needs some software.

The software is written in C and based on an example project from Objective Developments V-USB lib. This is a great piece of software, and it is free and open source for personal/non-commercial use.

I'm not going to go into great detail on how the software works. The reverse engineering is the emphasis of this Instructable. Here is the short version:

You need two programs to make this work. A program on your computer and firmware for the microcontroller.


The actual RF transmissions is done by an interrupt routine. I use a timer interrupt because this is the easiest way to get precise timing. The timer interrupt reads from a global buffer where the delay times are stored. I don't store the on/off status of the RF transmitter since on and off always alternates. I start with an off pulse, then alternate on and off pulses.

The buffer contains 42 values. There are 21 bits to be transmitted, and each has a low period and a high period. This configuration is not very RAM efficient, but the ATmega8 has plenty. I'll trade RAM for code readability instead of having unused ram!

The buffer is populated by the send_rf_frame(network, payload) function. It fills in the right timings in the rf buffer array, starting with the start bit, followed by the 12bit network id and the 8 bits of payload+checksum. When the buffer is populated, the buffer position variable is reset to 0, so that the interrupt routine will start working from bit 0 in the buffer.

When data is sent to the microcontroller over USB, the function usbFunctionSetup() is called. This is a function that you create and where you put your incoming USB code.

Depending on the request type sent from the PC, you can do different things inside this function. I have two request types configured, set_network_id and send_command.

The set_network_id request just takes the 12bit network id sent from the computer and stores it in a global integer value.

The send_command request calls send_rf_frame() and passes the received command byte to it. After that, the interrupt routine takes over.

Inside the main() loop:
usbPoll(); has to be called every few milliseconds (10 or 50, not sure) for the USB to work properly.
After that is done, the analog comparator is checked. If the charge pump voltage is too low, the charge pump is started. If it is at the desired voltage, the charge pump is shut off.

Finally, a status LED is set to ON if the rf_busy flag is active.


On the computer side I also modified the example provided by Objective Development. I added some code to parse arguments from the command line. I also wrote a function to create the payload byte. It takes arguments such as lamp number, on/off, broadcast.

The computer software uses libusb to communicate with the microcontroller.

I also created a small php script to call the commandline computer program when buttons on a web page is pressed. Open the webpage on your Android/iPhone and control the lights! :D

Step 16: Hardware: Prepare the Box

I have a nice little box that I want my project to live inside.

A couple of things had to be done to make this work.

1) The smallest circuit board i had was too small, and the next step up was too big. It had to be cut down to size. Easy enough. I just use a carpet knife and cut along the line where I want to cut. Do this 3-5 times and just break off the part you want to remove. I also had to do some dremeling to make room for some plastic bits inside the case.

2) The USB port needs to be accessible from the outside, so dremel away! I printed a template with the USB plug's dimensions and taped it to the case. I then used a dremel "router bit" to dremel it out. This bit can be drilled in, then moved sideways to cut out larger holes.

3) I added some spacers to keep the circuit board in place.

Step 17: Hardware: Build the Circuit

Finally, I get to use my soldering iron :D

The RF module takes up almost half the space inside the little box, so I had to make the circuit very compact.

I put everything as close together as I could and used magnet wire to make connections.

This is the first time I used magnet wire. It was great to work with! Even better than Kynar wire. I got the idea from this Instructable:

I managed to squeeze everything in using a little over half the board. The RF module fits perfectly in the remaining space!

Step 18: Hardware: Alternative RF Module

If you don't want to sacrifice your remote control, you can also buy an RF module.

The oscillator on the RF module has the text 433.92 written on it, so I assume it is a 434 MHz transmitter.

Sparkfun has a 434 MHz wireless transmitter that only costs $3.95.

Step 19: Check If It Works

Time to see if all my hard work has payed off.

Everything works :D

Also, it can switch the lights a lot faster than the original remote :)


hubi made it! (author)2016-11-11

Really good instructable. But I did not use such expensive tools for analysing.
I used open logic sniffer program with an Buspirate and 433MHz receiver Module.
But I have now built stef mientkis spectrum analyzer and used it that way.

hubi made it! (author)2016-04-08

Very good instructable.
It worked on Klik aan Klik uit remote switches. Instead of buying an expensive logic analyzer I used an Bus Pirate I already had.

diy_bloke made it! (author)2016-01-27

Though usually I get reasonable results with an Tf sniffer, there are those remotes that though I know they work on 433 Mhz just are not picked up by the sniffer.
Logic probe is indeed very handy in those cases

Arizno made it! (author)2014-06-20

wow, checksum calculation. my head just exploded.

mdobariya made it! (author)2013-12-22

just few minute back, I post a thread
, but now I found very useful page(this)..
I have not read whole article but ,, it seems very useful for me..
thanks to author of this post.. chr

ammyent made it! (author)2013-01-14

G8 Work........

ammyent made it! (author)2013-01-14

G8 Work

CalcProgrammer1 made it! (author)2012-08-17

Bought a 5-pack of these things (US 120V version) and will hopefully have them next week! I really hope they have the separate radio chip like yours, this is such a clean way to do it (opposed to the soldering wires on button pads). If it has a standard 433MHz transmitter I might buy one just so I can keep the remote and still have PC/network/phone control.

Ultimate goal is a home automation system driven off a RasPi, with web interface, timers, sensors, etc.

Wire54321 made it! (author)Wire543212012-11-30

Link so i can buy some too please

CalcProgrammer1 made it! (author)CalcProgrammer12012-12-17

They didn't work out too well, ended up buying some from Walmart (Holiday Time brand, seasonal only) that were 3 to a pack (bought 2 packs). The 5-pack only had toggle buttons, they didn't have different commands for on and off. I did the same method of reverse engineering the protocol and used an ATTiny to reproduce the signals. I did my own Instructable about it as well.

janisalnis made it! (author)2012-04-29

Like your tutorial very much.

It inspired me to put togather an instructable too.

Can one use voltage doubler for RF transmitter using 2 capacitors and 2 diodes.
Sorry, I put your picture about voltage booster in the description. Is it OK or should I remove it.

007fred made it! (author)2011-03-08

very good, its great !

blackghost made it! (author)2011-02-16

i love how thorough your explanations are !
well done
you made me interested in taking my circuits course again ha ha

Nostraquedeo made it! (author)2011-02-01

cool thanks

camdenhersh made it! (author)2011-01-31

i have absolutely no experience with building things like this but im starting my studies in electrical engineering soon and i want to build something cool like this very badly. any thoughts or suggestions?

EngineeringShock made it! (author)2011-01-31

This deserves to win the contest =)

helllordkb made it! (author)2011-01-30

I was an EE student and this instructable was fantastic. It was an excellent walkthrough that teaches you the theory of digital circuits through a custom/cool and practical implementation. Awesome Logic analyzer btw, gonna pick up one of those for myself perhaps to replace the one i hate. Incredibly well done and really invaluable. This is like a digital control programming class and a lab in ONE instructable. Just amazing.

Nice Oscilloscope btw, looks like an expensive one. Sparkfun has a really nice usb oscilloscope just like the logic analyzer you used/referenced. Both of them are at the bottom of their tools page. I'd love to see this done with some of the xbee units they sell, but doing it this way might be cheaper.

jonnyt6 made it! (author)2011-01-30

Thanks for the excellent explanaition and idea!!!!
its nice that you explain the logic and order.
keep it up!

tundrawolf made it! (author)2011-01-27

This is an awesome inscrutable. It has helped me a great deal with digital circuits. Thanks again.

rhkramer made it! (author)rhkramer2011-01-28

Some projects are, I'm sure, quite inscrutable--this doesn't sound too bad. ;-)

tuleele made it! (author)2011-01-27

This is exactly why this site and DIY is AWSOME!

pixiandreas made it! (author)2011-01-27

Hello Everyone!

Realy nice prodjekt :-)

There is a product from a swedish company named tellstick.
I have run this i 4 years with linux and windows and itś very easy to set up and work like a charm
there is also many 3part application.


itaross made it! (author)2011-01-27

This is simply AMAZING!
This is what i was looking for! V-USB + RF+Android !
How can i're the best (:
Best instructable I've ever read!

ClaudioDonate made it! (author)2011-01-27

Very very nice. Cool beginners guide to reverse engineering. Thanks for that!

dagob made it! (author)2011-01-27


yizhak made it! (author)2011-01-27

Isn't the zener diode reverse connected in the schematic?
We want the diode to reverse bias, not to forward bias.

studleylee made it! (author)2011-01-27

Very Well Done!!!! -Lee

davidprosser made it! (author)2011-01-27

This is pretty cool. For my A-Level electronics project I reverse engineered an RGB LED remote that I got cheap of eBay, found the protocol much like you, and used it to control my own coloured lights which decoded the protocol! Cool

polossatik made it! (author)2011-01-27

Don't turn it on, take it apart!..

I assume you are also suffering from an eevblog overdose? :)

nice writeup, cheers!

maltep made it! (author)2011-01-27

I've published a similar project some weeks ago (but more protocols and pcb available):

javipz made it! (author)2011-01-27

Nice work!

augustoyeung made it! (author)2011-01-27

That's COOL!
I understand you can control the mcu by PC through USB, but how do you control the PC by cell phone?!?! By blue tooth?! wifi? How?!!?

RetroPlayer made it! (author)2011-01-26

Another option is to purchase the encoder ICs that most of these remote systems are based on. I picked up several encoders and decoders on ebay for a similar project. Had to order from China, though.

They are usually PT2262 (encoder) and PT2272(decoder)

I think this is awesome that you decoded the protocol, however. Lower parts count, yeah!

woodega made it! (author)2011-01-26

Excellent! I have fairly rudimentary electronics knowledge, so this was practically a tutorial on using a logic analyzer and reverse engineering communication protocols. Not just a quick how-to, but something that I can take as a beginning step for doing similar stuff. Thanks!

one2one made it! (author)2011-01-26

Nice: here is something similar that i did
the kit was cheap (15€, 2 RF outlets modules and the remote control)

H3PO made it! (author)2011-01-26

to do the thing with an rfm12 module, take a look at ethersex. there even is another libra set on the compatibility list, so i think it should work out of the box.

johnnyrun made it! (author)2011-01-26

can we have the pcb layout??

chr made it! (author)chr2011-01-26

There is no pcb layout, it is soldered on a protoboard..

johnnyrun made it! (author)johnnyrun2011-01-26

Only now I see that you published .sch too... sorry.
very funny project.
I've made it in the lame way (16f627 + transistors), but it should be fine to control a lot of other receiver.
tnx a lot

TOCO made it! (author)2011-01-25

Very impressive!

jensenr30 made it! (author)2011-01-25

This is so BOSS! its awesome!

About This Instructable




Bio: I like microcontrollers and LEDs :D
More by chr:Reverse Engineering: RGB LED Bulb with IR remoteReverse engineering: USB controlled home automation hackLED Cube 8x8x8
Add instructable to: