Ultra-secure Programmable Lockbox

Adarsh Jayakumar
Timon Amirani
Cameron Boroumand

Our final project for ECE 4760: Digital Systems Design Using Microcontrollers is an ultra-secure programmable lockbox. The box can be unlocked using a keypad, three tunable knobs, a 'knocking' pattern (through a piezo electric sensor), and a fingerprint sensor. The user must provide the proper inputs to each of the various systems using the directions displayed on a TFT LCD screen. Once the box is unlocked, the user may update the passwords, combinations, and fingerprints that must be provided to unlock the box again.

We wanted to build something that was useful and appealing to a wide variety of people. As seniors nearing the end of our undergraduate years, we envisioned using what we have learned over the past seven semesters to build something that could be given as a gift to those that made our time here possible, our mothers. This box can be used to securely store jewelry and other valuable merchandise. As our mothers current jewelry boxes do not contain enough wires and microcontrollers, we dedicate this project to them.

This lockbox is a highly marketable product which provides real security in a unique way. This product may be particularly attractive to younger children who would like to have a toy box to which only they know the passcode. In addition, this box is equipped with multiple programmable hardware devices which may perk the interest of those interested in DIY electronics.

High-Level Design


Figure 1: Initial Design IdeaThe lockbox comes installed with factory settings. That is, the keypad password, potentiometer knob combination, knocking pattern, and fingerprint are preset. The factory settings are as follows. The password is set to 1-2-3-4. Each of the three tunable potentiometer knobs are set to unlock at a range of 320 to 380. The knock pattern is set to a knock, pause, knock, knock pattern. Finally, the user sends in a fingerprint, or a set of fingerprints, when ordering the box. This set of lock stages provides for ultimate security. Upon retrieving the box, the user unlocks it for the first time using the factory settings and then can reset the four digit password, the unlocking values of each potentiometer, and the knocking pattern.

Flow Chart

Figure 2: Flow Chart The user progresses through the system in accordance to the flowchart, starting with the passcode, then moving on to the tunable potentiometers, then onto the piezo sensor for knocking, and finally onto the fingerprint scanner. The code and hardware was done in such a manner that the user must go through in this way.

Hardware/Software Trade-offs

In terms of trade-offs between hardware and software, a multiplexer was used between the potentiometers and piezo sensor for knocking. Using a mux was necessary because we would not have had enough ADC channels for each of the potentiometers and piezo speakers otherwise. The mux allowed us to read values from each of the potentiometers and piezo through one ADC channel

Analog Circuitry

A large portion of the project was devoted to building and testing standard analog circuitry for each portion of the lockbox. The schematics for these are included below.

Figure 3: Potentiometer and Piezo Schematic

Potentiometer and Piezo

The potentiometer and piezo circuitry was accomplished through the addition of an analog multiplexer. This multiplexer was used in order to simplify the code necessary for the potentiometers and piezo-electric sensor by reducing the amount of ADC ports running from four to one. The three potentiometers acted as tunable knobs for the user to set and unlock the box, similar to a classic safe. Each potentiometer had one end terminal connected to Vdd (3.3 Volts) and the other end terminal conected to ground. The wiper of each potentiometer was connected through a 330 Ohm resistor to the first three inputs of the multiplexer. Meanwhile, the piezo electric sensor acted as another safety mechanism for the box. The negative terminal of the piezo electric sensor was connected to ground. The positive terminal of the piezo electric was connected to the fourth input of the multiplexer in parallel with a 1 Megaohm resistor to ground. The multiplexer was powered through Vdd (3.3 Volts) with its INH, Vee, and Vss terminals all tied to ground. Because only four inputs were required, select signal 'C' was also grounded. Select signals 'A' and 'B' were connected to digital pins of the microcontroller (pins 14 and 26 respectively) with the output of the mux connected to an analog pin (pin 24).

Figure 4: Solenoid Valve Circuit

