Project tutorial
Fingerprint Door Lock Based on FPM10A

Fingerprint Door Lock Based on FPM10A © CC0

Two versions of a door lock system based on the Adafruit FPM10A fingerprint sensor, one is easy for testing and the second more embedded.

  • 11,259 views
  • 4 comments
  • 34 respects

Components and supplies

About this project

Tutorial video

Hello, and welcome to this project, actually it includes two projects but they’re pretty much the same, it’s a door lock system based on an Arduino UNO board, FPM10A optical fingerprint sensor and a LCD i²c screen, but for the other version we include a keypad.

And sure don’t forget about the locking system that you’re willing to control, and following this your wiring and codes may change but don’t worry it would be easy.

That’s the system I’m using, I bought it for 10$ from China as always, but here I’m only using the lock unit not the included keypad unit.

So the system has a DC motor inside, and should be controlled to turn clockwise and anti-clock wise, that’s why in my project I add a L298n H-Bridge module, you can use a little IC H-Bridge it will be nice, but I had to use what I have in my hand for the moment.

You can use a solenoid lock, and control it by a transistor from the Arduino, your wiring will need only one pin to control the transistor and a fewer lines.

Without further ado… know how your system works and adapt it.

Before you continue make sure you know how to use all the elements mentionned above, as it will make your project easy to adapt and spot any problem:

Version 1:

The first version uses: LCD + fingerprint sensor + l298n (to control the system) + push button with a resistor (I used 1k).

For the first version, you need to upload the “Enroll” code first from the fingerprint library (down bellow), and use it to add a fingerprint, upload it and open the serial monitor then type the ID and press “Enter” then follow the steps as in the fingerprint tutorial. Then upload the second code and add the names you want for each user, upload the code and here we go, the fingerprint templates are stored in the modules internal flash drive.

Once the code begin working, the Arduino is constantly waiting for a finger to place on the sensor, otherwise if you’re inside just press the button to open, if the finger is valid (is in the database) it will opens the lock and shows a message and the name related to the fingerprint ID, if the ID isn’t paired with a name it will show some strange things :D…

Wiring

That’s pretty much my wiring, so you won’t be confused by the push button, actually instead of getting the high level from the Arduino 5v pin which requires me to add other wires (and it will be more messy) I just put the pin 8 on High and I read the button state from pin 9 which has a pull-down resistor.

Version 2:

As you can see in the 1st version you have to use a computer (or whatever you use to program you Arduino) in order to add new templates to the module flash drive, that’s why I made this more embedded version that requires only power source to work, and the new templates are now added via a keypad (which meant to stay on the inside as this project is based on access by fingerprint only, you can combine it with my other project based on keypad only, you’ll have to do some modification but they’re easy).

The keypad is placed inside which means you can open the lock by pressing a button here I’ve chosed ‘B’ as ‘A’ is for adding a new person.

To add new finger template press ‘A’ it will ask you for password that’s already in the code ‘1’ ‘2’ ‘3’ ‘4’, you can modify it there, you enter the code then you enter the ID number as a 3 digits format, examples “001”, “021” or “115” you can enter IDs from 1 to 127, after tapping the ID it will ask you to place the finger, remove it and place it again…Job done.

And as the first version it waits for a valid fingerprint to open the lock.

Wiring:

This is the wiring for the second version, I removed the push button as the opening from inside is done now by ‘B’ button.

Libraries:

Codes:

  • The first code in the version 1 is the “Enroll” code from the fingerprint library

The code I made for the first version is based on “Fingerprint” example from the library just instead of showing the ID on the Serial monitor (which means that the finger print template is in the database) it triggers the whole opening sequence otherwise (which means that the module failed to find match in the database) it shows a simple message on the screen.

The code for the second version is based on both “Fingerprint” and “Enroll” examples, and just like the first version but this time I added the “Enrolling” feature and you can add the ID from the keypad instead of the Serial monitor.

Possible improvements:

Codes are made the simple way as I’m a beginner, so they should be clear for anyone willing to improve it like entering the password it could be more secure as the user should enter a more than 4 digits or less, and the validation can be done with a button then it’s compared to the code programmed … Also you can add the deleting a template sequence, just like adding, press a button -> password -> and type the ID.

Also you can add a buzzer to ring or as an Alarm, or a PIR sensor to turn on the the system whenever a person is near the door…

