This all began with me buying a simple electronic door lock (Kwikset Model: 92690-001) at the local hardware store. It had a keypad, handle, and not much else.
It worked great. Enter the combination on the keypad, the door unlocks. Simple. Boring. Tedious.
( ¯ ö¯ )
I quickly tired of having to enter the door code each time I wanted in and out of the room... and I HAD to lock it. Otherwise the little darlings would sneak in while I was grabbing coffee in between conference calls.
So, maybe I can figure out a way to hook up one of these nifty Bluno Beatles (which is basically a very small and cheap Arduino Uno that includes a Bluetooth-LE chip), and automagically open the door.
The door lock itself has two halves. The exterior facing half that has the keypad, and the interior facing half that has the batteries, motors, and micro-controller. There are four wires that connect the two halves.
I'd always wanted an oscilloscope, but could never justify shelling out the dough to actually own one. If I wanted to figure out how the two halves of the door were communicating, I was going to need one. Fortunately, a simple digital scope that hooks up to a computer is no longer quite so expensive, so after a little bit of research, I bought one from BitScope and so far I've been pretty happy with it (I bought the more expensive BitScope 10, but a BitScope Micro would have worked just as well).
So, the first thing I wanted to do was to probe these four wires, and see what they do while the door is operating.
I very quickly identified two of the wires as 3.3v (VCC) and ground (GND). This makes sense, since the keypad half has no batteries and needs to be provided with power from somewhere.
For the other two wires, I needed to capture what was happening. The inside half of the lock contains a Sonix SN8F27E65 micro-controller, so it seemed likely that SPI, I2C, or UART was being used to communicate. SPI seemed unlikely, since it would require more wires.
After playing with various triggers, and the timebase controls in the oscilloscope software, I managed to figure out that the other two wires were using what *looked like* asynchronous serial to send data between the two halves of the door lock.
From Keypad - Brown Wire |
To Keypad - Orange Wire |
The orange wire seems to be used to send data to the keypad (e.g. data is sent whenever the door is opened or locked), and the brown wire seems to send data from the keypad (e.g. data is sent whenever I press a button on the keypad).
Awesome, but the timing looks a little odd.
From keypad (brown wire) | Starts high, 30000 µs low, [async data] |
To keypad (orange wire) | Starts high, 100 µs low, 1200 µs high, [async data] |
For both wires, the stuff that looks like async serial is at the end of each sequence that I capture. There's some preamble for both wires, before the stuff that looks like serial data gets sent.
The timing of the async data at the end looks almost exactly like 9600 8N1, since the pulses are about 10 µs apart (1s/9600 ~= 104 µs), and there appears to be the right number of bits (1 start bit, 8 data bits - the stop bit is not visible, since only one byte is sent at a time).
The other stuff preceding the serial data didn't make much sense, until I realized that the processors in both halves of the electronic door lock are probably in some sort of low power mode, and need to wake up before being able to process the serial data. The purpose of the preamble is to trigger a hardware interrupt to wake the processor up, and give it time to wake up.
The next step was to connect up my Arduino compatible board (the Bluno Beetle) to the door lock, and try to decode the signals. At this point, I'm connected to the Beetle by USB serial, which provides the supply voltage for the board, so I only need to connect a tap wire to GND, and either Keypad RX or Keypad TX.
I used the following simple Arduino program to sniff the messages being sent between the two halves of the door lock (switching the RX pin as needed). Really, you could use any Arduino board, but the
After using the small program above to capture messages in both directions while playing with the door lock, I now have a pretty good understanding of how the two halves of the door lock communicates!
Now, I just need figure out how to use the Arduino to actually control the lock.
See part 2 of My Fancy Bluetooth-LE Operated Door Lock series:
Controlling my Electronic Door Lock using an Arduino
The other stuff preceding the serial data didn't make much sense, until I realized that the processors in both halves of the electronic door lock are probably in some sort of low power mode, and need to wake up before being able to process the serial data. The purpose of the preamble is to trigger a hardware interrupt to wake the processor up, and give it time to wake up.
The next step was to connect up my Arduino compatible board (the Bluno Beetle) to the door lock, and try to decode the signals. At this point, I'm connected to the Beetle by USB serial, which provides the supply voltage for the board, so I only need to connect a tap wire to GND, and either Keypad RX or Keypad TX.
I used the following simple Arduino program to sniff the messages being sent between the two halves of the door lock (switching the RX pin as needed). Really, you could use any Arduino board, but the
Bluno Beetle is the board I'm eventually going to use in the finished version, since it has Bluetooth-LE already built in.
#include <SoftwareSerial.h> SoftwareSerial doorSerial(2, 4); void setup() { // initialize the real (UART) Serial Serial.begin(115200); // initialize the SoftwareSerial port doorSerial.begin(9600);/ } void loop() { if (doorSerial.available()) { Serial.print("0x"); // send what has been received Serial.println(doorSerial.read(), HEX); } }
After using the small program above to capture messages in both directions while playing with the door lock, I now have a pretty good understanding of how the two halves of the door lock communicates!
To keypad (orange wire) | |
---|---|
0xFF 0x62 | Locked or Handle Turned |
0xFF 0x61 | Unlocked and Handle not turned |
From keypad (brown wire) | |
0x00 0x69 | Keypad active (backlight on) |
0x00 0x6A | Keypad idle (not illuminated) |
0x00 0x42 | Keyguard button |
0x00 [0x30-0x39] | Number buttons 0-9 |
0x00 0x2A | Cancel |
0x00 0x23 | Enter |
Now, I just need figure out how to use the Arduino to actually control the lock.
Although the SoftwareSerial library reads the first characters as 0x00 and 0xFF, we know from the oscilliscope captures that these characters are not actually being sent. We'll have to keep that in mind in the next part, where we use the Arduino to actually control the door lock.
See part 2 of My Fancy Bluetooth-LE Operated Door Lock series:
Controlling my Electronic Door Lock using an Arduino
This was a good read ! :D
ReplyDeleteWell done. You have a skill at explaining things. -Frank
ReplyDelete