Solenoid Valve

A 12 Volt solenoid circuit was used to drive the valve high and low based upon the voltage from a microcontroller digital output pin. The basis of this circuit was taken from Bruce Land’s ECE 4760 Lab 4 project page (Link here). The circuit acts as a first order low-pass filter when the valve is off and a second-order low-pass filter when the valve is on. In order to safeguard all components and the MCU from any inductive spikes of the valve, a 4N35 opto-isolator was utilized to separate ‘valve ground’ and ‘MCU ground’. The BUZ73 FET sets the voltage of the valve based on the signal generated from the opto-isolator transistor. A 1 MΩ resistor was placed at the base of the opto-isolator’s transistor in order to optimize the fall time of the solenoid. In addition, a 100 nF capacitor was placed in parallel with the valve in order to filter noise from the input to the valve. Finally, the FET was protected from inductive spikes through the flyback diode in parallel with the valve. This flyback diode essentially cycles energy back to the power source and back through the valve instead of the transistor when the valve is transitioning from a high to low state.

Figure 5: Keypad Diagram Figure 6: TFT LCD Screen credit to

Keypad and TFT

The keypad used for entering an unlocking code was the same as the keypad used in Lab 2 in the implementation of the DTMF dialer. It used seven pins on the PIC32, with rows 1-4 taking up pins 2, 3, 9, and 10 on the PIC32, and columns 1-3 taking up pins 16-18 on the PIC32 microcontroller. The keypad uses 10 Kiloohm pull-down resistors on each column to provide a viable path to ground from the column pins, and uses 300 Ohm resistors on the rows to provide a viable path to ground from the row pins. Each switch connects a row wire to a column wire. The TFT LCD screen was used to interact with the user as they unlock the box. The connections to the screen itself takes pins 4, 5, 6, 22, and 25 on the PIC32 microcontroller. As the user goes through each step to unlock the box, the TFT displays information such as the unlocking step, or is used for feedback of information such as potentiometer values or the current passcode being entered.

Fingerprint Scanner

The fingerprint scanner was connected to the PIC32 through an external connection through an Arduino microcontroller. The fingerprint scanner was connected via a 4-pin JST terminal with connections to VDD, ground, RX, and TX (pins 4, 5 on the Arduino). The Arduino was used due to the fact that there is public source code, linked here. The Arduino communicated with the PIC32 by outputting a 5V signal from pin 12 to the PIC32 microstick whenever a correct fingerprint was detected. In addition to sending a signal to the PIC32, a signal was sent to the solenoid valve to unlock the box, as the fingerprint scanner is the final security measure.


Figure 7: Back of LockboxThere were three separate voltage rails that needed to be supplied for this product: 12 Volts for the Solenoid valve, 5 Volts for the Arduino and 3.3 Volts for the PIC32, multiplexer, and solenoid circuit. We used a 12 Volt AC-DC wall adapter and two linear regulators in order to provide all of these power rails. The wall adapter plugged into a barrel jack on the back of the box which went straight to the 12 Volt rail for the solenoid valve. A LM340 5 Volt LDO regulator and MCP1702 3.3 Volt LDO regulator were supplied with 12 Volts and produced 5 Volts and 3.3 Volts, respectively. Each of these regulators contained two 100 nF capacitors (one from input to ground and another from output to ground) in order to reduce transient voltage fluctuations caused by rapid changes in load current. The grounds for the 5 Volt and 3.3 Volt rails were shorted together (in order to create a common ground) and optically isolated from the 12 Volt rail ground. A final 100 nF capacitor was placed between the positive and negative 12 Volt rails in order to prevent transient voltage spikes whenever the solenoid valve was triggered.



This thread implements a finite state machine (FSM) to debounce button presses on the keypad and stores in a buffer the values input by the user so that it can be checked against the passcode required to pass this stage. The finite state machine, as used in our Lab 2 assignment, can be found below:

Figure 8: Keypad FSM

We use a finite state machine to discern valid keypad presses. The finite state machine begins in the ‘Release’ state by checking to see if the keycode is equal to -1. It does this by spawning the scanKey thread, which polls for key presses, by using the PT_SPAWN() function. The thread then yields for 30 milliseconds using PT_YIELD_TIME_msec(30). If keycode is equal to -1, that means no button has been pressed and we return back to the ‘Release’ state through the ‘Yes’ transition. If keycode is not equal to -1, we go through the ‘No’ transition to the ‘MaybePush’ state, storing our value of keycode into a new variable possible along the way. Within the ‘MaybePush’ state, we check to see if keycode is equal to possible, meaning that nothing has changed and the button press seems to be stable. If the answer is ‘No’, we go back to our ‘Release’ state and call our scanKey thread. If the answer is ‘Yes’, the most important portion of the FSM occurs. In the transition from the MaybePushed to the ‘Pushed’ state, the digits are stored (as the possible values). Using the keycode variable set in the scanKey thread, and a separate counter variable, buf_count, valid key presses (i.e. keys zero through nine) are placed inside a buffer called key_buf. If the key pressed is not a valid number, then the digit is not added to the buffer.

Within the ‘Pushed’ state, we once again check if keycode is equal to possible. If the answer is ‘Yes’, we call our scankey thread and feedback into our ‘Pushed’ state. If the answer is ‘No’, we enter into the ‘MaybeNoPush’ state. Within the ‘MaybeNoPush’ state, we check if keycode is equal to possible. If the answer is ‘Yes’, we must check if our keypad is properly debounced by returning to our ‘Pushed’ state and calling the scankey thread. If the answer is ‘No’, we simply return back to the ‘Release’ state and call our scankey thread.

Once the finite state machine has yielded a valid keypress, the number is stored in a buffer. Once there are four numbers in that buffer, the PIC32 checks if the number sequence in the buffer matches the passcode. If it does, then the keypad stage is passed and the user moves onto the potentiometer. If the number sequences do not match, then the user must input another four-digit sequence and the data in the buffer is overwritten by this next fourth-digit sequence.


We use ADC channels to continously read the outputs of the three potentiometers. Because each of the potentiometers is connected to a multiplexer, we must configure the select bits of the multiplexer accordingly before we read from each potentiometer. After reading the values from each potentiometer, we map them from (0,1024) to (100,999) using a simple linear mapping so that the user can only input 3-digit potentiometer values. We display this value on the screen so that the user can easily adjust the potentiometer knobs to the correct combination. Each potentiometer has its own unlocking value, and any number that is within 30 of that value is considered valid. For example, if the left potentiometer has an unlocking value of 230, then the user must input a value between 200 and 260 on the left potentiometer. We allow a range of plus or minus 30 to allow for a nicer user experience since the values read from the potentiometers oscillate slightly. The range could be modified to a smaller one to increase security.

The PIC32 records the time at which the user has input valid values on each potentiometer. It then continues to poll the three potentiometers to ensure that the valid values are held for 2 seconds. If any of the potentiometer values leave their valid range before the two second countdown, then the potentiometer stage is not passed and the user must again input the correct values. IF the values are held for the full two seconds, then this stage is unlocked. We require the user to hold the correct values for two seconds so that a rogue user cannot simply continously twist and turn the knobs and hope to pass the correct values just once to unlock this stage. Once this stage is unlocked, the user moves onto the piezo stage.