Hope you like it and if there’s any problem you can contact me, don’t forget to consider a subscribe to the channel.

Code

FP_lock_v1.inoArduino
/* This code works with FPM10A optical fingerprint sensor + LCD i2c screen + L298n and a push button
 * It's main function is to scan a fingerprint then trigger the opening lock sequence if the finger is recognized
 * It's based on the "fingerprint" example from the Adafruit_fingerprint library
 * Refer to www.SurtrTech.com for more details
 * The L298n H-bridge module is required for the door lock type used you could need something else
 */
 
#include <Adafruit_Fingerprint.h>    //Libraries needed
#include <SoftwareSerial.h>
#include <LCD.h>
#include <LiquidCrystal_I2C.h>

#define I2C_ADDR 0x27          //LCD i2c stuff
#define BACKLIGHT_PIN 3
#define En_pin 2
#define Rw_pin 1
#define Rs_pin 0
#define D4_pin 4
#define D5_pin 5
#define D6_pin 6
#define D7_pin 7

int in1 = 5; // In1 and In2 for the L298n H bridge module
int in2 = 4;

int But1=8;  // In order to add a push button I got the 5v from the pin 8 instead of "5v" arduino pin
int But2=9;

String Names[] = { "Yassine", "Surtr", "Tech",}; //Those are the names affected to the fingertemplates IDs
                                                 //The first on which is Names[0] : Yassine has the ID 1 in the fingerprint sensor

SoftwareSerial mySerial(2, 3);                  //Fingerprint sensor wiring RX 3, TX 2           
LiquidCrystal_I2C lcd(I2C_ADDR,En_pin,Rw_pin,Rs_pin,D4_pin,D5_pin,D6_pin,D7_pin); //LCD declaring

Adafruit_Fingerprint finger = Adafruit_Fingerprint(&mySerial);                    //Fingerprint sensor declaring

void setup()  
{
  pinMode(in1, OUTPUT); 
  pinMode(in2, OUTPUT);
  
  pinMode(But1, OUTPUT);    //Push button stuff, I made the pin 8 permanent HIGH level
  digitalWrite(But1,HIGH);
  pinMode(But2,INPUT);     //And I read the button state on pin 9
  
  Serial.begin(9600);               //Serial begin incase you need to see something on the serial monitor
  finger.begin(57600);              //Sensor baude rate
  lcd.begin (16,2);
  lcd.setBacklightPin(BACKLIGHT_PIN,POSITIVE);
  lcd.setBacklight(HIGH);
  lcd.home ();
  finger.getTemplateCount();        //Counts the number of templates stored in the sensor flash memory
  delay(2000);
  lcd.setCursor(0,0);
  lcd.print("Place finger");
  CloseDoor();                     //As we don't know the state of the lock system, first we make sure it's closed
}

void loop()                     
{
  getFingerprintIDez();            //This function keeps looping and waiting for a fingerprint to be put on the sensor
  delay(50);
  bool Button1=digitalRead(But2);  //Reading the state of the pushbutton
  if(Button1==HIGH){               //If the button is pressed it opens the doorlock as the button is meant to be inside
  OpenDoor();                      //And once more it depends on your system, mine requires an electrical signal to open
  delay(5000);                     //Opening delay 5s
  CloseDoor();                     //Closing sequence requires electrical signal otherwise it stays open
  }

}


//Main function taken from the "fingerprint" example and modified
//Only the modifications are commented
int getFingerprintIDez() {
  uint8_t p = finger.getImage();        //Image scanning
  if (p != FINGERPRINT_OK)  return -1;  

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

  p = finger.fingerFastSearch();     //Looking for matches in the internal memory
  if (p != FINGERPRINT_OK){          //if the searching fails it means that the template isn't registered
    lcd.clear();                     //And here we write a message or take an action for the denied template
    lcd.print("Access denied");
    delay(2000);
    lcd.clear();
    lcd.print("Place finger");
    return -1;
  }
            //If we found a match we proceed in the function
  
  lcd.clear();
  lcd.print("Welcome");                  //Printing a message for the recognized template
  lcd.setCursor(2,1);
  lcd.print(Names[finger.fingerID-1]); //Then print the name we gave it and the -1 is to remove the shift as the ID starts from "1" but the array from "0"
  OpenDoor();                          //Opening and closing sequence
  delay(5000);
  CloseDoor();
  lcd.clear();
  lcd.print("Place finger");
  return finger.fingerID; 
  
}
/*The two following functions depends on your locking system
 *mine has a DC motor that should turn in both ways for opening and closing
 *that's why I'm using H bridge, you could have a solenoid with a transistor
 *then you'll need only opening sequence but controlling the transistor
 *as the closing is spring loaded...
 */


