Introduction: Cryptap: a Rhythm-based Door Lock
Inspired by several door-unlocking mechanisms I've seen on hackaday.com, I decided to create one on my own. This one has a two-button interface; one to start and end the password submission, and one to actually tap in the rhythm that is your password. There is also a status light. I was able to build this really cheaply using parts I had scavenged over the past few months. The only things I had to pay for were the microcontroller itself, which was $21 (http://www.pjrc.com/teensy/), and some picture hanging wire which I had from before.
It's lots of fun to tap in the Star Wars Theme or something to enter my room. Now, I don't have to worry about locking myself out of my room again! Plus, it feels good and geeky.
It's lots of fun to tap in the Star Wars Theme or something to enter my room. Now, I don't have to worry about locking myself out of my room again! Plus, it feels good and geeky.
Step 1: Parts and Tools
I chose the Teensy because this is my first microcontroller, and I don't have a programmer yet. The Teensy only requires an A-miniB USB cable and free software to install, compatible with Mac/Windows/Linux. Also, it's really easy to upload the hex file; just compile, and press the button on the Teensy.
The cost of this project to me was $21, plus the picture-hanging wire.
Parts from the street came from a coffee percolator (relay, LED, capacitor) and a router (LED, modular jack, power jack, capacitors). Free samples were the 7805 5-volt regulator, buttons and switch. I also found lots of stuff in the "broken parts" box in my EE lab: banana connectors and cable, wire, the sn754410 driver, a four-pin header and resistors. I had an extra laptop charger lying around that I used for power, and an Apple modem cable whose tab was broken.
Other hardware: a wall plate.
I used a hot glue gun, a soldering iron, a needle file and a power drill, which are pretty standard. The most unusual thing I used was a long, flexible grabber tool.
The cost of this project to me was $21, plus the picture-hanging wire.
Parts from the street came from a coffee percolator (relay, LED, capacitor) and a router (LED, modular jack, power jack, capacitors). Free samples were the 7805 5-volt regulator, buttons and switch. I also found lots of stuff in the "broken parts" box in my EE lab: banana connectors and cable, wire, the sn754410 driver, a four-pin header and resistors. I had an extra laptop charger lying around that I used for power, and an Apple modem cable whose tab was broken.
Other hardware: a wall plate.
I used a hot glue gun, a soldering iron, a needle file and a power drill, which are pretty standard. The most unusual thing I used was a long, flexible grabber tool.
Step 2: Pre-existing Hardware
I was very lucky that there was already so much installed. My room is ADA-accessible, and there were various pipes, electrical boxes and an electric door strike already installed. On removing the door strike out of curiosity, I found that it was not connected. There was a pipe from the door strike to a blank wall plate inside my room, and another pipe from there to a blank wall plate outside.
The door strike says it needs 24V@3A to operate, but I was able to get by with a 19V, 7.9A power supply I had. The door strike was polarized, so make sure you have the polarity correct!
The door strike says it needs 24V@3A to operate, but I was able to get by with a 19V, 7.9A power supply I had. The door strike was polarized, so make sure you have the polarity correct!
Step 3: Circuits
To control the door strike, I used the relay I found in the coffee percolator. This relay needed more than 5V TTL to drive it, so the sn754410 was used to translate TTL to 19V, which drove the relay. The sn754410 is really a quad half-H driver, so I was wasting 3/4 of the chip, but I didn't have any power transistors, so that's what I used.
The sn754410 chip has two VCC pins, one for 5V, the other for what ever voltage you want to come out, which was 19V for me. It's a really cool chip. You can use this to drive motors and relays directly, because it can switch 1A per quarter chip and has built-in protection diodes. Take a look at the datasheet. In my circuit, I connected the sn754410 directly to my Teensy's output pin.
Buttons are connected as active-low, which is very common for microcontrollers. They are directly connected to the Teensy, which means I have to do debouncing in software.
The status light is connected to the Teensy through a 1K ohm resistor; nothing special.
The circuit worked without capacitors, but I put them in anyway just in case. There are protection caps on both the 19V and 5V power rails to ground.
While programming the Teensy, 5V came from the USB, but when it's running on its own, the power comes from the laptop power brick. When I connected the 7805 regulator directly to 19V, it got REALLY hot, so I put in a network of resistors to limit the input voltage and current to the regulator. This was a kludge, but now everything is at a manageable temperature.
The sn754410 chip has two VCC pins, one for 5V, the other for what ever voltage you want to come out, which was 19V for me. It's a really cool chip. You can use this to drive motors and relays directly, because it can switch 1A per quarter chip and has built-in protection diodes. Take a look at the datasheet. In my circuit, I connected the sn754410 directly to my Teensy's output pin.
Buttons are connected as active-low, which is very common for microcontrollers. They are directly connected to the Teensy, which means I have to do debouncing in software.
The status light is connected to the Teensy through a 1K ohm resistor; nothing special.
The circuit worked without capacitors, but I put them in anyway just in case. There are protection caps on both the 19V and 5V power rails to ground.
While programming the Teensy, 5V came from the USB, but when it's running on its own, the power comes from the laptop power brick. When I connected the 7805 regulator directly to 19V, it got REALLY hot, so I put in a network of resistors to limit the input voltage and current to the regulator. This was a kludge, but now everything is at a manageable temperature.
Step 4: Wiring It Together
The Teensy was no problem. It comes with pins, so you can plug it directly into the breadboard.
I decided to color-code the wires to the door strike with red (+) and black (-) banana cables from the lab's broken parts box. There were some plugs chopped off from their wires, so I dremeled away some plastic to expose a solder point. I really like how the lab banana plugs can plug into each other.
I used Apple's phone cable to connect the buttons and status light outside the room to the Teensy inside. Since one side was broken, I chopped off that end and soldered in the four-pin header, sealing it off with hot glue. This plugged nicely into my breadboard. The side that I left the plug on went into the modular jack I salvaged from the router. All four wires were used (GND, status light, start/stop button, code button).
In case you haven't noticed, I like plugs and connectors. The power brick connected to the power jack that I swiped from the router.
Threading the wires through the wall pipes wasn't too difficult, because of the flexible grabber thing. That really saved my day.
I decided to color-code the wires to the door strike with red (+) and black (-) banana cables from the lab's broken parts box. There were some plugs chopped off from their wires, so I dremeled away some plastic to expose a solder point. I really like how the lab banana plugs can plug into each other.
I used Apple's phone cable to connect the buttons and status light outside the room to the Teensy inside. Since one side was broken, I chopped off that end and soldered in the four-pin header, sealing it off with hot glue. This plugged nicely into my breadboard. The side that I left the plug on went into the modular jack I salvaged from the router. All four wires were used (GND, status light, start/stop button, code button).
In case you haven't noticed, I like plugs and connectors. The power brick connected to the power jack that I swiped from the router.
Threading the wires through the wall pipes wasn't too difficult, because of the flexible grabber thing. That really saved my day.
Step 5: Code
I've tried to comment my code. Keep in mind that this is 1.0 software, meaning that it is not bug-free.
## OPERATION ##
1. Press the start/stop button to signal that you are ready to begin code input. The status light begins to flash slowly.
2. Tap in your code on the code button. The status light will blink at 120 BPM, so you can use this as your metronome if you want. However, the cryptap program will measure the pulse lengths relative to each other proportionally, so you could also use your own tempo. Just make sure you that are accurate enough!
3. When the code input is done, press the start/stop button again. The program will then decide whether to let you in.
Since humans are not very accurate time keepers (yours truly is not), I set the tolerance ratio to +/- 30%. That means that the beat lengths can be inaccurate by that amount, and still pass muster. This is good enough to tell the difference between pretty similar tunes. There is a small amount of hard-to-reach overlap between double and triple-length beats, but the code is still pretty hard to break.
To unlock the door, the beats must be in the correct proportions to each other (+/- the tolerance ratio), and the number of beats must be correct. If an invalid password is entered, the program waits for a few seconds while ignoring any user input. It will also flash the status light quickly. If the correct code is entered, the status light will turn on steadily and the door will unlock for 8 seconds.
## USER CONFIGURATION ##
The key is stored in an array like this:
#define keylength 5
const int key = { 2, 1, 3, 3, 3 }; // "Happy birthday to you"
The array stores the amount of time that happens BETWEEN the beats. So if your password has SIX notes like "Happy birthday to you", there should be FIVE elements in the array. If your password is really long and you have more than 16 beats in it, (really hard, I don't recommend it), you must increase the number defined in this line:
#define inputCodeLength 16
## THE REST OF THE CODE ##
I was curious about interrupts, so I had my buttons trigger interrupts. To make these interrupts easy to use, I had my interrupt handlers check for certain function pointers. If the pointer is not set to NULL, the function it points to is invoked. These are set with the various "mode-setting" functions inside cryptap.c.
I made an effort to avoid buffer overflows by setting a maximum number of inputted pulses. If the maximum number of pulses are input, the program immediately starts password analysis and decides whether to unlock the door.
I hope my comments in the code help.
## BUGS ##
I tried to remove the USB debugging code, but the code won't work if I do. So, I left in usb_init() and the various print() statements. I would appreciate it if someone could remove them and still have the program work. Even better if they can explain why it didn't work for me.
Immediately after being programmed, the Teensy sometimes doesn't accept code input. To solve this, power-cycle the circuit.
## OPERATION ##
1. Press the start/stop button to signal that you are ready to begin code input. The status light begins to flash slowly.
2. Tap in your code on the code button. The status light will blink at 120 BPM, so you can use this as your metronome if you want. However, the cryptap program will measure the pulse lengths relative to each other proportionally, so you could also use your own tempo. Just make sure you that are accurate enough!
3. When the code input is done, press the start/stop button again. The program will then decide whether to let you in.
Since humans are not very accurate time keepers (yours truly is not), I set the tolerance ratio to +/- 30%. That means that the beat lengths can be inaccurate by that amount, and still pass muster. This is good enough to tell the difference between pretty similar tunes. There is a small amount of hard-to-reach overlap between double and triple-length beats, but the code is still pretty hard to break.
To unlock the door, the beats must be in the correct proportions to each other (+/- the tolerance ratio), and the number of beats must be correct. If an invalid password is entered, the program waits for a few seconds while ignoring any user input. It will also flash the status light quickly. If the correct code is entered, the status light will turn on steadily and the door will unlock for 8 seconds.
## USER CONFIGURATION ##
The key is stored in an array like this:
#define keylength 5
const int key = { 2, 1, 3, 3, 3 }; // "Happy birthday to you"
The array stores the amount of time that happens BETWEEN the beats. So if your password has SIX notes like "Happy birthday to you", there should be FIVE elements in the array. If your password is really long and you have more than 16 beats in it, (really hard, I don't recommend it), you must increase the number defined in this line:
#define inputCodeLength 16
## THE REST OF THE CODE ##
I was curious about interrupts, so I had my buttons trigger interrupts. To make these interrupts easy to use, I had my interrupt handlers check for certain function pointers. If the pointer is not set to NULL, the function it points to is invoked. These are set with the various "mode-setting" functions inside cryptap.c.
I made an effort to avoid buffer overflows by setting a maximum number of inputted pulses. If the maximum number of pulses are input, the program immediately starts password analysis and decides whether to unlock the door.
I hope my comments in the code help.
## BUGS ##
I tried to remove the USB debugging code, but the code won't work if I do. So, I left in usb_init() and the various print() statements. I would appreciate it if someone could remove them and still have the program work. Even better if they can explain why it didn't work for me.
Immediately after being programmed, the Teensy sometimes doesn't accept code input. To solve this, power-cycle the circuit.