(Last updated: Friday August 31, 2007)
X10 CM15A interface Communication Documentation
- Document History
This page is a derivative of the work Woody (UsAndThem Home Automation Information!) and I (Neil Cherry - Linux Home Automation) did tearing apart the USB protocol and the Dan Suthers' protocol.txt file.
- Originally taken from the X10 web page, for the CM11A - Dec 25, 1996.
- Some mistakes corrected. DBS - Jan 1, 1997
- Created a more specific CM15A page, NJC - Nov. 19 2006
- The X10 CM15A
The CM15A is a USB to X10 power line and RF interface that comes with the Active Home Pro software. It looks like it's meant to replace the CM11A (serial to X10 power line transceiver) and CM19A (USB to RF transceiver). X10 says it can send and receive all 256 house/unit codes and even take the place of the PC Transceiver (CM19A) for controlling X10 Cameras. It can keep the state of all 256 house/unit codes and has extra memory for timers and macros. Like the CM11A it has battery backup for when the power fails. It appears not be able to send commands to just the RF but when monitoring a selected house code (you can have more than 1) it can send and receive that house code via the RF and Power Line. Macros can be downloaded to the CM15A which allows it to run without a PC. It appears not to have the problem that the CM11A did of a dangling communication cable sending arbitrary X10 codes.
- Here is the device driver for the CM15A and Linux: iplc-driver.tgz. Yes it says iplc, that's because I create a distribution for the Labjack, CM19A, CM15A and the Insteon USB PLC. The majority of the code is the same for all four device. Only difference between the four is the USB IDs. If you notice a Z-Wave driver in there, don't use it as it doesn't work.
- To Do list
This will be a nice long list for a while as this document has a long way to go.
- Clean up the HTML (XHTML). Right now I'm mixing new and old HTML as I'm more interested in the content than the exact format commands. This is also true of the CSS which I've taken a few short cuts with.
- I really need to double check the information contained in this document. This will require coding, testing and researching newsgroup message (comp.home.automation).
- I still have a ton of detail to add. Much of the little white boxes needs to be expanded on and put into understandable statements.
- And of course much needs to be added as I'm sure there is much that is yet undiscovered.
- USB protocol
- 0x81 - data from controller - read
- 0x02 - data to controller - write
For Windows you might try libusb and libhid. For Linux try my device drivers (I need to update them and provide a link here). For the folks running BSD I understand that there is a generic USB device that performs like my cm15a module. For other operating systems you'll have to do further investigation.
Below you will see a section of output from the 'cat /proc/bus/usb/devices':
T: Bus=01 Lev=01 Prnt=01 Port=01 Cnt=02 Dev#= 9 Spd=1.5 MxCh= 0 D: Ver= 1.10 Cls=00(>ifc ) Sub=00 Prot=00 MxPS= 8 #Cfgs= 1 P: Vendor=0bc7 ProdID=0001 Rev= 1.00 S: Manufacturer=X10 Wireless Technology Inc S: Product=USB ActiveHome Interface C:* #Ifs= 1 Cfg#= 1 Atr=e0 MxPwr= 2mA I: If#= 0 Alt= 0 #EPs= 2 Cls=00(>ifc ) Sub=00 Prot=00 Driver=cm15a E: Ad=81(I) Atr=03(Int.) MxPS= 8 Ivl=10ms E: Ad=02(O) Atr=03(Int.) MxPS= 8 Ivl=10ms
Note that the CM15A us using my cm15a device driver. If my system had been setup with the HID module loaded the cm15a would have been usbhid instead. This is a common cause of problems with using my device drivers. I am working on software that takes advantage of Linux's HID sub-system but I'm finding it difficult to use it with the select function (Select(2) - synchronous I/O multiplexing). I'm also working on a tty like driver for the USB devices. This will make it easier to incorporate these devices into Mr. House home automation software.
- X10 Transmission Coding (Overview)
The housecodes and device codes range from A to P and 1 to 16 respectively although they do not follow a binary sequence. The encoding format for these codes is as follows:
Decimal value House code Device code Binary value Hex value Function code 0 M 13 0000 0 All Units Off 1 E 5 0001 1 All Lights On 2 C 3 0010 2 On 3 K 11 0011 3 Off 4 O 15 0100 4 Dim 5 G 7 0101 5 Bright 6 A 1 0110 6 All Lights Off 7 I 9 0111 7 Extended Code 8 N 14 1000 8 Hail Request 9 F 6 1001 9 Hail Acknowledge 10 D 4 1010 A Preset Dim (1) 11 L 12 1011 B Preset Dim (2) 12 P 16 1100 C Extended Data transfer 13 H 8 1101 D Status On 14 B 2 1110 E Status Off 15 J 10 1111 F Status Request
- X-10 Transmission.
- Standard Transmission.
An X-10 transmission from the PC to the interface typically refers to the communication of a Housecode and Device Code combination or the transmission of a function code. The format of these transmissions is:
PC Interface 2+ bytes Header:Code ... 1 byte ACK
This format is typical of all transmissions between the PC and the interface with the difference being in the first transmission from the PC.
Example: To turn on the module A1 you send the following the CM15A:
0x04 0x66 0x06 0x61
where 0x04 is the command type X10 Address, 0x66 is the House code (high nibble) Unit code (low nibble0, 0x06 is the command type X10 Function and 0x62 is House code (high nibble) Function code (low nibble).
The Header:Code combination is configured thus:
Bit: 7 6 5 4 3 2 1 0 Header: < Dim amount > 1 F/A E/S
Dim amount (dims) is a value between 0 and 22 identifying the number of dims to be transmitted (22 is equivalent to 100%)
Bit 2 is always set to '1' to ensure that the interface is able to maintain synchronization.
F/A defines whether the following byte is a function (1) or address (0).
E/S defines whether the following byte is an extended transmission (1) or a standard transmission (0).
Bit: 7 6 5 4 3 2 1 0 Address: < Housecode > <Device Code> Function:< Housecode > < Function >
Note the function only operates for devices addressed with the same Housecode.
- Standard Transmission.
- X10 Reception
- General receive format
B1 - What (5A - Power line, 5B - Macro, 5D - RF) B2 - Data Bytes that follow D1 - Type of data (Data byte 1) : Dn - nth Data Byte, usually the House Code/Function code
- Standard Receive (00 X10 Address/01 X10 Function)
- Dims (02 Dim/Bright)
- Extended receive (08)
(5a0508313f0667) 5A - The what ID (Power line, RF, Macro, etc) 05 - Byte that follow 08 - Bit map type of data that follows 31 - data 3f - data 06 - data 67 - House code (high nibble) key code (low nibble) This should be interpreted as follows: 5A Incoming data 05 Bytes that follow 08 Function bitmap 00001000 => 4th byte following (i.e., 67) is a function byte. 31 Extended Type/Function 31 => Extended Preset. 3F Preset value = 0x3F = 63 (scale 0-63) 06 X10 encoded Unit code for Unit 1. 67 Hi = 6 = House code A, Lo = 7 = Extended code Dave Houston reports that: > N1 Extended Dim 63 (100%) gives 5A 05 01 87 06 3F 31 with the CM11A. > > It looks like they changed the order of some of the bytes from the CM11A > protocol. My guess is that the output of the CM15A would look like this: (5a0508313f0687) See the "Standard" and "Extended" X-10 Code Formats document for further details.
- Macro (0x5B)
- RF (0x5D)
The following information is taken from the x10.rf.txt document. This work was done by Edward Cheung, Ph.D. and Paul Gumerman.
The RF command seems to break the 'ID, count, type, data' format and appear to use a different format.
5D 20 F0 0F 08 F7 1111-0000 0000-1111 0000-1000 1111-0111 (note the even byte is the inverse of the preceding odd byte) 5D 20 F0 0F 28 D7 > A1 ON: > 5D 20 60 9F 00 FF 9F = NOT 60, FF = NOT 00. Binary 01100000 00000000 = CM17A A1 On. ---- From: Neil Cherry - view profile Date: Sun, Nov 14 2004 5:58 pm Email: Neil Cherry
Groups: comp.home.automation Not yet rated Rating: show options Reply | Reply to Author | Forward | Print | Individual Message | Show original | Report Abuse | Find messages by this author On Sun, 14 Nov 2004 21:21:40 GMT, Dave Houston wrote: Thanks for the info, I'll add that to my code comments for later. > Neil Cherry wrote: >>5) actually X10 commands come in 'packets' >> A1 ON is: >> 5A 02 00 66 >> 5A 02 01 62 > My guess is that 5A means PLC, 02 means two bytes follow, 00 means an > address and 01 means a function. Correct, sorry I forgot to add that: 5A PLC 5B Macro 5D RF Andy first discovered those. It was driving me nuts as I would get a 5D xx xx xx ... then 5A xx xx xx 5A xx xx xx. I couldn't figure out why until I remembered that I had an RR501 also plugged in. > Can you check to see what an extended PLC command looks like? Using a TI103 (It's the only thing I had available) and using this example from the manual: 3. Sending an extended code message to an extended code dimmer: To TI103-RS232: $>28001A013F31A013F312D# Response: $<2800!4B# I got the following back: 5A 05 08 31 3F 06 67 Dims are another matter. I tried to send 16 dims with the TI103 but the CM15A ignored it. When I send 1 dim with the Remote Controller I get this: 5A 02 01 62 Yeah I need that or it ignores the command 5A 03 02 0B 64 If I set the Remote Controller to C and hit dim once I get nothing. If I hit dima second time I get: 5A 03 02 0B 24 With the mobile controller (and the RR501 on a different letter, O) I get this: 5D 20 60 9F 88 77 A DIM >> The above arrived via the power line from a Remote Controller. Via >> the wireless and the 6-in-1 remote it looks like this: >> A1 ON: >> 5D 20 60 9F 00 FF > 9F = NOT 60, FF = NOT 00. Binary 01100000 00000000 = CM17A A1 On. Cool! >>6) The CM15A seems to work with the camera remotes > What does it report for the RF from a camera remote? That's a 20-bit > protocol. CR14A - has a program button so I don't know which of these are programed. Also seems that if you hold the button too long it transmits more than one packet. Also the stuff after the (x times) is what showed up in the output. I don't know if it's an error or belongs there (programmed part?). Up arrow - 5D 14 37 62 00 (3 times) Left arrow - 5D 14 35 60 00 (2 times) Right arrow - 5D 14 36 61 00 (2 times) Down arrow - 5D 14 38 63 00 (3 times) Camera 1 - 5D 20 00 FF 00 FF (5 times) 5A 02 00 06 5A 02 01 02 Camera 2 - 5D 20 00 FF 10 EF (4 times) 5A 02 00 0E 5A 02 01 02 Camera 3 - 5D 20 00 FF 08 F7 (5 times) 5A 02 00 02 5A 02 01 02 Camera 4 - 5D 20 00 FF 18 E7 (4 times) 5A 02 00 0A 5A 02 01 02 Position 1 - 5D 14 39 64 00 (2 times) Position 2 - 5D 14 3B 66 00 (2 times) Position 3 - 5D 14 3D 68 00 (2 times) Position 4 - 5D 14 3F 6A 00 (2 times) Center - 5D 14 41 6C 00 (3 times) Sweep - 5D 14 43 6E 00 (3 times) Scan up - 5D 20 00 FF 00 FF (8 times) 5A 02 00 0E 5A 02 01 02 5A 02 00 0E 5A 02 01 02 Scan down - 5D 20 00 FF 18 E7 (8 times) 5A 02 00 0E 5A 02 01 02 5A 02 00 0E 5A 02 01 02
(5a0200485a020142) 5a - Power line 02 - 2 data bytes 00 - X10 Address 48 - O 14 5a - Power line 02 - 2 data bytes 01 - X10 Function 42 - O On
(5a03020b84) 5a - Power Line 03 - 3 data bytes 02 - Dim/Bright grouping 0b - 11% 84 - N Dim
Macro that kicked off: Read (03) 11/14 16:42:38 ?: [size = 3] 5B 00 7F Read (01) 11/14 16:42:39 ?: [size = 1] 55 <- Mysterious Read (03) 11/14 16:42:39 ?: [size = 3] 5B 00 87 Interface Read (03) 11/14 16:42:39 ?: [size = 3] 5B 00 90 Ready Read (03) 11/14 16:42:39 ?: [size = 3] 5B 00 99 Read (03) 11/14 16:42:39 ?: [size = 3] 5B 00 A2 Read (03) 11/14 16:42:39 ?: [size = 3] 5B 00 AB Read (03) 11/14 16:42:39 ?: [size = 3] 5B 00 B4 Read (03) 11/14 16:42:39 ?: [size = 3] 5B 00 BC Read (03) 11/14 16:42:42 ?: [size = 3] 5B 00 87
- General receive format
- Set Clock (0x9B)
Cm15a will send 0xA5's repeatedly if clock needs to be set respond with following buffer to set clock. In oreder to stop the Power Fail message send 0x9B and 7 bytes which are defined below. This will set the time for the CM15A.
size=0; time(&t); tm = localtime(&t); sendbuff[size++]= 0x9b; //function code sendbuff[size++]= tm->tm_sec; //seconds sendbuff[size++]= tm->tm_min + 60 * (tm->tm_hour & 1); //0-199 sendbuff[size++]= tm->tm_hour >> 1; //0-11 (hours/2) sendbuff[size++]= tm->tm_yday; //really 9 bits sendbuff[size]= 1 << tm->tm_wday; //daymask (7 bits) if(tm->tm_yday & 0x100) // sendbuff[size] |= 0x80; size++; sendbuff[size++]= 0x60; // house (0:timer purge, 1:monitor clear, 3:battery clear sendbuff[size++]= 0x00; // Filler (???)
- The mystery receive command
* 5A 07 15 F2 FE F2 FE F2 FE (Extended command ???)
I'm not sure what to make of this. Is it a bug or is it a valid command? If I use the last byte as the house code/function code I get FE = J Status On (I have no J devices). Take that one step further and F2 could be J 3. No help as I have no J devices and none of my neighbors have X10.
- Status command (0x8B):
# # Bit range Description # 111 to 96 Battery timer (set to 0xffff on reset) (Byte 0-1) # 95 to 88 Current time (seconds) (Byte 2 ) # 87 to 80 Current time (minutes ranging from 0 to 119) (Byte 3) # 79 to 72 Current time (hours/2, ranging from 0 to 11) (Byte 4) # 71 to 63 Current year day (MSB bit 63) (Byte 5+) # 62 to 56 Day mask (SMTWTFS) (Byte 6-) # 55 to 52 Monitored house code (Byte 7 lo) # 51 to 48 Firmware revision level 0 to 15 (Byte 7 hi) # 47 to 32 Currently addressed monitored devices (Byte 8-9) # 31 to 16 On / Off status of the monitored devices (Byte 10-11) # 15 to 0 Dim status of the monitored devices (Byte 12-13) # # 8B Battery time 8B40 = 2880 (0B40) High bit = sign? Low 7 bits + next byte = battery (???) # 40 # 30 Seconds # 45 Minutes # 0a hours*2 # 3e DoY (+next high bit) # 81 DoW (7 bits) # 61 Monitored house code(high) FW rev (low) # 00 Current address of monitored # 40 # ff On/Off stat of monitored # ff # 40 Dim stat of monitored # 80 # 00 Don't care (???) # 00 Don't care (???) # # db Macros? # # Status Report : 11/14/2004 09:27 pm # Battery Time 2880 # Battery State 1 # Interface Clock 11/14/2004 21:27:55.000 Sun # Monitored House Code A # Transceived House Codes 1,1,1,1,1,1,1,1-1,1,1,1,1,1,1,1 # Addressed Units 0,1,0,0,0,0,0,0-0,0,0,0,0,0,0,0 # Monitored House Code Status 1,1,1,1,1,1,1,1-1,1,1,1,1,1,1,1 # Monitored House Code Dim Status 1,0,0,0,0,0,0,0-0,1,0,0,0,0,0,0 # Monitored House Code Flag Status 0,0,0,0,0,0,0,0-0,0,0,0,0,0,0,0 # 254 151 I/D -> 0x81 W 1866.674 BULK_OR_INTERRUPT_TRANSFER - 255 152 O/D -> 0x02 R 2099.990 BULK_OR_INTERRUPT_TRANSFER 8b 256 152 O/U <- 0x02 R 2099.990 BULK_OR_INTERRUPT_TRANSFER - 0x00000000 257 127 I/U <- 0x81 W 2100.000 BULK_OR_INTERRUPT_TRANSFER 8b 40 37 57 0a 3e 81 61 0x00000000 258 153 I/D -> 0x81 W 2100.000 BULK_OR_INTERRUPT_TRANSFER - 259 129 I/U <- 0x81 W 2100.010 BULK_OR_INTERRUPT_TRANSFER 00 40 ff ff 40 80 00 00 0x00000000 260 154 I/D -> 0x81 W 2100.010 BULK_OR_INTERRUPT_TRANSFER - The above is the Status command (0x8b) you send it and get 16 bytes back. The above is what was returned from the AHP software. It confirms what is printed in Dan's document.
- Dump memory? (0xDF)
This is one of the many mystery commands that have yet to be documented.
Issue a DF xx yy (where XXYY appear to fall on 32 byte boundaries)
261 155 O/D -> 0x02 R 2100.010 BULK_OR_INTERRUPT_TRANSFER db 1f e0 262 155 O/U <- 0x02 R 2100.010 BULK_OR_INTERRUPT_TRANSFER - 0x00000000 263 130 I/U <- 0x81 W 2100.010 BULK_OR_INTERRUPT_TRANSFER 56 25 92 37 43 92 05 61 0x00000000 264 156 I/D -> 0x81 W 2100.010 BULK_OR_INTERRUPT_TRANSFER - 265 131 I/U <- 0x81 W 2100.020 BULK_OR_INTERRUPT_TRANSFER 83 4a 09 83 25 2e 83 21 0x00000000 266 157 I/D -> 0x81 W 2100.020 BULK_OR_INTERRUPT_TRANSFER - 267 132 I/U <- 0x81 W 2100.030 BULK_OR_INTERRUPT_TRANSFER 4b 83 3d 4c ea 00 d0 1f 0x00000000 268 158 I/D -> 0x81 W 2100.030 BULK_OR_INTERRUPT_TRANSFER - 269 134 I/U <- 0x81 W 2100.040 BULK_OR_INTERRUPT_TRANSFER 00 d6 82 45 b6 ca c4 01 0x00000000 270 159 I/D -> 0x81 W 2100.040 BULK_OR_INTERRUPT_TRANSFER -
The line which sends 'DF 1F E0' is a bit of a puzzle and I haven't quite figured it out yet. Woody may have a clue. I'll have to recheck my notes to see what he dug up. Note that '1F E0' is 32 bytes short of 8K. And that all other 'DF' references are in 32 byte increments. I seem to recall the addresses starting at 0000 and incrementing by 32 bytes each time.
- Other useful documentation and links
For further info email me at: firstname.lastname@example.org