Linux Home

(Last updated: Saturday February 24, 2007)

X10 Sniffer By Neil Cherry

I love the smell of AC in the morning ....

Well I really stuck my foot into this one. While up on the net I made the statemetnt that I wasn't happy with the current crop of X10 controllers and that I could probably do a better job of it myself. So Brian Karas of Future Standards ( challenged me to do something about it. This X10 sniffer is just a tool to help me debug the signals.

Now as far as controllers go the CM11A has it flaws which include locks ups and the TW523 can't detect extended commands or all the bright and dim commands (just the first and 3rd bright/dim command will be received).

- The X10 protocol Basics

First I needed to fully undertstand the X10 protocol. The good news is that X10 has published the protocol and it is a relatively simple protocol. Also there have been enough articles in Circuit Cellar and the net to cover the protocol that we may be beating a dead horse to death. But there are a few areas where I haven't seen a lot written or the subject clearly covered. A couple which I check out with the X10 sniffer.

- The Bits

The Protocol is relatively simple, a half bit pulse of 120KHz for 1ms long within 100us of a zero crossing. A combination of a pulse on the first half an AC cycle and none on the second half is a 1 bit (1 and 0 half bits = a 1 data bit) and a combination of no pulse on the first half and a pulse on the second half is a 0 bit (0 and 1 half bits = a 0 data bit). Other bit combinations have other purposes as we'll see in a minute.

- The Commands

There are 3 types of data packets, the first and most common is the normal X10 command packet. The next command is the Dim/Bright command and the last is the extended command.

- Device codes

A Device has a House code and a Unit code (House code + Unit code = Device code). The default for most devices out of the box is generally A1. Actually a single house can use all the house codes. I tend to assign a house code to a particular room or area such as the backyard. This allows me to break up the devices into groups. An example would be the living room lights. I tend to put most of the main lights on 1 device code. But other accent lighting may use another device but still use the same house code.

- Normal X10 commands

The majority of X10 commands are of this type. When we want device A1 to turn on we send 2 halves of a command. I like to break it up into 2 parts, the first part is the device identifier and the second is the device command. The first half is 22 half bits long (including the Start of header or SOH). It is sent twice then there is a 6 half bits pause (zeros on both halves of the cycle). Then the final device command which is also 22 half bits long and sent twice. We've sent A1, A1, pause, AOn, AOn.

But what if we want to turn on A1 and A2? Well X10 did a good thing here. First we send the A1 command (twice) then we pause, then we send the A2 command (twice) then we pause and finally we send the On command (which really is the A on command). We can do this for all the devices in a single house code and in no particular order. So we can do A1, A2, ... A16, AOn and all those devices will turn on. We shouldn't mix House codes as an AOn will not turn on a device on the M house code.

Having said that I did do some experitmenting. Using devices created by X10 and Oullet. I sent the following commands A1 C16 AOn COff. Both devices behaved as if each command was sent as A1 AOn (it runed on) and C16 COff (it turned off). So each device seems to keep it's own state machine. I'm not sure how far you can go with mixing commands or for how long these states will stay in the device. So do be careful.

- The Dim and Bright commands

X10 sells lamp modules and appliance modules. One of the differences is that the lamp modules respond to dim/bright commands in addition to the On/Off commands (plus a few other commands). The Dim/Bright commands differ from the above in that there are no pauses between commands.

- The Extended commands.

The Packets

A packet of bits starts when a train of 1110 (4 half bits) is sent. The then next 8 half bits are house code a

   SOH    A        1 
  1110 01101001 01101001 01 (sent x2, no pause between the 2 packets)

  000000 (Pause, 3 AC cyles or 6 zero crossing)

   SOH    A        ON
  1110 01101001 01011001 10 (sent x2, no pause between the 2 packets)

- The TW523

The TW523 is a 2 way communication device, it can send all of the commands including Dim/Bright, Extended commands and Extended data commands but it will not recognize extended commands or Extended data commands and it will 'lose' every other Dim/Bright command.

