Secret Door Opener
Intro: Secret Door Opener
As a college student, I'm frequently looking for ways to simplify my life in my dorm room. A big problem I've encountered so far is forgetting my keys and getting locked out. I created an NFC-enabled device to help me not forget my keys, but I wanted to take it one step further: eliminate the need for keys entirely!
To do this I created a mechanism that opens my door from the inside after receiving a secret combination from the outside. My system is wired such that I can tap on my door's peephole in a specific sequence. If I get the combo right, my door opens! No keys needed. The project uses a stepper motor and stepper driver to open the door, and a capacitive sensor to sense taps on the peephole.
Step 1: Conductive Surface Identification
The first thing you'll need to identify is if your door is a candidate for a capacitive system. Take a multimeter and test the conductivity of metal parts going through the door. For example, see if the doorknob on the inside of your door is electrically connected to the doorknob on the outside of your door. Other good metal parts would be things like the key hole, peephole, and others. If you have a good conductive surface going through the door then this system will work! If you don't, you could try and modify the system to detect something like knocks with a microphone or other methods like Bluetooth. From here on out I'll assume that you'll be working with the capacitive system.
Another constraint is that your doorknob needs to be able to be opened by a motor. The handle on my door is perfect, because it doesn't require too much force to open it. If you have a knob that just rotates you might have a more difficult time getting the stepper motor to open it.
Step 2: Parts!
Below is a list of all the parts you'll need. You can purchase them from DFRobot.
- Arduino Uno
- Stepper Motor
- Stepper Driver
- Buzzer
- Capacitive Sensor
- 12V Power Adapter
- Jumper Wires
- Double-Sided Mounting Tape
- Copper Tape
- String
Step 3: Wiring
You can do all of the wiring with jumper wires. For the stepper motor driver just screw the ends of the jumpers into terminal blocks. Follow the above diagram for wiring the stepper driver. You can connect the GND pin on the stepper driver to the GND on your Uno and the VCC pin to VIN.
The capacitive sensor and buzzer should each have three wires coming from them. Connect the black wire to GND for each, and the red wire to 5V. If you're out of 5V pins you can connect one of them to IOREF. Connect the green wire of the buzzer to pin 10, and the capacitive sensor to pin 3.
Lastly, tape the end of a jumper to the top pad of the capacitive sensor with copper tape.
Step 4: Mounting!
One constraint of this system is that you'll need to have access to an outlet to plug in the 12V adapter. For this reason, I placed the motor driver, Uno, and Buzzer on the left side of my door close to the hinge. This way, the cord coming from the wall doesn't interfere with opening the door.
Another constraint is that the motor should be able to be mounted directly above or below the end of your door handle. I'm not entirely sure if this system would work on knobs; it's much better suited to handles like the one shown in the photos above.
Additionally, your capacitive sensor needs to be close to the surface you're using to detect taps from the outside. Take the other end of the jumper you taped to the capacitive sensor in the previous step and tape it (with copper tape) to whatever surface you're using. In my case, I wrapped the end in lots of copper tape and stuffed it in the door's peephole to make sure it stays put.
The last thing you'll need to do is connect your motor to the door handle. I did this by using rubber bands to hold the string to the shaft of the motor and to the handle. You should be able to spin the shaft by hand and see the door handle come up or down without any slipping of the string.
Step 5: The Code
const int sensorPin = 3; const int soundPin = 10; const int pulsePin = 7; const int directionPin = 6; const int enablePin = 5; const int numPresses = 5; const int motorStepDistance = 12000; const int thresh = 100; const int volume = 5; int pressIndex = 0; bool haveResetCount = false; int pressTimes[numPresses]; int correctPressTimes[] = {100, 100, 100, 100, 100}; void setup() { pinMode(sensorPin, INPUT); pinMode(soundPin, OUTPUT); pinMode(pulsePin, OUTPUT); pinMode(directionPin, OUTPUT); pinMode(enablePin, OUTPUT); } void loop() { long loopStartTime = millis(); while(!digitalRead(sensorPin)) { // Resets after 10 seconds if (millis() - loopStartTime > 10000 && !haveResetCount) { pressIndex = 0; haveResetCount = true; for (int i = 0; i < 3; i++) { analogWrite(soundPin, volume); delay(75); digitalWrite(soundPin, LOW); delay(75); } } } long pressStartTime = millis(); while(digitalRead(sensorPin)) { analogWrite(soundPin, volume); } digitalWrite(soundPin, LOW); int pressTime = millis() - pressStartTime; pressTimes[pressIndex] = pressTime; haveResetCount = false; pressIndex++; if (pressIndex == numPresses) { bool stillCorrect = true; for (int i = 0; i < 4; i++) { if (abs(correctPressTimes[i]-pressTimes[i]) > thresh) { stillCorrect = false; } } if (!stillCorrect) { for (int i = 0; i < 20; i++) { analogWrite(soundPin, volume); delay(20); digitalWrite(soundPin, LOW); delay(20); } } else { for (int i = 0; i < 5; i++) { analogWrite(soundPin, volume); delay(100); digitalWrite(soundPin, LOW); delay(100); } unlock(); } pressIndex = 0; haveResetCount = true; } } void unlock() { digitalWrite(directionPin,HIGH); digitalWrite(enablePin,HIGH); for (int i = 0; i < motorStepDistance; i++) { digitalWrite(pulsePin,HIGH); delayMicroseconds(50); digitalWrite(pulsePin,LOW); delayMicroseconds(50); } delay(5000); digitalWrite(directionPin,LOW); for (int i=0; i < motorStepDistance; i++) { digitalWrite(pulsePin,HIGH); delayMicroseconds(50); digitalWrite(pulsePin,LOW); delayMicroseconds(50); } digitalWrite(enablePin, LOW); }
Attached is the code you'll need to upload to the Uno.
The first parameter you can change is the sequence of taps that unlock your door. The way the code is currently configured, the door will unlock after one short tap of 100ms, one long tap of 700ms, one short tap of 100ms, and finally one long tap of 100ms. There is also a significant threshold, so you don't need to be too precise with the timing. You can change the threshold to a much lower value to make the system slightly more secure. You can also completely configure the tap sequence. Change the numPresses variable to however many presses you want to comprise your combination, then change the values in correctPressTimes to your desired values.
Another thing you might want to customize is the motorStepDistance constant. If your handle isn't being lifted enough, increase this number, and vice-versa. If the directions are reversed you can change the unlock() function such that directionPin is initially set to LOW, then later is set to HIGH after the 5-second delay.
The sounds are also completely configurable. I currently have it set to do four long beeps if you get the combination correct and lots of short beeps if it is incorrect. The device will also beep every time the touch sensor is activated. I'm just sending a square wave with a very low duty cycle to the buzzer to keep it quiet - you can use the Tone library to make the buzzer produce jingles or notes. If the buzzer is too quiet then increase the volume constant.
Step 6: Troubleshooting and More
The most significant challenges I faced with this project were getting the motor-handle link to work correctly and getting the capacitive sensor to work correctly.
Holding the string connecting the motor shaft to the door handle with rubber bands works well, but something like hot glue might work better. You can definitely experiment with this.
My capacitive system was also quite finicky. If your sensor doesn't appear to be working at first then unplug it and plug it back in. The sensor is sensitive to changes in capacitance from the initial value, so every time you unplug it and plug it back in the sensor recalibrates. If you can't get this portion to work then try and get creative! There are many ways to get some form of a combination from the other side of a door.
Code :-
const int sensorPin = 3; const int soundPin = 10; const int pulsePin = 7; const int directionPin = 6; const int enablePin = 5; const int numPresses = 5; const int motorStepDistance = 12000; const int thresh = 100; const int volume = 5; int pressIndex = 0; bool haveResetCount = false; int pressTimes[numPresses]; int correctPressTimes[] = {100, 100, 100, 100, 100}; void setup() { pinMode(sensorPin, INPUT); pinMode(soundPin, OUTPUT); pinMode(pulsePin, OUTPUT); pinMode(directionPin, OUTPUT); pinMode(enablePin, OUTPUT); } void loop() { long loopStartTime = millis(); while(!digitalRead(sensorPin)) { // Resets after 10 seconds if (millis() - loopStartTime > 10000 && !haveResetCount) { pressIndex = 0; haveResetCount = true; for (int i = 0; i < 3; i++) { analogWrite(soundPin, volume); delay(75); digitalWrite(soundPin, LOW); delay(75); } } } long pressStartTime = millis(); while(digitalRead(sensorPin)) { analogWrite(soundPin, volume); } digitalWrite(soundPin, LOW); int pressTime = millis() - pressStartTime; pressTimes[pressIndex] = pressTime; haveResetCount = false; pressIndex++; if (pressIndex == numPresses) { bool stillCorrect = true; for (int i = 0; i < 4; i++) { if (abs(correctPressTimes[i]-pressTimes[i]) > thresh) { stillCorrect = false; } } if (!stillCorrect) { for (int i = 0; i < 20; i++) { analogWrite(soundPin, volume); delay(20); digitalWrite(soundPin, LOW); delay(20); } } else { for (int i = 0; i < 5; i++) { analogWrite(soundPin, volume); delay(100); digitalWrite(soundPin, LOW); delay(100); } unlock(); } pressIndex = 0; haveResetCount = true; } } void unlock() { digitalWrite(directionPin,HIGH); digitalWrite(enablePin,HIGH); for (int i = 0; i < motorStepDistance; i++) { digitalWrite(pulsePin,HIGH); delayMicroseconds(50); digitalWrite(pulsePin,LOW); delayMicroseconds(50); } delay(5000); digitalWrite(directionPin,LOW); for (int i=0; i < motorStepDistance; i++) { digitalWrite(pulsePin,HIGH); delayMicroseconds(50); digitalWrite(pulsePin,LOW); delayMicroseconds(50); } digitalWrite(enablePin, LOW); }
Thanks Pcbway for your Supporting ??
- Comments(0)
- Likes(0)