Overview

The Biometric Security Box uses the Adafruit Fingerprint Sensor as well as a numeric pass-code and a mechanical key-lock to provide triple-security.  This tutorial is based on a 4x6 card file box, but can be easily adapted to larger lock-boxes – or even a full-size door!

Parts and Preparation

Materials:

Remove lining from Lid

Carefully peel the fabric lining from the inside of the box lid.  You can discard the lining.

Lay out components

Arrange the major components in the lid and mark their positions.  Be sure to leave room for wiring and spacers to support the false lid.

Measure and mark cutouts

Mark the cutouts for the fingerprint sensor, power switch and keypad cable on the top of the lid.  Also mark the position for the power jack on the back of the box.

Cut the cable slot

Use an X-Acto or utility knife to cut a rectangular slot for the keypad cable.

Drill the holes

Drill holes for fingerprint sensor, power switch and power jack.

Cut a false lid

We will use a false lid to hide the circuitry inside the lid of the box.  Cut a piece of 1/8" (3mm) plywood or hardboard to fit the inside of the lid.  Also cut some 0.85" (22mm) spacer blocks to go under the false lid.

Circuitry

The Microcontroller

The box in the photographs uses a Menta without the mint tin (i.e. a demented Menta).  However, the code and circuitry will also work with an UNO,  Boarduino or any other Arduino compatible microcontroller.  If you are using the Menta or Boarduino, first build it according to the appropriate tutorial.

The Circuit

Connect the components as shown in the diagram below.  

If you are using a Menta, the pin locations are the same as for the UNO in the diagram, you can mount the MOSFET and Diode and a header for the keypad connector in the prototyping area.

If you are using a Boarduino, be aware that the pin locations will be different from the diagram.

Pre-Assembly

Install the keypad and switch

If the adhesive on the keypad does not stick well to the textured box surface, you can fix the corners down with small screws or nylon snap-rivets.

Install Circuitry

Position components inside the lid and glue spacer blocks around them. 
  • Use foam tape to hold the fingerprint sensor in place.
  • Place extra spacer blocks in the center under the solenoid location.
  • Use tape and/or cable ties to hold wires in place.

Fit the false lid

Make cutouts for the power cable, FTDI header and clearance for the switch.

Note:  A smaller switch would fit better in a box this size, but these metal lighted switches look SO awesome we couldn't resist!

Cover the false lid

Apply adhesive felt to the false lid.  Cut flaps around the FTDI header access and the switch and leave a cutout for the solenoid footprint.

Install the false lid and solenoid


Postion the solenoid with the tip of the shaft just even with the inner edge of the box lid.

Use wood screws to fasten the solenoid.  Make sure they are long enough to go through the false lid and fasten securely to the space blocks underneath.

Program and Test

Download Fingerprint and Keypad Libraries

Enroll Fingers

Load code

  • Load the Biometric Box sketch at the bottom of this page.
  • Edit the "secretCode" string to define your passcode.
  • Compile and upload the sketch.

Test the Latch Operation

  • Power on the box - the led on the power switch should flash a few times, then start to 'breathe'.
  • Enter your passcode - the fingerprint sensor should turn on and glow red.
  • Place your finger on the sensor and you should hear the solenoid click.

Download: file
/*************************************************** 
  Biometric Box Sketch for the optical Fingerprint sensor
  This sketch implements a two-level security scheme requiring the
  user to enter a passcode via the keypad before scanning a fingerprint
  for access.

  Adafruit invests time and resources providing this open source code, 
  please support Adafruit and open-source hardware by purchasing 
  products from Adafruit!

  Written by Bill Earl for Adafruit Industries.  
  BSD license, all text above must be included in any redistribution
 ****************************************************/
#include <Keypad.h>
#include <Adafruit_Fingerprint.h>
#include <SoftwareSerial.h>

// Define the states for the lock state machine
#define LOCKED 2
#define PASSWORD_OK 1
#define UNLOCKED 0

// State Variables:   Initialize to the locked state
int LockState = LOCKED;
long StartTime = 0;
int position = 0;

// Define your password key sequence here
char* secretCode = "1423";

// Keypad key matrix:
const byte rows = 4; 
const byte cols = 3; 
char keys[rows][cols] = 
{
   {'1','2','3'},
   {'4','5','6'},
   {'7','8','9'},
   {'*','0','#'}
};

// Keypad pin definitions
byte rowPins[rows] = {2, 3, 4, 5}; 
byte colPins[cols] = {6, 7, 8};  

// Instantiate the keypad
Keypad keypad = Keypad(makeKeymap(keys), rowPins, colPins, rows, cols);

// More pin definitions:
int LedPin = 10;
int SolenoidPin = 11;

// Define a Fingerprint sensor on pins 12 & 13
int getFingerprintIDez();
SoftwareSerial mySerial(13, 12);
Adafruit_Fingerprint finger = Adafruit_Fingerprint(&mySerial);


