LockBox

Embedded Systems Project

alexander's profile picture

Abstract

In this project, we replicated a functional Lockbox similar similar to the ones used in hotels where you can store your valuables and important belongings. We used a solenoid as the locking mechanism, keypad to lock and unlock the box, an LED as an indicator, and 7-segment display to display the numbers and messages.

The peripherals are interfaced with the microcontroller and controlled by a finite state machine. There are different modes or states that the lockbox will be in depending on the choice of operation which is either lock or unlock.

We have designed the lockbox to operate in a certain way that allows the user to cancel locking the box and also a safety feature that denies passcode entries after a certain number amount of incorrect entries.

This Lockbox design was successfully developed and fully functional.

Introduction

The Lockbox is uses a solenoid and keypad in order to secure valuables and belongings inside the container. The keypad will ask for a passcode that will be used in order to lock and unlock the box. However, if the wrong passcode is entered 5 times then the lockbox will enter "Safe" mode where it will no longer allow any keypad inputs. The passcode will be reset everytime the lockbox is unlocked similar to the ones found in hotels.

Objectives

  1. Understand how to drive the keypad with the multiplexed connection to the MCU.
  2. Develop a finite state machine in order to meet the required specifications for functionality.
  3. Integrate the keypad, LED, solenoid, and 7-segment display driver. Understand the connections to the MCU.
  4. Test and debug the system

