Overview:
Description: A device for opening a door using only a combination of knocks by a user on the outside.
Images:
Function:
Process:
Changing Ideas:
Building the Microphone Casing:
Some Highlights:
Discussion:
This was a tumultuous project to say the least. Entering the two week work period, I thought I had an idea of what my final product would be, how I would implement it, and what challenges I would encounter along the way. Of course, most of this thinking was quickly overturned when I decided to pivot to a completely different idea after having spent a week working on my first prototype. After I having spoken with Robert about my initial idea (which was at best contrived to begin with), I came to agree with his assessment that I had underestimated the complexity of designing and 3D printing a mechanical system for vending pencils one at a time from a pencil box. So I began a search for something new.
Looking ahead towards the deadline of this project, knowing I only had a week to create a final prototype, I was pretty sure I wouldn’t. Although I rarely get tripped with up with the technical details of implementing projects like this, there is something especially terrifying about prospect of polishing and packaging my work into something presentable and useful to an audience other than myself. So after having decided on creating a device that would allow me to open a door from the outside without a key, I’m proud to say that for once I didn’t just dive into the coding and circuitry, but instead decided to consider how my device would look physically and what space in the door/entranceway environment it would occupy. This felt like a big step to me and I was quite happy with the solution I came up with to hang the lock from the top of the door. It seemed relatively minimalist with the added advantage of being mechanically suited to the tricky problem of creating enough stable tension to lift a heavy door handle while still listening for and sensing the vibrations on the door. Barring the disappointment I felt with a last-minute malfunctioning stepper motor (and believe I me I was frustrated), I was both pleased and surprised to see a final product that by my normal standards seemed quite refined, compact and cleverly designed. For once I had actually taken the time to focus on the physical implementation first which actually made the rest of the process more of a joy and less stressful. With just a little more time to debug and iterate, I could have improved my current project to be more robust and useful. That being said, I do agree with many of my classmates about what I could have done better in developing The Knock Lock.
There were several critiques that seemed to follow my own line of thinking about my project. To begin with, I absolutely agree that the reliability of a project like this would be a major concern. The sensor I used were not especially sensitive and although I did take some particular care to try and minimize the error and noise of each sensor’s readings, they weren’t perfect implementations yet and the accelerometer especially probably should have been mounted directly to the door instead of relying on the weight of the lock to provide a good contact with the door. If I wanted to keep the lock entirely modular and immediately portable, it wouldn’t have been a bad idea to instead have the lock function by me flicking or sliding the brackets along the top of the door in a certain pattern. It’s not a bad idea, but obviously different from the implementation I was going for here. Further tuning of the lock as well as adding some potentiometers for manual tuning of the tap thresholds of the user would probably help solve this problem. I’m glad that everybody seemed to agree that the redundancy of two type of sensors would help improve the reliability of the lock. They also had similar ideas about where to take the lock from here. Making the microphone/accelerometer package more modular and separate from the control box would allow me to put several of them at different places around the door. This could make opening the door significantly more complicated as the pattern would not take on different options for double and single taps as well as the location of those taps on the outside of the door. This could be a very fun and interesting way to expand the complexity and usefulness of a project like this and I was glad to see that some of the inherent weaknesses of the hardware (low range for tap detection), could be used to create more complex code and project.
In many ways, I think the time crunch for this project was a bit of a blessing. I was not only required to quickly start iterating and implementing on my new idea, but also to think of creative but reasonable ways to deliver a usable product. Looking back, I know now that I should have spent more time during ideation not only thinking about general ideas, but also about the one or two difficult challenges associated with each. Afterwards, I could have done a quick sweep of my ideas to check for their feasibility given the time constraints and expectations of the project. But I was happy with the way I was able to bounce back and create something physical and possibly useable when I was unsure of my ability to make more aesthetically pleasing projects. Figuring out how to implement something as finicky as tap detection with relatively simple components also turned out to be a fun challenge that forced me to go beyond the simple I/O skills associated with Arduino, and with more time, I know I could have made something even better and more easily tunable to the individual cases of the user.
Although I don’t plan on creating any new version of my project, there are some clear improvements that could be made to enhance its performance and usability. To start, it would be better to find a way to attach the accelerometer directly to the to and secure it firmly so it moves as little as possible with reference to the vibration of the door. Moreover, it would be helpful to find a better way of attaching my rope to the stepper motor. Printing a small plastic wheel to attach to the stepper shaft would ensure management of the rope and prevent jamming (an idea I had the intention of completing, but could not before I ran out of time). It would also be helpful to find a way of making The Knock Lock compatible with a wider variety of doors, not just those who’s handles turn upwards. This would probably entail creating a clever attachment (similar to the pully or wheel attached to the stepper), that would fit around the base of the handle and redirect the string around and under the handle, so as the stepper pulls upwards the handle is pulled downwards. One problem with this setup is that is could require a greater torque on the part of the stepper, so careful steps would have to be taken to ensure the radius of the wheel around the handle would be large enough to minimize the force needed to pull the handle. And finally, of course, I would take greater care to continually check the functionality of my components throughout the assembly process so that I am not surprised to find that a single component has broken or been replaced somewhere along the way and hopefully have a less stressful and more enjoyable experience.
Schematic:
Code:
/*The Knock Lock * Author: Nicholas Toldalagi * * Acknowledgements: This code uses the AccelStepper library whos trademark is owned * by AirSpayce Pty Ltd. and Copyright Mike McCauley. * * Summary: This code is written to run on an Arduino UNO interfacing with an * accelerometer and microphone to listen for and detect single and double knocks * on the outside of a door to which they are all attached. Upon detecting a specific * sequence of single and double knocks, a stepper engages, opening the door handle * from aboves. * * Inputs: * Arduino pin / input * A0 Z-axis XL input (Z_PIN) * A1 Microphone analog output (MIC_PIN) * 6 Reset Button (RESET_PIN) * * OutputsL * Arduino pin / output: * 2 Step pin for stepper motor driver (STEP_PIN) * 3 Direction pin for stepper motor driver (DIR_PIN) * 7 Led indicator pin (LED_PIN) */ #include <AccelStepper.h> //Output Pins: const int STEP_PIN = 2; const int DIR_PIN = 3; const int Z_PIN = A0; //Input Pins: const int MIC_PIN = A1; const int LED_PIN = 7; const int RESET_PIN = 6; //Programming Constants const int DTAP_COOLDOWN = 115; //Number of loop cycles idle after single tap detection until second tap detection begins. const int CODE_LENGTH = 4; //Length of door code const int CODE[CODE_LENGTH] = {1, 1, 2, 1}; // 1 Indicates single tap, 2 indicates double tap, First knock is left digit const int DTAP_SAMPLING_PERIOD = 1200; //Period after a first tap detected in which a second one could be registered, roughly measured in clock cycles (#of loops) const int MIC_THRESH_OFFSET = 50; //Relative thresholds to offset bias above or below which a knock is registered (in LSB) const int XL_THRESH_OFFSET = 4; //Global Variables AccelStepper motor(1, STEP_PIN, DIR_PIN); int mic_min = -1; int mic_max = -1; int xl_min = -1; int xl_max = -1; int codeIndex = 0; void setup() { //Setting up all sensor pins: pinMode(Z_PIN, INPUT); pinMode(MIC_PIN, INPUT); pinMode(LED_PIN, OUTPUT); pinMode(RESET_PIN, INPUT); digitalWrite(RESET_PIN, LOW); //Internal Pull-down resistor used motor.setMaxSpeed(600); motor.setAcceleration(300); motor.setCurrentPosition(0); motor.moveTo(0); while(motor.distanceToGo() != 0){ motor.run(); } Serial.begin(9600); calibrateSensors(); //Sets Mic and XL Bias, need absolute silence and no vibration for this. Takes about 2 seconds } void loop() { //Begins continuous listen for correct input combination int xl_val = analogRead(Z_PIN); int mic_val = analogRead(MIC_PIN); bool xl_tap = xl_min > xl_val || xl_max < xl_val; bool mic_tap = mic_min > mic_val || mic_max < mic_val; if(xl_tap && mic_tap) { //Needs to be both xl_tap = 0; mic_tap = 0; int dtap = doubleTap(); if(CODE[codeIndex] == dtap) { //Checks registered taps against code codeIndex++; if(codeIndex >= CODE_LENGTH) { //Reaches the end of the combination, time to open openProcedure(); delay(10000); codeIndex = 0; } } else { //Wrong code value codeIndex = 0; //Reset index for another try digitalWrite(LED_PIN, HIGH); delay(500); digitalWrite(LED_PIN, LOW); //Cooldown time for another try } } } void calibrateSensors() { digitalWrite(LED_PIN, HIGH); Serial.println("Begining Calibration, wait 2 seconds..."); int avgXL = 0; int avgMic = 0; for(int i = 0; i < 20; i++){ //Takes average of both sensors when still to figure out the sensor bias offsets avgXL += analogRead(Z_PIN); avgMic += analogRead(MIC_PIN); delay(100); } avgXL = avgXL/20; avgMic = avgMic/20; mic_min = avgMic - MIC_THRESH_OFFSET; //Calculates range for each sensor mic_max = avgMic + MIC_THRESH_OFFSET; xl_min = avgXL - XL_THRESH_OFFSET; xl_max = avgXL + XL_THRESH_OFFSET; digitalWrite(LED_PIN, LOW); } int doubleTap() { //Listens for double tap, if double returns 2, if single returns 1 delay(DTAP_COOLDOWN); //No detection allowed for(int i = 0; i < DTAP_SAMPLING_PERIOD; i++) { //Detection begins int xl_val = analogRead(Z_PIN); int mic_val = analogRead(MIC_PIN); bool micTap = mic_min > mic_val || mic_max < mic_val; bool xlTap = xl_min > xl_val || xl_max < xl_val; if(xlTap && micTap) { //Need both to register a tap to prevent false positive. delay(DTAP_COOLDOWN); return 2; } } return 1; } void openProcedure() { //Opens and waits to close door until user input on reset button digitalWrite(LED_PIN, HIGH); openDoor(); while(!digitalRead(RESET_PIN)){ } digitalWrite(LED_PIN, LOW); releaseDoor(); } void openDoor() { //Opens the door motor.moveTo(600); while(motor.distanceToGo() != 0){ motor.run(); } } void releaseDoor() { //Releases the door motor.moveTo(0); while(motor.distanceToGo() != 0) { motor.run(); } }
Comments are closed.