The piezo protothread handles the piezo unlocking stage. This stage requires the user to knock the box in a certain 3-knock pattern. Our first task in writing this protothread was to determine how to record a valid knock and to ensure that a single knock was not counted more than once. We connected the piezo output to an ADC channel on the PIC32 and stored in a variable the values read by the channel. We noticed that, when the user was not knocking the box, the value oscillated between 0 and approximately 15. We also noticed that, when we knocked the box and caused the piezo to vibrate, the ADC channel would record one or more consecutive values above approximately 30. Hence, we deduced that a valid knock occurs when the ADC channel records a value above this threshold. After each recorded knock, the PIC32 yields for 50 milliseconds so that values above the knock threshold that follow immediately after the valid knock are not counted. We felt that 50 milliseconds was an appropriate amount of time to yield because a user cannot physically hit the box more than once in 50 milliseconds.

Having determined what constitutes a single valid knock, we set out to determine what constitutes a valid knock sequence. We used time as the distinguishing factor between various knock sequences. We first decided on our own knock sequence by having one partner knock the table while another pertner recorded the time intervals between successive knocks. This, of course, provided crude data but it worked in establishing time intervals for our factory setting knock pattern. The code is written such that the microcontroller records the time at which each knock occurs. After recording the first knock, the microcontroller polls the ADC channel to determine if a second knock occurs in the valid time interval. If it does not, then it reverts to polling for the first knock. If the second knock does occur in the valid time interval, then the microcontroller goes on to polling for a third valid knock. If the third knock occurs in the valid time interval, then the piezo stage is passed the user moves onto the fingerprint scanner. Otherwise, the microcontroller reverts back to listening for the first knock in the sequence again. This sequence of events describes a finite state machine that is shown below.

Figure 9: Piezo FSM

The piezo took a significant amount of time to tune. At first, it was not clear what the threshold value for a valid knock should be, and finding a number that worked well took a significant amount of trial and error. This stage of the unlocking mechanism was particularly difficult to debug because it required the user to knock the box in a very precise manner. Thus, at times, we could not be sure if the piezo stage was malfunctioning due to a bug in the code or hardware or because we were not knocking the box with the correct rhythm. We were able to overcome this issue by increasing the intervals in which the second and third knocks would be considered valid knocks in the sequence while making sure to keep the restraints tight enough such that a rogue user could not simply knock the box three times and pass the piezo stage simply by luck.

Fingerprint Scanner

To detect a valid fingerprint, we used an Arduino Fingerprint Scanner library built by Josh Hawley. When the PIC32 is in the fingerprint scanner state, it polls the Arduino for a HIGH input. When the Arduino senses a valid fingerprint, it sends a HIGH signal to the PIC32 and drives the solenoid valve to unlock the box. Otherwise, it continously sends a LOW signal to the PIC32. Once the PIC32 has sensed a HIGH signal from the Arduino, the box is unlocked and the PIC32 moves onto the programmability state. It remains unlocked for three seconds, after which the solenoid valve closes again.


When the box is in the unlocked state, the keypad code, potentiometer combination, and piezo knock pattern can each be customized by the user. The prototheads used to unlock the box are the same protothreads that are used to configure the passcodes. If the user chooses to change the keypad code, the same keypad FSM is used to read the values that the user inputs. Once a four-sequence value has been input, the user is asked whether they would like to keep this new code, keep their current code, or input a different code.

To change the potentiometer combination, the user is asked to input new values for each potentiometer using the keypad. We chose to program the potentiometer combination using the keypad as opposed to the potentiometers themseleves to allow for an enhanced user experience. Using the keypad allows the user input exactly the combination that they would like. Although the factory settings require that each combination have a range of plus or minus 30, the user can choose a value that will not allow such a range. For example, the user can input 110 as the value for a potentiometer, in which case the range is bounded by 100 since the potentiometer values are mapped to (100,999). In this case, the user's range for that potentiometer would be (100,140). After inputting new values for each potentiometer, the user is shown their new combination range asked if they would like to update to the new combination, keep their current combination, or input a different combination.

