I recently had the misfortune of dealing with the RF side of X10 a bit more than I wanted to. I set up some appliance and lamp modules, an SS13A Stick-a-Switch, and an MS16A motion detector in my office. Since it is in an office building that I do not manage and I do not have the luxury of isolating noise makers and signal suckers on the power lines all over the building, I just have my X10 PLC modules on two power strips, one at each end of the room, each isolated by an XPPF filter and using an RR501 transceiver on the power strip to forward RF commands to the PLC modules. I wanted to add some manner of "scene changes" also, so I also added a CM19A RF computer interface.
I figured that since the RF protocol is much faster than the PLC protocol, RF signal collisions would likely be a non-issue since the possibility of overlap would be greatly reduced, right? Wrong. It would be right except that every device seems to transmit its RF command repeatedly for a duration of about one second, so the commands actually monopolize the airwaves for even longer on RF than they do the power lines on PLC. Even worse, no transmitter has a receiver or any sort of avoidance/detection implementation for RF signal collisions. The CM19A has a receiver, but it doesn't implement any sort of collision management. At least, not with the ActiveHome Scripting SDK, which is what I am using. If an X10 signal is already being sent from another device (and received by the CM19A) when the SDK is given a command to send, it just blasts it out the CM19A anyway with no regard to the transmission that it ends up overlapping. It was driving me crazy that frequently, one or more commands in a sequence sent by the computer would be lost because the damn motion detector was blindly sending an ON command, like it does for 1 full second out of every 10 while it's sensing motion, which it does almost the entire time that someone is in the room. I had to do something about this.
So I did something, and it works pretty reliably. I implemented a very lame algorithm for RF collision avoidance and detection. The SDK gives me control of the duration of every RF command sent, and I found that even a value of 1 (the shortest duration, only sending a single copy of the command) is very reliable. So why all the redundancy in other devices? If I only make the CM19A send each command once and other devices are blasting copies of the same command for 1000ms, then the CM19A should be able to "hear" the colliding commands so I can avoid them. Well, sort of. It turns out that the CM19A can either send or receive at once, but not both. And immediately after sending, there is a period in which it is "deaf" and misses other RF signals completely. Maybe the AGC on its receiver has to to settle and fade back up after its own transmission deafens it. I'm not sure of the technical reason, but I know that it happens. After a lot of experimenting, I came up with a simple algorithm and timings that work. I'm not happy with the timings; it's still too slow. But this is as fast as I could make it and still keep it reliable, and it's still much better than missing commands.
Simply, it is the following:
- Every time any copy of an RF command is received, reset a global timer.
Transmission sequence:- COLLISION AVOIDANCE: Before transmitting, check to see if any commands were received in the last 200ms. If so, delay the transmission until 200ms has elapsed since the last received command. (This accounts for the delay between reception of repeated commands. Based on my measurements, 90ms should have been more than sufficient, but for some reason, it's not in practice.)
- Transmit the command with a duration of 1 (shortest).
- After transmitting, wait 1100ms before allowing the next transmission to be sent.
- COLLISION DETECTION: If a command is received during the ("non-deaf" portion of the) 1100ms window, check to see what the command was.
- If it was the same command that was just sent, ignore it because it is probably an echo.
- If it was any other command, treat it as a collision and immediately repeat the entire transmission sequence.
Of course, this entire approach relies on other transmitters sending their usual long blast of repeated commands to ensure that they extend into the "non-deaf" part of the CM19A's reception window. Though it is kludgy and inefficient, it is sufficient to deal with the incredibly rude motion detector, it's only slightly slower than the default behavior of repeating the same transmission for 1 second with NO collision management, and I am quite happy that I was able to make this work. And considering how much more reliable I just made the system, I didn't even put a whole lot of effort into doing so. But this is exactly the thing that bugs me: If it is this simple to add very basic collision management to X10's PC RF transceiver with X10's own software tools, why didn't X10 do it themselves? It makes a massive difference for its reliability.
I still feel as though I'm missing something that should be obvious to me and would have made this whole endeavour unnecessary, so whatever it is, please feel free to point it out!