void OpenDoor(){
  digitalWrite(in1, LOW);  //Turn in a direction for 100ms and stops
  digitalWrite(in2, HIGH); //it's not the delay for the whole sequence
  delay(100);              // the sequence delay is above (5000) 5s
  digitalWrite(in1, LOW);  //If I stop the motor, the lock holds its place either open or closed
  digitalWrite(in2, LOW);
}

void CloseDoor(){
  digitalWrite(in1, HIGH);  //Turn in other direction for 100ms and stops
  digitalWrite(in2, LOW);
  delay(100);
  digitalWrite(in1, LOW);
  digitalWrite(in2, LOW);
}
FP_lock_v2.inoArduino
/* This code works with FPM10A optical fingerprint sensor + LCD i2c screen + L298n and a 4*4 Keypad matrix
 * It's main function is to scan a fingerprint then trigger the opening lock sequence if the finger is recognized
 * And add new finger templates if the user is willing to by intriducing a password
 * It's based on the "fingerprint" and "Enroll" examples from the Adafruit_fingerprint library
 * Refer to www.SurtrTech.com for more details
 * The L298n H-bridge module is required for the door lock type used you could need something else
 */

#include <Adafruit_Fingerprint.h> //Libraries needed
#include <SoftwareSerial.h>
#include <Keypad.h>
#include <LiquidCrystal_I2C.h>

#define I2C_ADDR 0x27 //defining the LCD pins
#define BACKLIGHT_PIN 3
#define En_pin 2
#define Rw_pin 1
#define Rs_pin 0
#define D4_pin 4
#define D5_pin 5
#define D6_pin 6
#define D7_pin 7

LiquidCrystal_I2C lcd(I2C_ADDR,En_pin,Rw_pin,Rs_pin,D4_pin,D5_pin,D6_pin,D7_pin); 

SoftwareSerial mySerial(2, 3);   //Fingerprint sensor wiring RX 3, TX 2 

const byte numRows= 4;          //number of rows on the keypad
const byte numCols= 4;          //number of columns on the keypad

char keypressed;

char code[]={'1','2','3','4'}; //Passcode needed you can change it just keep the format "4 digits as char array"
char c[4];                     //Array to get the code from the user
int ij;

int in1 = 5; // In1 and In2 for the L298n H bridge module
int in2 = 4;

//keymap defines the key pressed according to the row and columns just as appears on the keypad
char keymap[numRows][numCols]= 
{
{'1', '2', '3', 'A'}, 
{'4', '5', '6', 'B'}, 
{'7', '8', '9', 'C'},
{'*', '0', '#', 'D'}
};


byte rowPins[numRows] = {13,12,11,10}; //Rows 0 to 3 //if you modify your pins you should modify this too
byte colPins[numCols]= {9,8,7,6}; //Columns 0 to 3

//initializes an instance of the Keypad class
Keypad myKeypad= Keypad(makeKeymap(keymap), rowPins, colPins, numRows, numCols);


Adafruit_Fingerprint finger = Adafruit_Fingerprint(&mySerial);

uint8_t id;

void setup()  
{
  Serial.begin(9600);
  pinMode(in1, OUTPUT); //L298n H bridge pinmodes
  pinMode(in2, OUTPUT);
  finger.begin(57600); 
  lcd.begin (16,2);
  lcd.setBacklightPin(BACKLIGHT_PIN,POSITIVE);
  lcd.setBacklight(HIGH);
  lcd.home ();
  lcd.clear();
  lcd.print("Standby");
  delay(2000);
}



