Arduino Controlled Electronic Safe

by Jacco Verhoeckx in Circuits > Arduino

355 Views, 1 Favorites, 0 Comments

Arduino Controlled Electronic Safe

Arduino Powered Electronic Safe
20230519_130636.jpg

Everyone needs a safe place to store important belongings. With this Instructable, you can make your very own electronic safe. I got the idea from watching a video about how someone made a safe-cracking machine using an arduino. While that was a bit outside of my skillset to make, I thought I could at least make a regular safe. It's a lot easier than you might think!

Supplies

Electronics

  • Arduino Uno
  • 16x2 LCD screen with I2C backpack
  • Joystick module
  • SG90 micro servo
  • 6V battery pack (4xAA)
  • Regular jumper wires
  • Male-to-female jumper wires
  • Breadboard(s)


For the construction of the safe itself I used the following, but you can replace any material if you want to:

  • Plywood (any size that can house the electronics will do)
  • Saw
  • Drill
  • Screwdriver
  • Screws
  • Hinges


If you want to solder, some extra parts are required:

  • Soldering iron
  • Solder
  • PCB with breadboard layout (other layouts should work fine as well if you know how they work)

The Circuit

Screenshot 2023-05-19 143738.png

The wiring is pretty simple. The project only needed 5V and GND connections for the modules, so the breadboard used in this image is way too big. Still, it gets the point across. I didn't end up using the pushbutton for the joystick, so I left that out. The most important part here is that the servo is wired to the battery pack, and to keep the GND in mind. Note that he GND has to be wired in this exact sequencce, otherwise the whole setup won't work.

Code

//The following code should work out the box. If the joystick doesn't register,
//try tuning the sensitivity settings below


//Included libraries
#include <Wire.h>
#include <hd44780.h>
#include <hd44780ioClass/hd44780_I2Cexp.h>
#include <Servo.h>


#define VRX_PIN  A0 // Arduino pin connected to Joystick VRX pin
#define VRY_PIN  A1 // Arduino pin connected to Joystick VRY pin


//Sensitivity for the Joystick
#define LEFT_THRESHOLD  400
#define RIGHT_THRESHOLD 800
#define UP_THRESHOLD    400
#define DOWN_THRESHOLD  800


//Joystick command setup
#define COMMAND_NO     0x00
#define COMMAND_LEFT   0x01
#define COMMAND_RIGHT  0x02
#define COMMAND_UP     0x04
#define COMMAND_DOWN   0x08


int xValue = 0; // To store value of the X axis
int yValue = 0; // To store value of the Y axis
int command = COMMAND_NO;


//LCD setup
hd44780_I2Cexp lcd;


const int LCD_COLS = 16;
const int LCD_ROWS = 2;
int currentRow = 1;
int currentCollumn = 0;


//booleans that are true when text is being printed on the LCD
bool upperTextIsPrinting = true;
bool lowerTextIsPrinting = false;


//Servo setup
Servo servo;
int servoPos = 0; //servo position in degrees


//Variables that store the password and user input
String currentPassword = "1234";
String currentInput = "";
int inputCount = 0;


//Enumerators for the 3 different states
enum state{
  CLOSED,
  OPEN,
  SETNEWPASSWORD
};


int currentState = CLOSED;//Always starts closed


void setup()
{
int status;


  Serial.begin(9600) ;


  servo.attach(9);


  servo.write(0);//0 degrees is closed

  status = lcd.begin(LCD_COLS, LCD_ROWS);
  if(status) // non zero status means it was unsuccesful
  {
    hd44780::fatalError(status); // does not return
  }
}


