Cheap Arduino Controlled Light Sockets - Reverse Engineering RF

79,227

621

42

Posted

Introduction: Cheap Arduino Controlled Light Sockets - Reverse Engineering RF

Formlabs Contest

Finalist in the
Formlabs Contest

Smart lightbulbs cost your firstborn child. Which is a shame, because smart lights unlock tremendous potential for home automation, energy savings, and all sorts of cool projects.

If only there was a way to control your lights without breaking the bank...

And now there is! For $19 on Amazon, you can get a 4-lightbulb kit from China that ordinarily is limited to 4 channels from a single remote...but with some creative hacking, can be used to control an unlimited number of channels using an arduino and a very simple RF module!

Here's a video of them in action as part of our smart bathroom project (Instructable for that coming soon!):

Think this is awesome? Don't forget to favorite it and follow us on Facebook!

Time required: 1-2 hours

Total Cost: $19 for four sockets ($5/socket), ~$20 for a transmitter

You should know:

  • How to program an Arduino (see here)
  • The basics of using a Bus Pirate (see here)

Materials:

Tools:

Step 1: Reading the EEPROM

We'll start by cracking open one of these light sockets and reading its memory. Grab your screwdriver and remove the two phillips screws holding the housing together. The case should fall open and reveal the PCB inside.

If you look around, you'll see a few capacitors, some diodes, a big box (the relay), a long IC (the microcontroller), a separate board tacked on (the RF receiver), and a little 8-DIP chip marked 24C04 - this is the EEPROM that stores the RF command to turn on the bulb.

Let's take a closer look at what the memory chip holds, shall we? Using the bus pirate and the datasheet for the EEPROM chip, wire up a circuit like the one shown. You should have:

  • Bus Pirate VCC -> chip VCC (and to VPU, the pullup pin of the Bus Pirate)
  • Bus Pirate GND -> chip GND
  • Bus Pirate SDA (MOSI, Orange for Sparkfun BPs) -> chip SDA
  • Bus Pirate SCL (CLK, Yellow for Sparkfun BPs) -> chip SCL
  • Bus Pirate VPU -> Bus Pirate VCC (the pullup I/O pins are driven from this pin)

Next, let's run a script that will dump the EEPROM data to a file using the I2C circuit we just set up. Using the terminal or command line, navigate to the folder where you downloaded i2c_dump.py and run it as follows:

It'll produce a .hex file showing the hex values of the data.

Open up the .txt file. If it contains nothing but 0x00 or nothing but 0xFF, chances are you need to check your circuit and re-run the dump. If you see a few different values towards the start of the file and a bunch of 0x00's after, you have a successful hex dump!

It's a good idea at this point to try dumping a couple of the other bulbs to see what values change in this code. Don't worry if the hex dumps don't make sense yet, but you should notice that only one specific value in them is changing. Hmmmm...

Step 2: Transmitter Disassembly/Cracking the Code

Now it's time to build a circuit that will mimic the incredibly cheap plastic remote. Open up the remote by removing the battery case, battery, and screws. You'll see a couple pushbuttons, some tiny components, a metal crystal package (marked with R315A), and an IC with HS1527 stamped on it. The "315" on the crystal sounds very much like we're operating a 315MHz transmitter, and a quick look at the HS1527 datasheet tells us that we're dealing with an OTP encoder transmitter.

Page 2 is particularly interesting, showing an output format of a 20-bit code and 4 data bits. The code is used to prevent any random device on the same frequency from accidentally turning the lights on, since there's an approximately 1/1,000,000 chance that a random broadcast will match the code. The four data bits correspond to which RF socket is being turned on - this is the last four bits of the hex value that changes between each of the socket's EEPROMs.

So we know the data bits are where the hex data is changing. What about the 20-bit code? Couldn't it be anywhere in the EEPROM? Well, it turns out that programmers are lazy. They really don't want to create extra work and more code, so when reading a serial transmitter broadcast they'd likely want the comparison data arranged in the same way in memory. Looking at one of the dumps, we see something like:

5a5a 0c5a c18c 285a bea3 915a ffff ffff

On another dump, we see:

5a5a 0c5a c18c 285a bea3 925a ffff ffff