void loop() 
{ 
  getFingerprintIDez();                //Waiting for a fingerprint to scan if it's valid or not
  keypressed = myKeypad.getKey();      //Reading the buttons typed by the keypad
  if(keypressed == 'A'){               //If it's 'A' it triggers "Adding new template" sequence

            ij=0;                      //ij is set to 0
            lcd.clear();
            lcd.setCursor(0,0);
            lcd.print("Enter Password");
            getPassword();            //Getting the passcode function
            if(ij==4){                //If the passcode is correct we can start enrolling new finger template
            Enrolling();              //Enrolling function
            delay(2000);
            lcd.clear();
            }
            else{                    //If the code is wrong we can't add new users (templates)
            lcd.setCursor(0,0);
            lcd.print("Wrong code");
            delay(2000);
            lcd.clear();
            }
    
  
  }
 if(keypressed == 'B')        //As the keypad is meant to stay inside the 'B' button opens the door lock
 {                            //Because the system I used needs an electrical signal to open
  OpenDoor();
  delay(5000);                //Opening delay
  CloseDoor();
 }
  
  lcd.setCursor(0,0);
  lcd.print("Place finger"); //Constant showing message
  delay(50);
}

//Getting password (code) function, it gets the characters typed
//and store them in c[4] array
void getPassword(){
   for (int i=0 ; i<4 ; i++){
    c[i]= myKeypad.waitForKey();
    lcd.setCursor(i,1);
    lcd.print("*");
   }
   lcd.clear();
   for (int j=0 ; j<4 ; j++){ //comparing the code entred with the code stored
    if(c[j]==code[j])
     ij++;                    //Everytime the char is correct we increment the ij until it reaches 4 which means the code is correct
   }                          //Otherwise it won't reach 4 and it will show "wrong code" as written above
}

//The Enrolling and getFingerprintEnroll functions are mainly based on the "Enroll" example code from the library
//Only the modifications will be commented, return to the example to see each step in details, as here it's shortened

void Enrolling()  {
  keypressed = NULL;
  lcd.clear();
  lcd.print("Enroll New");
  delay(2000);
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("Enter new ID");
  id = readnumber();                           //This function gets the Id it was meant to get it from the Serial monitor but we modified it
  if (id == 0) {// ID #0 not allowed, try again!
     return;
  }
  
  while (!  getFingerprintEnroll() );
  }

//Enrolling function only the modifications are commented
uint8_t getFingerprintEnroll() {

  int p = -1;
  lcd.clear();
  lcd.print("Enroll ID:"); //Message to print for every step
  lcd.setCursor(10,0);
  lcd.print(id);
  lcd.setCursor(0,1);
  lcd.print("Place finger"); //First step
  while (p != FINGERPRINT_OK) {
    p = finger.getImage();
  }

  // OK success!

  p = finger.image2Tz(1);
  switch (p) {
    case FINGERPRINT_OK:
      break;
    case FINGERPRINT_IMAGEMESS:
      return p;
    case FINGERPRINT_PACKETRECIEVEERR:
      return p;
    case FINGERPRINT_FEATUREFAIL:
      return p;
    case FINGERPRINT_INVALIDIMAGE:
      return p;
    default:
      return p;
  }
  
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("Remove finger"); //After getting the first template successfully
  lcd.setCursor(0,1);
  lcd.print("please !");
  delay(2000);
  p = 0;
  while (p != FINGERPRINT_NOFINGER) {
    p = finger.getImage();
  }
  
  p = -1;

  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("Place same"); //We launch the same thing another time to get a second template of the same finger
  lcd.setCursor(0,1);
  lcd.print("finger please");
  while (p != FINGERPRINT_OK) {
    p = finger.getImage();
  }

  // OK success!

  p = finger.image2Tz(2);
  switch (p) {
    case FINGERPRINT_OK:
      break;
    case FINGERPRINT_IMAGEMESS:
      return p;
    case FINGERPRINT_PACKETRECIEVEERR:
      return p;
    case FINGERPRINT_FEATUREFAIL:
      return p;
    case FINGERPRINT_INVALIDIMAGE:
      return p;
    default:
      return p;
  }
  
  
  p = finger.createModel();
  if (p == FINGERPRINT_OK) {
  } else if (p == FINGERPRINT_PACKETRECIEVEERR) {
    return p;
  } else if (p == FINGERPRINT_ENROLLMISMATCH) {
    return p;
  } else {
    return p;
  }   
  
  p = finger.storeModel(id);
  if (p == FINGERPRINT_OK) {
  lcd.clear();                //if both images are gotten without problem we store the template as the Id we entred
  lcd.setCursor(0,0);
  lcd.print("Stored in");    //Print a message after storing and showing the ID where it's stored
  lcd.setCursor(0,1);
  lcd.print("ID: ");
  lcd.setCursor(5,1);
  lcd.print(id);
  delay(3000);
  lcd.clear();
  } else if (p == FINGERPRINT_PACKETRECIEVEERR) {
    return p;
  } else if (p == FINGERPRINT_BADLOCATION) {
    return p;
  } else if (p == FINGERPRINT_FLASHERR) {
    return p;
  } else {
    return p;
  }   
}