void setup()                    
{
   pinMode(LedPin, OUTPUT);
   pinMode(SolenoidPin, OUTPUT);
   
   // Flash hello
   for (int i = 0; i < 3; i++)
   {
     digitalWrite(LedPin, HIGH);
     delay(100);
     digitalWrite(LedPin, LOW);
     delay(100);
   }
   
   // Initialize state and communicatins
   setLockState(LOCKED); 
   Serial.begin(9600); 
   finger.begin(57600);

   // Connect to the sensor
   if (finger.verifyPassword()) 
   {
      Serial.println("Found fingerprint sensor!");
   } 
   else 
   {
      Serial.println("Did not find fingerprint sensor :(");
      while (1);
   }
}


void loop()                    
{
   // Run the state machine:
   
   // Locked State - Monitor keypad for valid Password code entry
   if (LockState == LOCKED)
   {
      char key = keypad.getKey();

      if (key == '*' || key == '#')
      {
         position = 0;
         setLockState(LOCKED);
      }
      if (key != 0)
      {
         if (key == secretCode[position])  // Valid key in Password sequence
         {
            Serial.print("Matched ");   
            Serial.print(key);   
            Serial.print("-at-");   
            Serial.println(position);   
            position ++;
         }
         else  // Invalid key - start all over again
         {
            Serial.println("Invalid Code!");   
            position = 0;
         }
      }

      // Let the LED 'breathe' while we wait
      analogWrite(LedPin, sin((millis() % 3142) / 1000.0) * 255);

      if (position == 4)  // Password successfully entered - advance state
      {
         setLockState(PASSWORD_OK);
         position = 0;
      }
      delay(100);
   }

   // PASSWORD_OK state - Now wait for a valid fingerprint reading
   else if (LockState == PASSWORD_OK)
   { 
      if (getFingerprintIDez() != -1)
      {
         setLockState(UNLOCKED); // Valid fingerprint - advance state to UNLOCKED
      }
      if (millis () - StartTime > 5000) 
      {
         setLockState (LOCKED); // Time-out - go back to the LOCKED state
      }
   }

   // UNLOCKED state - hold the solenoid open for a limited time
   else if (LockState == UNLOCKED)
   { 
      for (int i = 0; i < 30; i++)
      {
         // Flash the led to indicate the lock is open
         digitalWrite(LedPin, LOW);
         delay(50);
         digitalWrite(LedPin, HIGH);
         delay(50);
      }
      setLockState (LOCKED);  // Time-out - go back to the locked state.
   }
}



// returns -1 if failed, otherwise returns ID #
int getFingerprintIDez() 
{
   uint8_t p = finger.getImage();
   if (p != FINGERPRINT_OK)  return -1;

   p = finger.image2Tz();
   if (p != FINGERPRINT_OK)  return -1;

   p = finger.fingerFastSearch();
   if (p != FINGERPRINT_OK)  return -1;

   // found a match!
   Serial.print("Found ID #"); Serial.print(finger.fingerID); 
   Serial.print(" with confidence of "); Serial.println(finger.confidence);
   return finger.fingerID; 
}


// Set the state and the time of the state change
void setLockState(int state)
{
   LockState = state;
   StartTime = millis ();
   if (state == LOCKED)
   {
      Serial.println("Locked!");
      digitalWrite(LedPin, HIGH);
      digitalWrite(SolenoidPin, LOW);  
   }

   else if (state == PASSWORD_OK)
   {
      Serial.println("PASSWORD_OK!");
      digitalWrite(LedPin, LOW);  
   }    
   else if (state == UNLOCKED)
   {
      Serial.println("Unlocked!");
      digitalWrite(LedPin, LOW);
      digitalWrite(SolenoidPin, HIGH);      
   }
}

Final Assembly

Make the strike.

Cut a strip of brass about 2.5" (64mm) long.
  • Measure the distance from the top of the solenoid shaft to the edge of the box lid - typically about 0.44" (11mm).
  • Drill a .31" (8mm) hole in one end for the solenoid shaft.  The edge of the hole should be 11mm from the end of the strip.
  • Drill 2 more 1/8" (3mm) holes for rivets.
  • Bend the strike above the hole as shown below.

Temporarily install the strike

  • Position the strike on the front of the box and align the top with the edge of the box as shown.
  • Fasten it temporarily with machine screws.  Make sure you can unfasten it from outside the box.  We will need to open the box for adjustments if the latch binds.

Test latch operation

If the latch binds or fails to engage the strike, shim the solenoid and/or adjust the position of the strike as needed.

Rivet the strike

Once you have verified that everything is positioned for proper latch operation, make it permanent and tamper-proof by replacing the screws with pop-rivets.

Use It!

Turn it on

  • Press the power button until it clicks in the on position.
  • The led in the power button will blink three times, then start to 'breathe'.

Enter the passcode

  • Type in the passcode you programmed on the keypad. 
  • If you enter it successfully, the fingerprint sensor will light up.

Scan your fingerprint

  • Place your finger on the glass window of the sensor.  
  • If the sensor recognizes a finger that you enrolled, you will hear the solenoid click and the led will start flashing rapidly.  
  • You will have 3 seconds to open the box.
This guide was first published on Dec 29, 2012. It was last updated on Dec 29, 2012.