I was looking for a cheap way to interface my PIC microcontroller projects with my X10 home automation system. Plug-in serial X10 interfaces have to be … plugged into the wall, so I thought a good alternative would be to hack a wireless X10 remote. It worked… here are the details.
Probably the easiest (and most proper) way to inject X10 signals into your household wiring is to use a plug-in serial adapter. The PL513 and TW523 from X10.com (cheaper) or smarthome.com (no annoying popups) are great examples. The key reason you’d use one of these plug-in solutions over what I describe here is if you wanted to send and receive X10 signals – the PowerLinc TW523 is a two-way serial-X10 interface for about the same price, while the hacked wireless remote can only send signals. (Hopefully obviously, this will require that you have an X10 wireless receiver). I recently got a RKR24 model X10 wireless remote for free as a throw-in for my order from smarthome.com. They are under $20 if you have to buy one. This same theory would probably work with other X10 remotes, but I haven’t tested any. Here’s what the RKR24 looks like (courtesy smarthome.com).
|
At first, I thought I would just hook up the PIC I was programming, so it could electronically “push” the buttons on the remote. This would have been very easy to do, and would have let me send On/Off/Dim/Bright commands to 2 units on the same house code – good enough for what I was trying to do. However, when I actually opened up the remote, I was plesantly suprised to find it was based on a PIC processor – a 12C508A, shown here after I ripped it off the board.Once I saw the PIC, I got ambicious and decided to try and replace its functionality entirely, so that instead of just “pushing” buttons on the remote, I could hopefully send any house/unit code I wanted. |
The X10 wireless RF protocolFirst, I popped open the remote. BEFORE I removed the stock PIC 12C508A from the circuit board, I connected my incredibly-useful LogicPort Logic Analyzer to the PIC pin that was attached to the RF transmitter circuit. Unfortunately I didn’t take any pictures until I finished the project, so you have to bear with. Here’s an example of what the spectacular LogicPort software showed when the original circuit sends the A1-ON command. (I left the remote running on its own battery for these tests, and just manually pushed the buttons on the front to send various X10 commands).
The X10 command transmission starts on the left of the image above, going right. This is the raw digital signal leaving the PIC towards the RF circuitry and eventually to the antenna. First, you can see the “preamble”, or wake-up signal that alerts the receiver to a new transmission. The preamble is to simply send a 1 for 9 msec (starts at marker A in the image above), then a 0 for 4.5 (starts at marker B). After that, you can see actual 0′s and 1′s that make up the command transmission (the first bit starts at marker C, the second bit at marker D). In this example, the transmission starts out with 110101111101110… I manually decoded many of these bitstreams and spent a significant amount of time reverse-engineering the X10 wireless protocol. I couldn’t find any official spec’s anywhere, and only later found the wonderful references. If you’re curious the thing that really hung me up was that if you want to transmit a logical “1″, you send a 1. However, if you want to send a logical 0, you have to send a “1″, then a “0″. So to send the number 5, for example, which in binary is 101, you’d actually have to send 1101 across the airwaves. (not following me? don’t worry, it took me a while.) The first link below describes the protocol (and this tricky detail) well, and the second link provides “real world” samples of pretty much every command.
Wiring up the transmitterIn general, the remote is easy to take apart and put back together, so don’t be scared. You only have to make a total of three (3) solder joints, and two of those are super-easy. The first thing you have to do, and probably the hardest, is remove the original PIC. Unfortunately, it’s not one of the reprogrammable flash memory PICs, so there’s not much you can do with it but chuck it in the trash. You won’t need the photo above to find the PIC on the board – it’s the only thing that looks like a chip. I’m not sure what the best way to remove surface-mount chips without a hot-air tool, but typically do it by running a small wire under one row of pins, and pulling gently outward on both ends while I heat up the pins with my soldering iron. You have to be kinda careful to make sure you don’t jack up the pads on the circuit board – there IS a lot of room for slop here. On the left, you can see the circuit board with the original PIC processor removed. There are two wires in this picture – blue and white. You DON’T need the blue wire – I just attached it ’cause I had an extra hole in my connector and thought it might be useful to still have one of the buttons work. The important wire is the white one in the top right corner of the picture. It’s connected to the positive side of the LED light, which is conveniently directly connected to the pin the PIC was using to communicate with the RF circuitry. This gives you something easy to solder to (so you don’t have to try to solder to the pad the PIC was attached to). This was a cool circuit design on someone’s part, because the LED flashes nicely during transmission – I wonder, though, if you would get better range by replacing it with a diode (or just a solder bridge). I included the highlighted picture on the right, to help show where the important parts (to us) of the cirucuit are. You would want to solder your wire to “bottom” lead of the LED, or in the picture on the right where the small orange line (representing your wire) intersects with the red line (representing the connection to the RF circuitry). There’s a handy hole you can use to run your wire through the board to the other side. The purple highlight shows where the original PIC sat on the circuit board, and the yellow highlight covers the RF circuitry. This would be a good time to point out that I’m not that great at analog RF circuit design. I like to avoid it like java/j2ee programming. I’m sure many people could reproduce the (very simple) RF circuitry here, or use a design of your own, very easily. It was easier for me to just re-cycle it. Wiring up the power and connector
|
Here’s the remote with the body reassembled. Actually doing this work should take well under 30 minutes. You only have to connect one pin (the transmit pin) to the PIC, and the power and ground pins. This circuit was designed (by someone else) to use a 3V battery for power, so you should probably stick with that. I used a 5V supply and everything works fine (although it’s possible something will burn out or accidentally increased the transmit range).
Software on the new PICI write software in C and compile it with a licensed version of the CSS compiler. I really havn’t tried other compilers since this one has worked fine for me. It integrates nicely with MPLAB and is reasonably well documented. I’m sure you could easily re-use the X10-specific functions in any C compiler for almost any processor platform that has a digital out. Here’s the X10-specific code that worked for me. This function sends the preamble: void x10_sendpreamble() {output_low(X10PIN); delay_ms(40); // delay before start output_high(X10PIN); delay_ms(8); // high output_low(X10PIN); delay_ms(4); // low return; } These two functions send a single bit and byte of data, respectively: void x10_sendbit(int thebit) {output_high(X10PIN); delay_us(400); output_low(X10PIN); delay_us(700); if (thebit == 0) { delay_us(1100); } return; } void x10_sendbyte(int thebyte) { int8 i; for (i=0;i<8;i++) { x10_sendbit(shift_left(&thebyte,1,0)); } return; } Finally, here’s the meat of the code that assembles the proper bits to send. It doesn’t have support for dim/bright, but that would be easy to add. void x10_send(char hc, int unit, int action) {int ufcbyte; // unit function code x10_sendpreamble(); // here we set the house code if (unit > 8) { hc=0b00000011; } else { hc=0b00000111; } switch (hc) { case ‘P’: { hc=hc&0b11001000; break; } case ‘O’: { hc=hc&0b11011000; break; } case ‘N’: { hc=hc&0b11101000; break; } case ‘M’: { hc=hc&0b11111000; break; } case ‘L’: { hc=hc&0b00101000; break; } case ‘K’: { hc=hc&0b00111000; break; } case ‘J’: { hc=hc&0b00001000; break; } case ‘I’: { hc=hc&0b00011000; break; } case ‘H’: { hc=hc&0b01001000; break; } case ‘G’: { hc=hc&0b01011000; break; } case ‘F’: { hc=hc&0b01101000; break; } case ‘E’: { hc=hc&0b01111000; break; } case ‘D’: { hc=hc&0b10101000; break; } case ‘C’: { hc=hc&0b10111000; break; } case ‘B’: { hc=hc&0b10001000; break; } case ‘A’: default: { hc=hc&0b10011000; break; } } x10_sendbyte(hc); x10_sendbyte(~hc); // send the house code and its inverse // here, we set the unit and function code bits switch (action) { // need to support dim/bright case 0: { ufcbyte=0b10000111; break; } // off case 1: { ufcbyte=0b10100111; break; } // on default: { ufcbyte=0b11111111; break; } // A1on } switch (unit) { case 8: { ufcbyte=ufcbyte|0b00000000; break; } case 7: { ufcbyte=ufcbyte|0b00010000; break; } case 6: { ufcbyte=ufcbyte|0b00001000; break; } case 5: { ufcbyte=ufcbyte|0b00011000; break; } case 4: { ufcbyte=ufcbyte|0b01000000; break; } case 3: { ufcbyte=ufcbyte|0b01010000; break; } case 2: { ufcbyte=ufcbyte|0b01001000; break; } case 1: default: { ufcbyte=ufcbyte|0b01011000; break; } } x10_sendbyte(ufcbyte); x10_sendbyte(~ufcbyte); // send the unit/function code and inverse x10_sendbit(1); // gratuitous 1 at the end… return; } To wrap things up, here’s my software sending an X10 code as seen from the LogicPort:
|
I recently got a
At first, I thought I would just hook up the PIC I was programming, so it could electronically “push” the buttons on the remote. This would have been very easy to do, and would have let me send On/Off/Dim/Bright commands to 2 units on the same house code – good enough for what I was trying to do. However, when I actually opened up the remote, I was plesantly suprised to find it was based on a PIC processor – a 12C508A, shown here after I ripped it off the board.Once I saw the PIC, I got ambicious and decided to try and replace its functionality entirely, so that instead of just “pushing” buttons on the remote, I could hopefully send any house/unit code I wanted.





If all you want to do is to send signals wireless to an X10 unit, look for the CM17A: http://www.smarthome.com/1141.html
It’s discontinued, but thousands and thousands of them were basically given away with the “Firecracker” kit that X10.com used to sell for only $6, so finding one on ebay or elsewhere shouldn’t be too difficult. Heck, I’ve got two or three just lying around in my bucket of random parts.
Basically, it’s a little serial dongle (with serial passthrough even) and it requires no power source, no connection to the house wiring. It just sends wireless signals to any of the X10 wireless receivers. It can send any signal and the protocol it used has been reverse engineered all to heck and back, so that you can easily find source code to use it. Sends for about 30-40 feet to the transciever modules, which then resends the signal on household wiring. Sends only, it has no receive capabilities. Works great.
Otto – the Firecracker kit requires a full-blown plug-in RF transmitter (ie: not battery powered). From your link: “Note: Requires an X10 Plug-In RF Base (#4002 or #4005X) for proper operation.” Not that the plug-in base station is expensive… it’s just not quite as portable as this project.
> the Firecracker kit requires a full-blown plug-in RF transmitter
The CM17A “Firecracker” is the actual transmitter unit. It plugs directly into and is powered by a 9-pin PC serial port, so it would need 5VDC at most (probably less). There’s a $40 kit which includes the CM17A, plug-in receiver, and other goodies at http://www.x10.com/automation/ck18a_s_ps32.html .
> “Note: Requires an X10 Plug-In RF Base (#4002 or #4005X) for proper
> operation.” Not that the plug-in base station is expensive… it’s just not
> quite as portable as this project.
I guess I’m confused. I thought this was a hack to take the “cheap” two device/one house remote and enable it to support more devices/house codes. That implies you already have the plugin RF receiver (aka “X10 Plug-In RF Base”). Or did I miss the point of this hack completely?
Very interesting read and great links. Thanks!
The link says “Note: Requires an X10 Plug-In RF Base (#4002 or #4005X) for proper operation.”
That is just the regular reciever that you would need anyways.
http://www.smarthome.com/4005x.html
amazing. you rock. can you hack a trinity7 remote aswell? i need to unlock a garage. keep it quiet though!!
Ned – No, it doesn’t. Like I said, I’ve got three of the bloody things. I use them for my lighting controls.
The “plug in base” is a standard transciever module. You have to have one of these to use *any* of the wireless X10 stuff. The CM17A serial dongle (or CM19A USB dongle) both send the signals in exactly the same way that your keyfob module does. The same receiver units receive them.
I know, I’ve got three or four the keyfobs, at least three of the serial dongles, four 18-button remotes… I ordered a bunch of the gear from X10 back when they were practically giving it away.
Otto – Okay, okay, I finally get it. Not only does the CM17A do what I did here, but it does it better: You can just talk to it via serial, rather than having to modulate the RF signal yourself. Also, it looks like you don’t need to externally power it. So, this was a good learning experience for me, but now I’d recommend the next guy just go after an old CM17A!
Thanks for your patience! Ned.
Hi Ned
Great reading!
I know nothing about pic controllers and reqd programming do you know of any beginner/tutorial links?
I would like to learn more, as it seems you can do so much with them!
Utmost sincerity
Jay