And so on. Counting 20 bits to the left of the changing digit (that's 5 hex values), we get the code 0xBEA39. With any luck, we can shove this into a data packet and blast it at the light sockets, and they'll respond by turning on or off!

Let's get to building a new transmitter!

Step 3: Let's Make an Arduino Transmitter!

Wire up your arduino to your 315MHz RF Link Transmitter chip. To do this, you'll want to look at the datasheet and match:

  • Arduino GND -> Transmitter GND (pin 1)
  • Arduino P7 -> Transmitter Data in (pin 2)
  • Arduino 5V -> Transmitter Vcc (pin 3)

Cut a piece of wire approximately 23.8cm long and attach it to the ANT pin (pin 4) on the transmitter. This will be our antenna.

Now grab our Arduino files (original author: salanki) and change the value of "char *address" in hs1527_rf_light.ino to the 20-bit address you found in the previous step. Upload this to your board. The default code will toggle each of the four lights in sequence.

If all of this works, you now have four individually addressable wireless light sockets!

Step 4: Optional: Simultaneous Toggling

Our use case was in the bathroom - we had a set of four overhead lights that we wanted to turn on and off all at the same time. But with the current transmitter code, you can clearly see when each light turns on. How do we fix this?

Modify the EEPROM, of course! We'll just make the activation data bits the same for each of the transmitters.

Crack open each of the RF sockets, and do the following for each:

  • Attach the bus pirate (same way as before)
  • Type "[ 0xA0 0x00 ]" in the bus pirate terminal (This sets the read pointer to 0x00)
  • Run "[ 0xA1 r:16 ]" which will print the first 16 bytes. Note the 0x91/2/4/8 value is at position 0x0A (i.e. the byte #10 counting up from zero)
  • Write a new hex value by running "[ 0xA0 0x0A 0x91 ]". This writes the value 0x91 to position 0x0A.

When you finish with all the sockets, each one should be keyed to button 1 on the transmitter. If you re-run the test program again, you'll find that all the lights turn on with only one code!

Similarly, we can use the bus pirate to change the 20-bit code, letting us turn on more than four lights at a time with a single code. Try it and see what happens!

Step 5: That's All, Folks!

With your new RF-hacking powers, you can now build smart, computer-controllable lightbulbs for a mere $5 a pop!

If you like this Instructable, don't forget to favorite it and follow us on Facebook


References:

The RF light sockets: http://www.amazon.com/Vktech-Wireless-Remote-Contr...

The HC1527 chip datasheet: http://sc-tech.cn/en/hs1527.pdf

EEPROM found in the bulb sockets: http://www.atmel.com/Images/doc0180.pdf

Bus pirate pinouts (Scroll to bottom for Sparkfun pins): http://dangerousprototypes.com/docs/Common_Bus_Pir...

BusPirate Scripting in python: http://dangerousprototypes.com/docs/Bus_Pirate_Scr...

i2c_dump.py script for dumping EEPROM: https://gist.github.com/kost/592e96381ca3c97abe21

Viewing a hex dump in vim: http://vim.wikia.com/wiki/Hex_dump

The vpullup problem: http://dangerousprototypes.com/docs/Practical_guid...

HS1527 encoder original INO files: http://forum.arduino.cc/index.php/topic,99714.0.ht...

315MHz transmitter datasheet: http://dlnmh9ip6v2uc.cloudfront.net/datasheets/Wir...

Share

    Recommendations

    • Microcontroller Contest

      Microcontroller Contest
    • Spotless Contest

      Spotless Contest
    • Science of Cooking

      Science of Cooking
    user

    We have a be nice policy.
    Please be positive and constructive.

    Tips

    Questions

    42 Comments

    Using this library - https://github.com/sui77/rc-switch- I was able to easily decode/encode the signals. First I ran the ReceiveDemo_Simple sketch and intercepted the codes from the remote through the serial output (in my case 491521, 491522, 491524,491528). Then I just changed the code in the SendDemo sketch (specifically, this code - /* Same switch as above, but using decimal code */ mySwitch.send(491521, 24); delay(1000); mySwitch.send(491521, 24); delay(1000);). Super straightforward!

    I dumped the EEPROMs of my set.

    Three have a very similar content (starting at 0x00):

    5a5a 0c5a 4609 885a 3cfb a15a

    5a5a 0c5a e00e 885a 3cfb a25a

    5a5a 0c5a 9ace 885a 3cfb a45a

    But then there is one which is different:

    5a5a 085a 3cfb a85a ffff ffff

    The 20-bit code got shifted to the left. So probably the code on the microcontroller reads in a different location. I'm under the impression that no two bulb kits are the same. (Please do not use these codes to turn my lights on and off)

    user

    Hello moojo, your first 3 sockets can be controlled by 2 different codes (different remotes)...

    First thank you for this I have LIFX Bulb and a SmartThings hub I was looking for a cheap way to had more IoT devices.

    I ordered the same bulb you linked from Amazon and I got a tow bad surprises. First I got two version of Light Bulb Holder, the one you got and another one totally different. Where there is only a 8IC dip (ST ED08) and somewhat a more advanced RF receiver, the remote is also different with a AD2262 Remote Controller Encoder (http://www.indreamchip.com/uploadfile/201301/7/103177117.pdf).

    The second surprise is, the extreme poor quality of construction, some the leg of the chip are turned apart. They didn't bother cutting the leg of a resistor which touch other component. On one of the attached picture you'll see that the circuit etching burned or disappeared, so they replaced it with a wire...

    None of this is your fault, obviously, I just wanted to let everybody know before someone burn their house or get electrocuted.

    Aside from this, I'll see if I manage to get the second one working with an Arduino, I'm not even sure if they work in the same frequency of 325.

    When I was looking at the circuit I was wondering, how do they convert 110v to 5v? I saw a 78L05, and 4 Diode for converting AC to DC, but there is no way the 78L05 is plug directly on 110DC. How do they do this?

    IMG_2878.jpgIMG_2879.jpgIMG_2880.jpg

    Did you find a datasheet on that ST ED08? I got a full set of 4 of those. I have not and I tried hooking it up to the bus pirate (even desoldered one and tried it out of circuit). When I try to give it power the bus pirate says "is there a short?" and won't power so I'm guessing it does not have the same pinout.

    Also, there is other writing on that IC: AFB422 if that helps at all.

    I have just bought another variant which has ST ED08 AFB422 in light bulb and ST F081 FB 445 in remote. In this one remote is generating same signal for all four light bulbs so they are not individually addressable. I at least managed to sniff binary data which is sent out so I can control all four bulbs at once. Full writeup is available at http://blog.rot13.org/2014/12/controlling-315-mhz-light-sockets-using-arduino.html

    remote.jpgsocket-top.jpgsocket-bottom.jpg

    Hello,


    I enjoyed the project, but wanted the wiring diagram for me to use in another project that does not require transformer!

    I look carefully.

    Hi, I also got one of those cheaply assembled sets with the

    ST ED08 AFB422 chip. I read your blog article which is very interesting. However I am able to address each bulb independently using the remote so this works as expected. I will analyze the signal using rtl-sdr like you did to see how it differs between bulbs.

    Do you have four pins on remote soldered together like I do? I didn't do that, and both of my remotes are same.