My previous house came with a pre-installed security system that had door sensors, a motion sensor, and a control panel. Everything was hard wired to a big electronics box in a closet and there were instructions for wiring a landline phone to automatically dial out in case of an alarm. When I tried playing with it I discovered that one of the door sensors was incompletely installed and another was intermittent due to improper alignment. So much for the professional installation touted on the business card of the security company. My solution at the time was to buy a couple of internet security cameras and a cheap wireless security alarm.
Fast forward to today and that wireless alarm is sitting in a box in my basement. After my recent acquisition of a cheap RF receiver I decided to see if I could decode the messages transmitted by the variety of alarm sensors and remotes that I have. I figured that since they all worked with the cheap alarm box that they must all use the same message format with just a different ID. I soon found out that they are similar only in the general structure of the messages. So the project quickly went from trivial to very interesting.
As you can see in the pictures above the transmitters include door open sensors, motion detectors, arming remotes, and a wireless keypad used for programming the alarm box. As it turns out, no two of these devices use the same sync length or bit duration. The only commonality, other than the message length, is the basic format of the bits. Each bit takes up a fixed time period with the difference between a zero and a one being the duty cycle of the high/low portions.
The pretty waveform shown above is NOT what I first received. Because there is so much traffic in the 433-MHz frequency band I had to make sure to activate the sensor just before I set the scope to do a single trigger. Fortunately the sensors put out several copies of the data message when activated and the remotes and keypad continue outputting messages as long as a key is pressed. By using the scope I was able to determine the sync length and the data bit durations for each item. As mentioned previously, the sync times are different and the bit times are different but the message formats all have a low-level sync followed by 24 data bits and one stop bit. That was enough for me to be able to build a generic decoder in software without having to hard code all of the different details for each device.
The simple schematic is shown above and it will look familiar if you have read the post on the AcuRite Weather Sensor Interface. I have also included a picture of the breadboard I use for both this project and for a data logger version of the AcuRite sensor decoder. All I have to do is change the software in the PIC for whichever function I need at the time.
The software converts the received bits into displayable ASCII characters. It also outputs the nominal value of the sync length (rounded up to full milliseconds). Because I already knew the sync lengths and the bit formats, I could have written the software specifically for them. Instead, I decided to see if I could write it to sort out the sync lengths and to automatically figure out the data bits. I figured that would make it easier to modify in case I wanted to try to detect other formats at some time.
The interrupt handler first determines if the captured count is long enough to be a sync pulse. The various devices I have use sync pulses of 4, 9, 10, and 14 milliseconds. At one point I widened that window a bit and discovered that my really old Acurite temperature sensor also has the same message format as these security sensors but uses a 3ms sync. Instead of hard coding the sync window I decided to make it flexible so that it can be widened or narrowed and can even be used to capture messages with a single sync value. The define statements for the min/max allowed sync values are up front in the software and are currently set for 3 and 14 milliseconds. If you modify these keep in mind that the desired times need to be in BCD format. The count is rounded up because just the upper 8 bits of the Timer1 count are used. As luck would have it, the 8-MHz clock of the PIC allows the count to be easily converted to the integer value of the time in milliseconds. This is accomplished by adding 4 to the count (rounding up), then dividing by 8 (right shifting). The result is then converted to a BCD representation.
The bit times also vary between the sensors so the algorithm for decoding bits needs to take that into account. Because the software only uses the upper 8 bits of the Timer1 count (rounded up), the captured bit times are pretty stable. That allows for a direct comparison of subsequent bit times. The bit decoding starts by assuming that the first data bit is always recorded as a logic 1. That rounded count value is saved and then used to test subsequent bits. If a subsequent data bit count is equal to the saved value then it is also recorded as a logic 1. If it is less than the saved value then it is recorded as a logic 0. If, however, a subsequent data bit count turns out to be greater than the saved value it is still recorded as a logic 0 but a flag is set to tell the software that the bytes need to be inverted before displaying. The only case where this algorithm fails is when the bits in a message are all 0’s. We can accept that limitation because that kind of message is meaningless.
The sensors I am interested in all have a message length of 24 data bits. The software is set up to collect the bits, convert them into bytes, store them temporarily, and then output them in ASCII format via the serial port. The event that triggers the output of the message is the receipt of a new sync. The software checks a switch input in order to cover the case where a message may exist that has more data bits. The maximum number of data bytes allowed in the software is 15. While I saw a lot of traffic that looked like messages I was not able to discern any patterns that made sense. But the switch is included in case you want to check what’s floating around in your area.
The software is set up to output the converted data as packed ASCII characters via the serial output of the PIC. You can use whatever method you want to capture the bytes for display or logging. I use the Windows terminal program Tera Term and connect to the PC using a standard USB to TTL adapter (see the Hardware step photo). The software baud rate is set to 9600. You will want to set Tera Term to do a new line whenever a carriage return is received because that is what the software sends. To do that, go to Setup/Terminal and select “AUTO” for the receive New-Line. The screen shot shows a typical output. As you can see, the data is not always perfect but you can easily determine what the real value of each sensor should be. You can then make a modified version of this software to specifically check for the desired values. That’s it for this post. Check out my other electronics projects.