void loop() {
  xValue = analogRead(VRX_PIN);
  yValue = analogRead(VRY_PIN);


  command = COMMAND_NO;


  //Reads the input from the joystick
  if (xValue < LEFT_THRESHOLD)
    command = command | COMMAND_LEFT;
  else if (xValue > RIGHT_THRESHOLD)
    command = command | COMMAND_RIGHT;


  if (yValue < UP_THRESHOLD)
    command = command | COMMAND_UP;
  else if (yValue > DOWN_THRESHOLD)
    command = command | COMMAND_DOWN;


  if(currentState != OPEN) { //OPEN is the only state in which input isn't read this way


    //The following few if statements process the user input to the LCD screen.
    //Every time an input is detected, it checks the direction of
    //the joystick, adds the corresponding number on the bottom screen, and
    //moves the cursor to the left. Then there is a short delay until the
    //next input is read, because otherwise the input would be read incredibly
    //fast, which is not what you want. They also add 1 to the integer 'inputCount',
    //which gets used later when checking for the correct password.


    if (command & COMMAND_LEFT) {
      Serial.println("COMMAND LEFT");


      ProcessInput(4);


      delay(400);
    }


    if (command & COMMAND_RIGHT) {
      Serial.println("COMMAND RIGHT");


      ProcessInput(2);


      delay(400);
    }


    if (command & COMMAND_UP) {
      Serial.println("COMMAND UP");


      ProcessInput(1);


      delay(400);
    }


    if (command & COMMAND_DOWN) {
      Serial.println("COMMAND DOWN");


      ProcessInput(3);


      delay(400);
    }
  }


  //The switch case that handles the three different states. Case 0 is CLOSED,
  //case 1 is OPEN and case 2 is SETNEWPASSWORD
  switch(currentState) {
    case 0:
      if(servoPos =! 0) {
        servoPos = 0;
      }


      if (upperTextIsPrinting) {
        UpperText("Input Password");
        currentCollumn = 0;
        currentRow = 1;
        ClearInput();
      }


      if (currentInput == currentPassword && inputCount == 4) {
        upperTextIsPrinting = true;
        lowerTextIsPrinting = true;


        UpperText("Correct!");
        ClearInput();


        servo.write(180);
        servoPos = 180;


        currentState = OPEN;
      }


      if (inputCount == 4 && currentInput != currentPassword) {
        ClearInput();
        UpperText("Incorrect!");
        LowerText("     ");


        currentCollumn = 0;
        currentRow = 1;
      }
    break;
    case 1:
      if(servoPos =! 180) {
        servoPos = 180;
      }//180 degrees opens the safe by moving the servo away from the lock


      if(lowerTextIsPrinting && lowerTextIsPrinting) {
        UpperText("Correct!");
        LowerText("1=CLOSE 2=NEW");
      }


      if (currentInput  == "1") {
        upperTextIsPrinting = true;


        servo.write(0);
        servoPos = 0;


        currentState = CLOSED;
      }


      if (currentInput == "2") {
        upperTextIsPrinting = true;
        ClearInput();
        lcd.clear();


        currentState = SETNEWPASSWORD;
      }
    break;
    case 2:
      if (upperTextIsPrinting) {
        UpperText("New password?");
        currentCollumn = 0;
        currentRow = 1;
        ClearInput();
      }


      if (inputCount == 4) {
        currentPassword = currentInput;
        ClearInput();
        upperTextIsPrinting = true;
        lowerTextIsPrinting = true;


        currentState = OPEN;
      }
    break;
  }


  lcd.setCursor(currentCollumn, currentRow);
}


//Function that processes the user input, as described on lines 97-103
void ProcessInput(int inputNumber) {
  lcd.print(inputNumber);
  currentInput += inputNumber;
  currentCollumn += 1;
  inputCount += 1;
}


//Function that prints text on the upper row of the LCD
void UpperText(String text) {
  lcd.setCursor(0, 0);
  lcd.clear();
  lcd.print(text);


  upperTextIsPrinting = false;
}


//Function that prints text on the lower row of the LCD
void LowerText(String text) {
  lcd.setCursor(0, 1);
  lcd.print(text);


  lowerTextIsPrinting = false;
}


//Function that clears the password that the user put in
void ClearInput() {
  currentInput = "";
  inputCount = 0;
}


//Code written by Jacco Verhoeckx

Soldering

20230510_171007.jpg
20230510_173101.jpg

I soldered the components roughly the same way as the circuit described above. Not much to it, but as this was my first time soldering it looked a bit sloppy at the end.

Making the Safe

20230510_170809.jpg
20230510_173322.jpg

For the construction of the safe itself I went to the local supply store and bought some plywood. Any material would work, but this was enough for me. I sawed some planks from it, and drilled some holes into them for the screws. I started with screwing both sides and the back together.


Bottom Plank

20230510_174832.jpg

After the first three planks are done and screwed together, measure the space between both sides of the safe and saw accordingly. Then drill some more holes for the screws and screw the bottom plank to the sides.

Top Plank

20230510_180605.jpg

After that, simply measure the top of the safe, saw accordingly and screw the plank to the top.

Make the Door and Finish Up

20230510_195340.jpg

Now measure the space from the top plank to the bottom plank, and from side to side. Saw accordingly. After that, make holes that are the same size as the joystick and LCD screen. I realised too late that the wood I used was a bit too thick, so I put the joystick on the front of the door and drilled a small hole for the jumper wires. Then I attached 2 small hinges to the door to connect to the safe. Finally, I drilled a larger hole in the back for the Arduino USB to go through.

Attach Modules

20230519_131346.jpg
20230519_131358.jpg

The final step. Simply attach the modules to the door and side of the safe. Put a small piece of plastic on the side of the servo, so the servo arm can keep the door closed. I attached everything with double-sided tape, but most modules can be screwed to the wood to more securely hang them up. (Excuse my poor cable management)

And that's it! You should now have a working electronic safe!