Changing the piezo knock pattern requires the user to knock the box three times, in any rhythm or speed that they would like. The PIC32 records the relative times at which each of these knocks occur, and builds time intervals of plus or minus 300 milliseconds around them. This means that if the second knock occurs 600 milliseconds after the first knock, then the time interval for the second knock is (300,900). This may seem like an overly large interval for a knock to considered, but through trial and error, we found the programmability of the knock piezo to result in quite robust knock lock patterns. Also, a microcontroller is much more accurate than humans using a stopwatch in recording the times at which knocks occur. For this reason, the reprogrammed knock pattern seemed to even function better than the knock pattern that was shipped with the factory settings.

Command Thread

We set up a simple command thread that chooses which thread to run. During the unlocking stage, the command thread runs the code from keypad stage to potentiometer stage to piezo stage to fingerprint scanner stage. This sets up the cascading system quite nicely, as a user can only be in the potentiometer stage, for example, after they have passed the keypad stage. Once the box has been unlocked, the command thread moves into the configuration state, in which the user can choose to change the keypad, potentiometer, or piezo lock. At this configuration state, the user can also choose to return to the unlocking stage to unlock the box again and run through the four cascading systems.


Speed of Execution

Although there are multiple stages to unlocking the box, a user can step through each one relatively quickly. We determined that it takes about 30 seconds for an experienced user to unlock the box from start to finish. This may be slower than a typical lock box, but this is the drawback that comes with the extra security.


The box never unlocks when given incorrect inputs. Following hours of testing, we concluded that a user can only unlock the box by providing the proper input at each stage, and that any variations from the proper input will be denied. We also verified that our box is easily understandable by other people. We gave some of our peers in the class the factory settings so that they could unlock the box and reprogram its settings. Most of the time, they were able to do with this ease, and this exemplified not only the robustness of our lock box but also that our design made stepping through the various stages rather intuitive.


This product is very easily usable by the general population, and is intended for those of all ages with basic reading and thinking skills. The box runs through each state, giving visual feedback to the user when each stage is reached and passed, as well as easy to follow instructions on resetting passcodes and such.

Our product can also be modified to be used by people with various special needs. For example, a person with extreme visual impairment may a braille keypad. The potentiometer stage may need to be removed since it requires the user to read the values from the TFT screen but the knock pattern stage could remain as long as the person can locate the box. In the future, we could enable the box to give speech feedback throughout the stages and effectively replace the TFT screen as the main interface between the box and the user. Of course, there are an innumerable amount of security systems that could be added to the box that would help make it more usable by all people, such as face recognition and voice recognition.


Figure 10: Lockbox Layout

Figure 11: Lockbox Interior
The integration of each portion of the lock box was done in a multi-step process. The box itself was quite small, so planning was essential to making the final product usable. The fingerprint scanner was placed in the bottom left of the box, with the keypad above it, and the TFT screen propped up on the right. When each individual component of the box was moved from the testing phase onto the box, the breadboards were substituted for perfboards to make the circuitry cleaner and less-space consuming. The perfboards, PIC32 microstick, and the Arduino were each placed inside the box itself.

Safety in Design

This design does not pose any dangers to the public or the environment. Some harm could be inflicted upon the user if the box is shut closed on their finger.

Video Demonstration


When designing the box, the team stressed the importance of its cascading nature and its value in increasing the security of the box. Each goal was met, with the keypad, potentiometers, piezo scanner, and fingerprint scanner being integrated into the design. The one element of the project proposal which was not integrated was the frequency detector. Our project proposal mentions a "note detector" stage which would require the user to play a specific frequency to pass. The team felt that this was unnecessary due to the fact that the vast majority of people could not pass this test without some exterior instrument or device. In addition, a four stage lock box with a final stage of a fingerprint scanner was felt to be very secure.

If our team were to do this project over again, we would focus on the reprogrammability aspect of the fingerprint scanner, as well as proper communication between the Arduino and PIC32, perhaps over an SPI or UART channel. Our team did not initially plan to make the lockbox repgrammable, and this made it difficult to configure the fingerprint scanner to be programmable by the user. However, we feel that our team did an excellent job of meeting the specifications put forth.


