My main project is a keypad-and-fingerprint-scanner-secured safe. It features a 3×4 matrix keypad and an electronic fingerprint scanner. When the fingerprint scanner detects a valid fingerprint after the correct 4-digit password is typed on the keypad, a servo inside the safe will turn to unlock it.
Area of Interest
Lick-Wilmerding High School
From my six weeks in this program, my biggest takeaway is that sometimes your best resource is yourself. At the beginning of the program, I would often ask my instructors simple questions, and they would answer with “search it up.” In having to figure out problems for myself with minimal intervention from instructors, I was able to get more out of this program than I would’ve otherwise. I learned how to be more resourceful on the internet. I also learned how to work more independently. Knowing that I am able to complete a project with little help gives me a lot of confidence going into the future.
Another skill that I was able to practice was handling unplanned problems. Though I made plans and goals for what I was going to do to finish my project, things would rarely go perfectly as planned. I had to think on my toes just as much as I had to plan. In my six weeks at Bluestamp, I had to stay mentally tough and focused to move forward when things went wrong. When something turned out to work terribly, I had to tell myself not to give up, even when I was on the verge of an emotional breakdown. Being able to push through all my project’s problems really empowered me and showed me that I am more capable than I originally thought.
Though Bluestamp hasn’t changed my intended field on study in the future, it has increased my interest, confidence, and knowledge in the field of engineering. Hearing from the guest speakers was a useful experience, as I got to hear about experiences and advice from engineers of the real world.
Overall, I really enjoyed my time here at Bluestamp Engineering, and I think that this program is one that every aspiring engineer should experience.
Advice for Making this Project
Make sure to order a stable box that is practical for a safe. If you want to go for aesthetics like I did, that’s fine, but if you really want a usable safe, order a metal file cabinet or some other heavy duty container. If you are buying a box that comes in parts, then be cognizant of how it’s constructed – you would not want a box that could be deconstructed from the outside, if at all. It’s preferred that you buy a container with a pull-out door rather than a hinged door, as there will be less leverage when opening the door, thus making the lock more effective.
Servos draw a lot of power. This is especially relevant if you are using multiple servos. Servos tend to suck up a lot of energy, meaning if you are powering the servo through an Arduino’s 5V pin, the servo can shut off the Arduino if the Arduino doesn’t have enough voltage going into it. From experience, the minimum voltage for keeping the Arduino on while having it power a servo is 9V. If you are planning to power multiple servos using the Arduino, then good luck. It’s probably better to just power the servos directly from a battery.
Make sure your lock is durable and solid. If there’s one thing that will fail completely, it’s your locking mechanism. For my project, I had to scrape up some random parts to come up with a half-solid locking mechanism, and it worked out okay. However, okay isn’t enough to keep people out of your safe. Make sure your servo is soundly attached to something, and that the lock is set up in a way that won’t allow people to break your servo. Use durable materials for your actual lock mechanism, such as metal.
Final Milestone: A Complete Safe
For my final milestone I have completed my safe. All the parts work together as intended. The lock system that goes with the servo is in place. The frame is constructed of wood, while the door is made of MDF fiberboard. In addition to my base project, I have added a buzzer and a spy camera.
How it Works:
Final Milestone Documentation
For my final milestone, I have my safe working, with a couple add-ons. I have all the code and hardware working together with my lock mechanism and door. Though there are a few flaws, the safe works exactly the way I want it to. One of the major flaws is that the safe isn’t too hard to break into using brute force. In constructing the safe in a way that it wasn’t meant to be by inserting the screws from the inside, I compromised the structural integrity of the box. There are a couple gaps in the box, but the most glaring one is at the hinge of the door. The wood isn’t very strong, so someone could easily break my project with a hammer. Looking back, I should’ve ordered a metal filing cabinet, which would’ve saved me all the construction time, and would’ve also made the safe much stronger. The electronics aren’t extremely well hidden either. If I had more time, I would’ve made a front board in addition to the floorboard. The servo port isn’t very strong or stable either, so someone could rip the door off with a crowbar.
The improvements made in this milestone from milestone 2 are mainly hardware improvements. As one of my modifications, I have a buzzer working. This buzzer serves the purpose of giving me auditory feedback. I have programmed different sounds for different events, allowing me to distinguish what is happening. This buzzer makes it so that I don’t have to look at a serial monitor to know what part of my code is running.
Another modification I have added is a spy camera. If the password is typed wrong 5 times, the camera will snap a picture, and then store it on a microSD card, allowing me to see the picture from a computer anytime I feel like it.
Instead of using a breadboard, I have a proto board, making the wiring more reliable and permanent. I made a common 5V power rail and a common ground rail on either side of the board, so I can simply carry on the wiring from my breadboard onto my final safe.
My safe is constructed from a wooden box that I ordered from Amazon. Because it was originally meant to be a shelf, there were many things about it that weren’t ideal for a safe. First, the door had a huge hole in the corner, which was mainly for aesthetic. This presented a problem, because somebody could mess with what’s inside through it. I fixed this by constructing the box so that this door would be in the back. I was able to use this hole to access the 9V battery. Another problem was the lack of a hinged, opening door. The original door was nested within the frame, so a hinge would not work. I fixed this by using a custom cut MDF fiberboard piece as the door. My last problem was the way in which the box was meant to be constructed. Originally, the screws were supposed to be screwed in from the outside, but that would compromise my safe, as someone could just deconstruct my safe from the outside. I was able to solve this by cutting small MDF blocks, and placing then at the intersections of each of the sides. This allowed me to keep the box together with screws from the inside. The only problem with this method was that the MDF had a grain, so when I tried to attach screws from two sides, the grain would break, weakening the structure of the MDF. Despite this, the box still held together well.
My locking mechanism is simply an L-bracket attached to my door that hooks onto the servo port when the servo is in “lock” position. The port and the L-bracket are made of metal, so the mechanism is durable.
I added a board on the inside to cover up most of the electronics, while also giving the safe a flat floor.
Because of the buzzer and the spy camera, I had to make some changes to my code. Coding the buzzer onto my Arduino was very simple, as Arduino already has functions for buzzers. I simply have to call the function tone(pin,frequency) in order to get the buzzer to sound. The pin input for the function depends on which pin the input wire of the buzzer is connected to. The frequency input allows me to control the frequency of the buzzer. However, the buzzer does have some limitations, so making the exact sounds I wanted was sometimes difficult, if not impossible. To turn off the buzzer, the function notone() is used. I integrated the delay() function a lot in order to make more unique and noticeable sounds.
Integrating the camera into my code was somewhat complicated. I made it so that when the password was typed in wrong five times, the camera would snap a picture. To do this, I set a global variable called cam. Cam starts at zero and every time the password is typed wrong, cam++ adds one to the value of cam. At the beginning of each loop, the Arduino checks to see if cam is five. If it is, then it will set pin 12 as an output pin. The camera is triggered when the transmitting wire is touched to ground. If touched under half a second, the camera will snap a picture, and if it’s touched for more than half a second, it will begin to take a video until it is touched to ground again. Once pin 12 is set to an output pin, it will be set at LOW for under half a second, making its output 0V, essentially making it behave as ground. Then the pin is set to high, meaning it outputs 5V; this ends the transmitting wire’s connection to ground. By the time all this is done, the camera will have snapped a picture, storing it on the microSD.
PCB Board Schematic
Credit for this project idea goes to Gedalia K (Bluestamp NYC 2015).
Second Milestone: Battery-Powered Lock System
For my second milestone I have added my servo, an on/off switch, a 9V battery, and a function for adding fingerprints to the database. Just like before, the correct password must be typed in before the fingerprint scanner turns on, and once the fingerprint scanner detects the correct fingerprint, the servo will turn. For enrolling fingerprints, once ‘*’ is pressed, and the correct password is typed, the fingerprint scanner will be ready to enroll a new fingerprint. Because of the 9V battery, the system can run without being hooked up to the computer. The on/off switch is between the battery and the rest of the system, so when the switch is off, nothing will work. This is so that the battery can preserve power, and so that the fingerprint scanner and servo won’t overheat from being on for so long.
How it Works:
For this milestone I have a servo, on/off switch, and 9V battery working in addition to what was working in milestone 1. The battery powers the arduino board, which then powers the fps and the servo through the 5V pin. The LED in the on/off switch is powered by the battery, with a 470 ohm resistor in between. When the on/off button is pressed to be in on mode, the built-in LED in the switch and the arduino will be powered, activating the whole system. The servo is powered by 5V, so resistors aren’t necessary to protect the servo. When the switch is put into off mode, current from the battery is cut off. This turns off the fps and the servo, both of which can overheat if left on for too long.
Setting up the * button as the enroll fingerprint button was really challenging. I would have to find a way to protect it with a password while distinguishing to the arduino that I was entering a password in order to enroll a fingerprint. To do this, a global boolean data value called “mode” is declared “Mode” starts as false, and while mode is false, the arduino will run the section of the code meant for unlocking the safe. All this code goes under a while loop [while (mode == false)]. Pressing * changes the value of “mode” to true. The code responsible for enrolling fingerprints is under another while loop [while (mode == true)]. Once “mode” is changed to true, the arduino will begin to run the section of code responsible for enrolling fingerprints. Both sections of code will not run at the same time, as each have opposite requirements; this makes it so that my password will not try to enroll and fingerprint and unlock the safe at the same time.
Because a lot of my coding uses deeply nested if statements, it is easy to get “stuck” in the code, meaning that the code would stop looping if a certain requirement wasn’t met. To bypass this issue, goto functions are implemented in many of the else statements. My goto functions are all set to jump to “start:”, which is placed at the beginning of void loop. I make sure to reset all other variables and data bytes during the else statements, so that when my code goes to the very beginning of the loop, no previous inputs will be carried over.
To simplify and make my code easier to read, I have made a lot of common lines of code into functions. Once I have established what these functions do, I can call them whenever necessary. I can also set what kind of outputs the function can give, and what inputs are necessary to get it to start running. Passwordcount() is a function responsible for keeping the password string limit to 4. Passwordcheck() is a function responsible for verifying the entered password. Reset() is a function that is responsible for resetting all variables and data bytes, and for turning off the LED on the fps. Exit() is a function used for exiting from the section of code responsible for enrolling fingerprints.
Milestone 2 Setup
First Milestone: Security System
For my first milestone I have my keypad and fingerprint scanner working. Once the correct password is typed into the keypad, the fingerprint scanner will turn on, and once the fingerprint scanner detects a valid fingerprint, the LED will turn on.
How it Works:
For this milestone I have my keypad and fingerprint scanner(fps) working. Once the correct password is typed into the keypad, the fps is turned on. Next, once the fps detects a valid fingerprint, it will turn on an LED. The inputs and outputs for the keypad are transmitted through 7 pins, 3 for columns and 4 for rows. These pins are labeled from 1-7 on the keypad. Every time I press a key, a signal is transmitted through two pins, a column pin and a row pin. Each key has a unique combination of row and column pins that it transmits through. Using a 560 ohm and a 1k ohm resistor, I made a voltage divider between the Arduino and the receiving signal wire of the fps because the Arduino runs on 5v, while the processing logic of the fps runs at 3.3v. This voltage divider doesn’t need to be made for the power source of the fps, because it runs on 5v power.
My coding for both the fps and the keypad use libraries. I use a library made specifically for the fps, a library for my keypad, a library to help me set a passcode for the keypad, and a library for communicating with the serial monitor. These libraries are packages of code made by other people to make life easier. When included in my code, I can pull out functions from these libraries to run the specific operations for my keypad and fps. I tell the arduino to include these libraries by typing #include <library name>. Then, I need to declare an instance of the object the library corresponds to, in my case, I need to declare an instance of my keypad, password, and fingerprint scanner. This makes it so that the board knows that these objects exist, and what the libraries are for these objects.
The array at the top of my code makes it so that the buttons on my keypad can interface with the arduino board correctly. An array is simply a list of variables. The byte rowpins and columnpins establish which of my arduino pins are responsible for the column pins and which are responsible for the row pins.
Under this I have 3 instances declared, Keypad keypad, Password password, and FPS_GT511C3 fps. These make it so that I can use the libraries by declaring them within the code. The first part denotes which library I am declaring, and the second part denotes what I will call it when I use it in the code. For example, if I wanted to use a function from the FPS_GT511C3 fps library, I would type “fps.(function)”. Next to Keypad keypad, I run a function that makes the internal keymap match up with the array. Next to Password password, I have set the password for my password library, as some of the functions rely on knowing the password in order to work. Next to FPS_GT511C3 fps, I declare the input and output pins for the arduino to communicate with the fps.
Under void setup, serial.begin establishes the baud rate of the arduino. This makes it so that the arduino is communicating at the same speed as everything else. As digital communication is essentially a series of 1s and 0s, objects must communicate at the same speed in order for them to understand each other.
Under void loop, the functions that make up the body of my program are run. Keypad.getkey is a function from the keypad library. This function returns the key that is pressed. I use this combination with serial.println later on so that I can read which key I have pressed on the serial monitor. This is useful for knowing what is going on and what works, so that troubleshooting and debugging is much easier. The if(key) line of code basically says “if I do what’s in the parenthesis, run the code within the corresponding brackets.” So in this case, this code tells the arduino to run the code in the brackets if a key is pressed. For an if statement, if the requirements within the parenthesis are met, then the code within the brackets will be skipped over.
Within the brackets for if(key), I have a switch(case) statement. A switch(case) essentially does the same thing as an if statement. However, switch(case) statements are structured in a way that makes it easier to account for multiple varieties of inputs. Switch (keypad.getState()) basically says “if any of the keys are in a certain state, then run the code assigned to that state.” Keypad.getState is a function from the keypad library that returns the state of any one of the 4 possible states of the keys (IDLE, PRESSED, RELEASED, HOLD.) In my case, I will only use PRESSED, so under my switch statement, I only have one case: PRESSED.
The if(key) statement under this tells the arduino to run the code within if I press any key. Password.append is a function from the password library. It tells the board to add whatever key I press into the password string. Like any other digit-based password, my password has to be typed in the right order to be read as the correct password. For this reason, password.append is essential. Num++ refers to the integer variable I set earlier in the code (int num = 0). I set this integer variable before void loop so that it is a global variable, which makes the value consistent and true wherever I am in the code. Num++ adds 1 to the value num everytime I press a key. This is used in combination with if(num==4) in order to set the password as a 4 digit password. Serial.println(num) simply prints the number of digits in the password string to the serial monitor.
Under if(num==4), I run the code that checks to see if the password was right. First, num = 0 resets the password string to 0 digits, so that I can type the password again. Password.evaluate is a function from the password library that checks whether the inputted password is equal to the set password. This function outputs a boolean value, meaning it either outputs TRUE or FALSE. The serial.print function helps me see whether something is working as intended via the serial monitor. If this password is right, then the arduino runs the code in the next set of brackets.
Fps.open turns on the fps, and fps.setLED controls the LED inside the fps. SetLED can be in two modes, TRUE or FALSE. TRUE turns on the LED, and FALSE turns off the LED. The delay is so that I have time to put my finger on the fps. Fps.IsPressFinger is a boolean function from the fps library that detects whether there is a finger pressed on the fps or not. If this function outputs TRUE, then the arduino will run the code in the brackets.
Fps.CaptureFinger is a boolean function that tells the fps to scan the finger that is currently on it. There are two modes, TRUE and FALSE. TRUE is the more precise scanning mode, which is used for enrolling fingerprints into the database. FALSE is the more rough scanning mode, which is used for identifying fingerprints because it’s faster. The next two lines of code tell the fps to identify and verify the fingerprint against all fingerprints enrolled on the database. The fingerprints are stored on the fps instead of the arduino, so the fps does most of the work identifying and verifying fingerprints. Fingerprints, when enrolled, are stored as a number from 0-199 (0-199 because the fps can store up to 200 fingerprints). When the fingerprint detects any of the ids as being from 0-199 (basically if the id is on the database), then the arduino will run the next bracket of code.
DigitalWrite is a function that sets a HIGH or LOW value to a digital pin. As the pin connected to my LED is set as an output pin. HIGH tells the pin to output a voltage, while LOW tells it to output nothing. In my case, digitalWrite(12,HIGH) tells pin 12 to send a voltage to the LED, turning it on. Fps.setLED(FALSE) turns off the LED on the fps.
The else statements are extensions of the if statements that reset the code to step 1 if any of the requirements aren’t met (i.e. wrong password, wrong fingerprint).
If(key == #) sets the # key as the “reset” button. When the # key is pressed, the password string, the fps LED, and the LED are all reset.
Keypad Matrix Pin Grid
Starter Project: Electronic Dice
How it Works:
Once the die is dropped on a table (or any other hard surface), the piezo sensor that is taped to the base senses the vibrations. The piezo sensor then sends an analog voltage along into the PCB board. In this case, the analog signal is an amount of voltage determined by how much vibration the piezo senses. If the die is asleep, then the sensor also sends a signal telling the die to wake up and run the program. A diode along the way limits the voltage, so that it doesn’t overload the sensitive PIC chip.
Once the analog signal reaches one of the legs of the PIC chip, the chip converts the analog signal into a digital decimal value. The last three digits of this decimal value are used to generate a value from 1-6. Based on this value, one of four legs of the PIC chip sends signals through the resistors to the LEDs. In order to show all the dice configurations from 1 to 6, only four combinations of LEDs are required (shown in Figure 1 below) – each of four legs on the PIC chip is responsible for one combination of LEDs.
In order to assemble all configurations of 1-6 with these 4 combinations, a programming loop displays all of the die throws in a sequence of three steps (shown in Figure 2). This loop prevents some LEDs from being brighter than others due to being lit for a longer time.
Once the die is left alone for 15 seconds, the PIC chip is told by a program to sleep. Once in sleep mode, the PIC chip drains very little battery. When the PIC chip goes to sleep, the same pin on the PIC chip that is used to read analog signals from the piezo is told by a program to “interrupt on change,” so once the pin senses any input from the piezo, the sleep mode will be interrupted, and the original die rolling program will resume. When in sleep mode, this same pin also changes into a pin that reads digital signals, because the “interrupt on change” program doesn’t work with analog pins. Once awoken, however, the pin changes back to an analog pin.
Problems and solutions:
My only problem surfaced after the die was finished. I found that the the die kept rolling 1s. I originally thought that this was just because of chance. As dice are completely random, it’s totally plausible that somebody could be consistently rolling 1s on any given day. However, I really started getting suspicious after about an hour of consistently rolling my die, and consistently rolling 1s. With an engineer’s mindset, I set out on finding a way to fix this. I first tried to correct this by actually gluing my piezo sensor to the acrylic base (I had originally taped the piezo sensor to the base). My reasoning behind this was that because the piezo sensor worked based on vibrations, the tape was messing with how the vibrations got to the sensor. After the super glue dried, I anxiously rolled my die again, but unfortunately, I still kept rolling 1’s. Unsatisfied with this result, I kept trying to determine the source of the problem. I observed that when I rolled the die by tapping lightly on the bottom of the acrylic base, the die would work “correctly” and roll a more varied series of numbers. From this, I inferred that dropping the die would overload the piezo sensor. The piezo sensor works within a certain range of vibration, and being quite sensitive, it isn’t hard to go above the range of vibration the piezo accepts. By overloading the piezo sensor with too much vibration, I would make the piezo default to sending the voltage that would result in a 1. I plan to try to fix this by padding the bottom of the acrylic base with a soft material, such as felt, in order to dampen the vibrations that get to the piezo sensor.
All instructions, figures, and the schematic are credited to Spikenzielabs.