At the heart of the TW523 is an analog shift register chip. It waits for the start of header and then begins to accept the data to follow. It needs to see the data twice (ED: What happens if the data isn't sent twice or the second packet get corrupted? I need to experiment.)

- The X10 sniffer (Frankenstien's monster)

I was actually surprised that in the 15+ years the TW523 has been around that now one has tried this 'hack'. After sitting down with the TW523 Tech Notes and Uncle Phil's online X10 articles I figured out that if I simply replace the analog shift chip by 2 transistor amps I would get all the bits from the AC line. This included any stray signals and protocol violations.

So I broke out the soldering iron and solder-pult and sacrificed a TW523 (photo X). Out came the chip and I was left with a TW523 with no brain. One of the first things I did was to bend up some wire and solder them in at certain test points. I also took apart another working TW523 and put both side by side. This made it easier to take measurements and verify what I was seeing in the circuit. I borrowed a Tektronix 100MHz Digital Storage Oscilloscope (DSO). Having one of these made my job of testing much easier to figure out.

Now at this point I wish to warn those would be tinkerers that this circuit contains live line level AC. That the sytem ground is not isolated from the AC neutral. This circuit is very hazardous and can kill you. Also note that the DSO that I am using is isolated from the line voltage by a 1:1 transformer. Not doing this will allow the DSO's ground to contain live AC. This tends to do very bad things to the DSO.

Now where was I, Frankstein, sacrifical virgin, angry AC gods, oh yea I was about to introduce the breadboard (see photo X). So I started wiring up my transistors.

- (Basic Transistor theory here and explaination of the new circuit)

Once I got a working circuit it was time for a microprocessor. I have plenty to chose from, 6802's, 6809's, 68K's, Z80's, 6502's, 68HC11's and 16F84's. I really prefer a nice flat memory space but I also like inexpensive tools. Having played with the PIC16F84 for a while I decided that I would get the Microchip In Circuit Debugger (ICD). The ICD has an a 16F877 on it along with a proto type area. At ~$200 this wasn't a cheap toy (I have a strict budget that all my hobbies share, including cycling). I've discovered that it was well worth the cost in the reduction of debugging time. I also played with the C2C compiler (, I've discovered that there are things that don't work very well. But I was able to make the compiler work on this project.

- Collision detection and avoidance

Well basically there is none from the TW523. Because it hides the first half of the twice sent packet you can't know when a packet is being sent. The X10 CM11A and RR501 are reported to do collision detection but I'm not sure how they go about doing it.

- Sniffer software

- Output

What we're looking at here is the RS232 output of the X10 CM11A and the modified TW523. The output of the TW523 is a very simple output. If there is a 1 bit on the AC then output a 1, if there is a 0 bit then output a 0. If the it see 6 zeros in a row then stop the output until another 1 bit is see. The reason for the 6 zeroes is that that is what X10 considers enough silence to output data. The device doing the actual transmitting of the X10 commands is the CM11A. And it doesn't look like it's doing a very good job of it.

Bad packet transmission caught in the act

  X10 Sniffer Raw Ouptut

                                       SOH     A         2                 
                 x x x x x x x x x x x      0 1 1 0   1 1 1 0 0 Pause
  04 05:42:50 - 1010011010001010100001 1110 00101001 1010100101 000000
  04 05:42:51 - 1110 00101001 0001101010 1110 01101001 0100100010 00000
  04 05:42:55 - 1000000
  04 05:42:55 - 1011000010101 1110 01100001 1001010100 0000
  04 05:42:56 - 1010011001000101101010 1110 01100100 0101101010 00000

  CM11A output (using Dan Lanciani's X10d)

  04 05:42:50 - R A02 2 Unit 2
  04 05:42:51 - R A20 2 Off
  04 05:42:55 - R O14 8192 Unit 14
  04 05:42:56 - R O20 8192 Off

Good packet transmission

  X10 Sniffer Raw Ouptut

  04 09:27:48 - 1110 01100101 1001010101 1110 01100101 1001010101 000000
  04 09:27:48 - 1110 01100101 0101101010 1110 01100001 0101101010 00000

  CM11A output (using Dan Lanciani's X10d)

  04 09:51:44 - R A01 1 Unit 1
  04 09:51:45 - R A20 1 Off