//This function gets the ID number as 3 digits format like 001 for ID 1
//And return the number to the enrolling function
uint8_t readnumber(void) {
  uint8_t num = 0;
   while (num == 0) {
      char keey = myKeypad.waitForKey();
    int  num1 = keey-48;
         lcd.setCursor(0,1);
         lcd.print(num1);
         keey = myKeypad.waitForKey();
    int  num2 = keey-48;
         lcd.setCursor(1,1);
         lcd.print(num2);
         keey = myKeypad.waitForKey();
    int  num3 = keey-48;
         lcd.setCursor(2,1);
         lcd.print(num3);
         delay(1000);
         num=(num1*100)+(num2*10)+num3;
         keey=NO_KEY;
  }
  return num;
}

//Main function taken from the "fingerprint" example and modified
//Only the modifications are commented
//This function waits for a fingerprint, scan it and give it access if recognised

int getFingerprintIDez() {
  uint8_t p = finger.getImage();        //Image scanning
  if (p != FINGERPRINT_OK)  return -1;  

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

  p = finger.fingerFastSearch();     //Looking for matches in the internal memory
  if (p != FINGERPRINT_OK){          //if the searching fails it means that the template isn't registered
    lcd.clear();                     //And here we write a message or take an action for the denied template
    lcd.print("Access denied");
    delay(2000);
    lcd.clear();
    lcd.print("Place finger");
    return -1;
  }
  //If we found a match we proceed in the function
  
  lcd.clear();
  lcd.print("Welcome");        //Printing a message for the recognized template
  lcd.setCursor(2,1);
  lcd.print("ID: ");
  lcd.setCursor(5,1);
  lcd.print(finger.fingerID); //And the ID of the finger template
  OpenDoor();
  delay(5000);
  CloseDoor();
  lcd.clear();
  lcd.print("Place finger");
  return finger.fingerID; 
  
}

/*The two following functions depends on your locking system
 *mine has a DC motor that should turn in both ways for opening and closing
 *that's why I'm using H bridge, you could have a solenoid with a transistor
 *then you'll need only opening sequence but controlling the transistor
 *as the closing is spring loaded...
 */


void OpenDoor(){
  digitalWrite(in1, LOW);  //Turn in a direction for 100ms and stops
  digitalWrite(in2, HIGH); //it's not the delay for the whole sequence
  delay(100);              // the sequence delay is above (5000) 5s
  digitalWrite(in1, LOW);  //If I stop the motor, the lock holds its place either open or closed
  digitalWrite(in2, LOW);
}

void CloseDoor(){
  digitalWrite(in1, HIGH);  //Turn in other direction for 100ms and stops
  digitalWrite(in2, LOW);
  delay(100);
  digitalWrite(in1, LOW);
  digitalWrite(in2, LOW);
}

Schematics

Wiring 1
Wiring 1 zradxzv4bg
Wiring 2
2 r4plhpufgn

Comments

Similar projects you might like

Password Based Door Lock

Project tutorial by Rishabh

  • 16,435 views
  • 6 comments
  • 30 respects

Arduino Keyless Door Lock System with Keypad and LCD

Project tutorial by DIY Hacking

  • 32,441 views
  • 19 comments
  • 59 respects

Interfacing FPM10A (50-DY) Optical Fingerprint Sensor

Project tutorial by SurtrTech

  • 6,039 views
  • 4 comments
  • 20 respects

Arduino and Android Based Password Protected Door Lock

Project tutorial by Md. Khairul Alam

  • 15,837 views
  • 6 comments
  • 54 respects

Smart BT Door Lock (Simple Arduino)

Project showcase by Arun

  • 12,505 views
  • 1 comment
  • 23 respects
Add projectSign up / Login