Cheap Arduino Controlled Light Sockets - Reverse Engineering RF

88K61842

Intro: Cheap Arduino Controlled Light Sockets - Reverse Engineering RF

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...

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)

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?

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

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.

No, mine looks reasonable. See picture.

Thanks. I de-soldered blob, and my chip has other three legs cut off! Now only first button works (but still on all four bulbs) which makes sense -- solder blob just makes all buttons behave like first one. This on the other hand makes me think that chips in bulbs have to be somehow programmed to respond to same code (as mine do). However, I don't have idea how to do that since there is no datasheet for chip.

Just a little more information: I tried hooking up one of the ST ED08 AFB422 chips to the bus pirate as if it was an EEPROM but no luck. So either the standard configuration is not correct for this chip or it's not an EEPROM.

They must have multiple suppliers for these because my remote looks like zzarbi's: with the big encoder chip and not much else (there are only traces on the reverse side).

Awesome write-up, thanks for sharing! We're surprised at how much variation there's been between versions, so it's awesome to see the community stepping in and filling in the gaps :)

Nice write-up. Thanks!

I could not find any documentation about it. I think this set is "reversed" instead of the remote being simple and the receiver having RAM and a Microprocessor. The remote is more complex and the bulb is much more simple. I haven't got the time to look though.

I wondering if you had figure out how they convert 110v to 5v ?
I have the remote controller with the same AD2262 encorder, could provide more detail on how you setup your arduino to control the lights ?

Yes I did! Again what they did isn't the best.

Basically they use a Resistor to drop the voltage, a few Diodes to redress it and a few capacitor to stabilize it (http://www.electronicecircuits.com/electronic-circuits/transformerless-power-supply) I had found a link with different design to do just that, with explanation of why you would not want to do this this way but I cannot find it. Their design is really bad if there is surge...

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.

This is a great hack for people who want to learn something, do it themselves, or who have a particularly custom need (such as a project that already uses an Arduino and needs to switch some lightbulbs). However, the new reality of the marketplace is that today you can go to a local home improvement store and buy just-released smart lightbulbs for far less than they cost just a few months ago, and there are more brands rushing to market (at least in some countries, including the US) according to industry announcements. So the idea that this is a way to save big money is not quite the incentive it was until recently. Still, it's a cool project.

More Comments