Parts List

  • MSP432 (MCU)
  • Solenoid
  • Keypad
  • 7-segment Display
  • Hardware Design

    alexander's profile picture
    Figure 1: Keypad and 7-segment Display Schematic

    Keypad

    The Keypad is divided into 4 rows and 4 columns. Each of these rows and columns are connected as an input to a GPIO pin on the microcontroller. The keypad rows are connected are also connected to the PNP transistors from the 7-segment display. This enables the ability to activate the rows whilst still turning on the 7-segment display and reduces the number of pins used.

    7-Segment Display

    The 7-segment display is divied by 4 digits and 7 LED segments (8 when including the decimal point but not used in this project). The digits are connected to 4 GPIO pin inputs and the LED segments are connected to 7 GPIO pins. There are also pull up resistors connected between the GPIO pin and the LED segments to ensure the current is high enough to provide enough power to light the LED to its full brightness and not surpass the maximum current the output pin can handle.

    The Digits are controlled because all 8 LED anodes connnected to a common anode which is connected a PNP transistor which is essentially a switch that enables the ability to turn on any or all the LEDs. There is a resistor connected to the base and GPIO output which ensures that the current is high enough to allow the transistor to operate in saturation mode to provide the 3.3V to the commonn anode pin.

    Hardware Interface

    Keypad Driver

    To read the keypad and display 4 digits on the display simultaneosly, they need to be time-multiplexed. This means that the MCU has to scan the keypad rows and display the digits at a very fast rate. The scanning can be done in short burst when the digits are turned off. Therefore, the 4 digits has to be turned on about a quarter of the time. This is also known as a refresh rate. Below is the snippet of the code.

    switch(state){
                    /***************************
                                IDLE
                    **************************/
                    case 0:
                        if(key != 0){
                                        col = key;
                                        row = x;
                                        counter = 0;
                                        state = 1;
                    }
                        break;
                    /***************************
                        PRESS DEBOUNCE
                    ***************************/
                    case 1:
                        if(counter > N){
                            //printf("%d", key);
                            state=2;
                        }
                        if(x == row && key != col){
                            counter = 0;
                            state = 0;
                        }
                        if(x == row && key == col){
                            counter++;
                        }
                        break;
                    /***************************
                            PROCESS KEY
                    ***************************/
                    case 2:
                            display[digit] = decode(row, col);
                            digit++;
                            if(digit == 4){
                                digit = 0;
                            }
                            counter = 0;
                            state = 3;
                            break;
    
                    /***************************
                        RELEASE DEBOUNCE
                    ***************************/
                    case 3:
                        if(counter > N){
                            //key = 0;
                            counter = 0;
                            state = 0;
                            //printf("%d", key);
                        }
                        if(x == row && key != 0){
                            counter = 0;
    
                        }
                        if(x == row && key == 0){
                            counter++;
                        }
                        break;
            /****************************
                    FOREVER LOOP
            ****************************/
                x++;
                if(x == 4){
                x = 0;
                }
            }
    }

    There are different states in order to register a keypad input. The first state is the IDLE which waits until a key press is detected. Then it moves on to the next state which is PRESS DEBOUNCE where debounce allows the key press to be regsitered whenever it is presesd once. Since the keypad is electronic it can be susceptible to noise. This will avoid double pressing even though the user only pressed once. One click press can actually mean multiple clicks since the signal is sent instantly and debouncing allows us to filter this out to only register once. The next state is the Process Key which is how it finds out which key has been pressed and loads it into an array that stores the values of the keys pressed. Only a maxiumum of 4 key inputs are allowed which resets the counter of the digit. We also have a debounce counter that waits a certain amount of time for the key press to be registered and released.

    7-Segment Display Driver

    The driver for the 7-segment display is similar to the keypad but instead we are only using the GPIO pins as output. There are 5 pins for the digits and 8 pins for the LED segments. I use a loop that turns on each digit at a certain rate which is the refresh rate. This is created by adding a delay. This will allow the human eye to read was is being displayed.

    
    /****************************
    Enabling xth-row and digit
    *****************************/
        P4->OUT = 0xFF; //BLANK DISPLAY
        P8->OUT = port8[x];
        key = input_key(P9->IN);
    
    //check if openkey(A) or lockkey(C) is pressed
    
    /*****************************
            Setting P4->OUT
    ****************************/
        show(display[x]);
                        

    port8[x] holds all the values for the 5 pins that is needed for each digit. In this project, we are only using 4 since the dots are not needed. show(display[x]) is a subroutine that outputs the specific binary values for a number or symbol to the Port 4 GPIO pins. Display[x] holds the values that are inputted from the keypad depending on what state the lockbox is in.

    Finite State Machine Design

    NORMAL state

    alexander's profile picture

    This is the default state. It is just waiting for the keypad to detect an input. Once 4 keypad inputs are registered and the lock key is pressed. It will move on to the next state which is PRELOCK. It will also reset the counters and flag for the lockkey and number of kepypad inputs.

    PRE-LOCK state

    The PRE-LOCK state is when the lockbox is notifying the user that the box is about to lock. It will toggle the red onboard LED for 5 seconds before activating the solenoid and moving to the lock state. This is also the only state that you can cancel locking the box by pressing any key on the keypad. This will result in going back to the NORMAL state. This allows the user to open the box again within 5 seconds before locking.

    LOCK state

    alexander's profile picture alexander's profile picture

    The LOCK state is where the keypad inputs are compared to the passcode that was set in the NORMAL state. This is also the state that keeps track of the number of attempts to unlock. At 5 failed atttempts, the program will go to LOCKDOWN state. If the keypad inputs match the set passcode it will go to the OPEN state which resets all the flags and counters and goes back to the NORMAL state.

    LOCKDOWN state

    alexander's profile picture

    The LOCKDOWN state turns off the keypad and has a wait loop. This doesn't allow anonymous user keypad inputs and also sets the display as _Ld_ to let the user know that they are in the lockdown state. Once the wait loop is done, it will go back to the LOCK state.

    OPEN state

    alexander's profile picture alexander's profile picture

    The OPEN state is energizing the solenoid for a certain amount of time by setting the pin connected to the solenoid high. In this project, the solenoid is energized for 5 seconds then after all the solenoid is deenergized and all flags and counters are reset. After completing all the tasks, it will go back to the NORMAL state.

    Testing & Techncial Challenges

    Keypad Driver Debugging

    Since each key on the keypad isn't connected to a single pin. It was difficult at first to figure out how to detect the keypad inputs. However, after applying the similar logic to the 7-segment display driver. I figured that I only needed to find out which keys are pressed in a specific column since the columns are activated from the same pins as the 7-segment display digits.

    Debugging FSM

    There are many tasks that are required for each state and making sure that each task are performed at the correct state was tedious but with the help of the debugging tools such as breakpoints. This made it much easier to debug and find out where the bugs were in my program.

    Conclusion

    I was able to successfully design and implement the lockbox program using C language. There was a lot of effort put into creating a lockbox very similar to the ones found in hotels which involved debugging and circuit analysis. Most importantly, through the project I gained knowledge in embedded programming. This was a very fun but educational project that gave me an idea of the many things that are possible within embedded systems. Due to previous coursework and solid foundation, I was able to apply the skills and knowledge with minimal mistakes.