There are no known standards relevant to our project as there is no wireless connectivity into the box. However, each part of our project does satisfy any IEEE standards.

Intellectual Property Considerations

While working on this project, we drew extensively from work we had previously done in the course. In particular, we used the keycode state machine implemented in lab 2. We also went back to our code in lab 3 to reacquaint ourselves with the ADC software setup. The TFT display helper functions and PT thread were taken from lab2 of ECE 4760 and were written by Bruce Land and Syed Tahmid Mahbub. Additionally, we used open source code for the Arduino in dealing with the fingerprint scanner, written by Josh Hawley. It was asked that we include the original license message, which is as follows:

" Created by Josh Hawley, July 23rd 2013 Licensed for non-commercial use, must include this license message basically, Feel free to hack away at it, but just give me credit for my work =) TLDR; Wil Wheaton's Law ".

We look forward to working towards publishing our work next semester. We ask that anyone who wants to use our work for any purposes to first acquire our consent.

Ethical Considerations

Before we started our project, we read the IEEE Code of Ethics and we made sure to abide by it each step of the way. Foremost, we were not concerned with endangering the public or the environment as this lockbox is rather benign, but we understood that, should the box impose any dangers at any point, we would make them clear to the user.

All data presented and claims made in this report are valid to the best of our knowledge, and we properly credited others' contributions. We accepted criticism of our work, whether it was from Bruce or another student. For example, one of our peers pointed out that it seemed peculiar that a user could not update the passwords necessary to unlock the box for what if an intruder learns the codes? We acknowledged this shortcoming of our work, and despite the immense amount of time this required, we added the necessary functionality to make our lockbox programmable.

We feel that the project is honest and realistic in all its claims, and, in addition to being a non-discriminatory product, does not pose a threat of injury or harm to any person.

The IEEE Code of Ethics states that members of the IEEE community must seek to improve the understanding of technology and its appropriate application, and we feel that we leveraged the functionalities of various sensors and technologies and applied them in a very unique way, one that is not obvious or commonplace. We feel that our work is helpful and innovative, which is true with the spirit of engineering and the IEEE Code of Ethics. We are proud that our work further exemplifies the endless uses of a microcontroller, particularly the PIC32.

Legal Considerations

There are no legal considerations for our lockbox. There has yet to be an intruder capable of unlocking the box and thus we have not had any legal issues.


We would like to thank our Professor, Dr. Bruce Land, for helping our team work through each of these projects by providing valuable insight and advice. Additionally, we would like to thank each of the course TAs, especially Andrew Palmer, who oversaw our lab section and provided us assistance in understanding our Lab assignments when we needed it throughout the semester.


The group approves this report for inclusion on the course website. The group approves the video for inclusion on the course youtube channel.

Parts List

Name Description Link Price
5 V TTL Fingerprint Scanner Provides fingerprint functionality Link $31.95
12 V Lock-style Solenoid Locks/Unlocks the box Link $14.95
Large Piezo Element Provides knocking functionality Link $0.95
Arduino Uno Microcontroller for fingerprint functionality Link $6.61
Microstick II For programming and temporarily mounting the PIC32 Link $10.00, Rental
Protoboard Permanent mounting of circuit components N/A $2.50
Wooden Box Box that holds all circuitry and stored items Link $13.55
TFT LCD Acts as GUI for lockbox N/A $5.00
Keypad Interface for keypad combination N/A $6.00
Total: $91.51


Tasks Carried Out By Team Members
  • Cameron: Worked on the software for keypad, potentiometer knobs, and piezo. Integrated the various systems in software and helped to debug hardware.
  • Adarsh: Designed and implemented hardware. Worked on software for fingerprint scanner and helped integrate/debug overall system
  • Timon: Wrote keypad code and worked on integration of the individual security components in the box, in addition to helping debug the overall system.