Last year I’ve made two door lock projects. One was the keypad project and the second one was an RFID door lock project each with a 3D printed case and a servo to open the door. Today I have a new one and probably the last door lock project on this channel.
by: ELECTRONOOBS on 2026-09-03
Check the keypad project as well! This is a fingerprint door lock with a black box integrated. So, why is this better than the other two projects? Well, first you don’t need to carry any key or card with you since you always have your fingerprint. So that’s more convenient. It is also faster to use than typing the code of the keypad door lock. Just place the finger and open the door. Also, it is almost impossible to trick this door lock since a fingerprint is difficult to copy so with a metal case instead of plastic, this would be a very secure door lock. It also has a black-box with SD card and real time clock so we could see the log line by line with everything that happened with the door.

First we need to see how to use the fingerprint sensor by itself. Then we will create the rest of the project. When you receive the fingerprint module, it has no fingerprints stored to its memory so first we have to add our data. Connect it like below (left) to and Arduino UNO, or like (right) to and Arduino MEGA. Not all pins are good for this since not all pins could create interrupt for the RX pin so follow the schematic below. For this example, we will use the serial monitor to save our fingerprint to the sensor database. Upload the example code below called, fingerprint scan example.
#include <Adafruit_Fingerprint.h>
//For Arduino UNO use pin #D2 from sensor (GREEN wire)
// pin #D3 is OUT from arduino (WHITE wire)
//For Arduino MEGA use pin #D10 from sensor (GREEN wire)
// pin #D11 is OUT from arduino (WHITE wire)
#include <SoftwareSerial.h>
SoftwareSerial mySerial(10, 11);
Adafruit_Fingerprint finger = Adafruit_Fingerprint(&mySerial);
uint8_t id;
void setup()
{
Serial.begin(9600);
while (!Serial); // For Yun/Leo/Micro/Zero/...
delay(100);
Serial.println("\n\nFingerprint sensor enrollment");
// set the data rate for the sensor serial port
finger.begin(57600);
if (finger.verifyPassword()) {
Serial.println("Found fingerprint sensor!");
} else {
Serial.println("Did not find fingerprint sensor :(");
while (1) { delay(1); }
}
}
uint8_t readnumber(void) {
uint8_t num = 0;
while (num == 0) {
while (! Serial.available());
num = Serial.parseInt();
}
return num;
}
void loop() // run over and over again
{
Serial.println("Ready to enroll a fingerprint!");
Serial.println("Please type in the ID # (from 1 to 127) you want to save this finger as...");
id = readnumber();
if (id == 0) {// ID #0 not allowed, try again!
return;
}
Serial.print("Enrolling ID #");
Serial.println(id);
while (! getFingerprintEnroll() );
}
uint8_t getFingerprintEnroll() {
int p = -1;
Serial.print("Waiting for valid finger to enroll as #"); Serial.println(id);
while (p != FINGERPRINT_OK) {
p = finger.getImage();
switch (p) {
case FINGERPRINT_OK:
Serial.println("Image taken");
break;
case FINGERPRINT_NOFINGER:
Serial.println(".");
break;
case FINGERPRINT_PACKETRECIEVEERR:
Serial.println("Communication error");
break;
case FINGERPRINT_IMAGEFAIL:
Serial.println("Imaging error");
break;
default:
Serial.println("Unknown error");
break;
}
}
// OK success!
p = finger.image2Tz(1);
switch (p) {
case FINGERPRINT_OK:
Serial.println("Image converted");
break;
case FINGERPRINT_IMAGEMESS:
Serial.println("Image too messy");
return p;
case FINGERPRINT_PACKETRECIEVEERR:
Serial.println("Communication error");
return p;
case FINGERPRINT_FEATUREFAIL:
Serial.println("Could not find fingerprint features");
return p;
case FINGERPRINT_INVALIDIMAGE:
Serial.println("Could not find fingerprint features");
return p;
default:
Serial.println("Unknown error");
return p;
}
Serial.println("Remove finger");
delay(2000);
p = 0;
while (p != FINGERPRINT_NOFINGER) {
p = finger.getImage();
}
Serial.print("ID "); Serial.println(id);
p = -1;
Serial.println("Place same finger again");
while (p != FINGERPRINT_OK) {
p = finger.getImage();
switch (p) {
case FINGERPRINT_OK:
Serial.println("Image taken");
break;
case FINGERPRINT_NOFINGER:
Serial.print(".");
break;
case FINGERPRINT_PACKETRECIEVEERR:
Serial.println("Communication error");
break;
case FINGERPRINT_IMAGEFAIL:
Serial.println("Imaging error");
break;
default:
Serial.println("Unknown error");
break;
}
}
// OK success!
p = finger.image2Tz(2);
switch (p) {
case FINGERPRINT_OK:
Serial.println("Image converted");
break;
case FINGERPRINT_IMAGEMESS:
Serial.println("Image too messy");
return p;
case FINGERPRINT_PACKETRECIEVEERR:
Serial.println("Communication error");
return p;
case FINGERPRINT_FEATUREFAIL:
Serial.println("Could not find fingerprint features");
return p;
case FINGERPRINT_INVALIDIMAGE:
Serial.println("Could not find fingerprint features");
return p;
default:
Serial.println("Unknown error");
return p;
}
// OK converted!
Serial.print("Creating model for #"); Serial.println(id);
p = finger.createModel();
if (p == FINGERPRINT_OK) {
Serial.println("Prints matched!");
} else if (p == FINGERPRINT_PACKETRECIEVEERR) {
Serial.println("Communication error");
return p;
} else if (p == FINGERPRINT_ENROLLMISMATCH) {
Serial.println("Fingerprints did not match");
return p;
} else {
Serial.println("Unknown error");
return p;
}
Serial.print("ID "); Serial.println(id);
p = finger.storeModel(id);
if (p == FINGERPRINT_OK) {
Serial.println("Stored!");
} else if (p == FINGERPRINT_PACKETRECIEVEERR) {
Serial.println("Communication error");
return p;
} else if (p == FINGERPRINT_BADLOCATION) {
Serial.println("Could not store in that location");
return p;
} else if (p == FINGERPRINT_FLASHERR) {
Serial.println("Error writing to flash");
return p;
} else {
Serial.println("Unknown error");
return p;
}
}

Make sure you install the adafruit fingerprint library that you could also find below. Upload this example code to the Arduino and open serial monitor and select the 9600 baud rate. Now sent the ID number where you want to store the new fingerprint. I send 1 since I want to save my first print to the ID 1 which will be the main user. Type 1 and press enter and follow the instructions. Scan the finger once, remove it and scan it once again and the new data is stored. Now my finger is on the database.

Now, you have another small example code that will detect the scanned fingerprint. With the same schematic before, upload the scan fingerprint example code you can find below. Open the serial monitor and place your finger on to the sensor. There you have it. ID1 was detected, which is the ID for the finger scaned before. With these two codes you now know how to store and read data from the sensor. Read the comments in the code for more.
#include <Adafruit_Fingerprint.h>
//For Arduino UNO use pin #D2 from sensor (GREEN wire)
// pin #D3 is OUT from arduino (WHITE wire)
//For Arduino MEGA use pin #D10 from sensor (GREEN wire)
// pin #D11 is OUT from arduino (WHITE wire)
#include <SoftwareSerial.h>
SoftwareSerial mySerial(10, 11);
Adafruit_Fingerprint finger = Adafruit_Fingerprint(&mySerial);
void setup()
{
Serial.begin(9600);
while (!Serial); // For Yun/Leo/Micro/Zero/...
delay(100);
Serial.println("\n\n Finger detect test");
// set the data rate for the sensor serial port
finger.begin(57600);
if (finger.verifyPassword()) {
Serial.println("Found fingerprint sensor!");
} else {
Serial.println("Did not find fingerprint sensor :(");
while (1) { delay(1); }
}
finger.getTemplateCount();
Serial.print("Sensor contains "); Serial.print(finger.templateCount); Serial.println(" templates");
Serial.println("Waiting for valid finger...");
}
void loop() // run over and over again
{
getFingerprintIDez();
delay(50); //don't ned to run this at full speed.
}
uint8_t getFingerprintID() {
uint8_t p = finger.getImage();
switch (p) {
case FINGERPRINT_OK:
Serial.println("Image taken");
break;
case FINGERPRINT_NOFINGER:
Serial.println("No finger detected");
return p;
case FINGERPRINT_PACKETRECIEVEERR:
Serial.println("Communication error");
return p;
case FINGERPRINT_IMAGEFAIL:
Serial.println("Imaging error");
return p;
default:
Serial.println("Unknown error");
return p;
}
// OK success!
p = finger.image2Tz();
switch (p) {
case FINGERPRINT_OK:
Serial.println("Image converted");
break;
case FINGERPRINT_IMAGEMESS:
Serial.println("Image too messy");
return p;
case FINGERPRINT_PACKETRECIEVEERR:
Serial.println("Communication error");
return p;
case FINGERPRINT_FEATUREFAIL:
Serial.println("Could not find fingerprint features");
return p;
case FINGERPRINT_INVALIDIMAGE:
Serial.println("Could not find fingerprint features");
return p;
default:
Serial.println("Unknown error");
return p;
}
// OK converted!
p = finger.fingerFastSearch();
if (p == FINGERPRINT_OK) {
Serial.println("Found a print match!");
} else if (p == FINGERPRINT_PACKETRECIEVEERR) {
Serial.println("Communication error");
return p;
} else if (p == FINGERPRINT_NOTFOUND) {
Serial.println("Did not find a match");
return p;
} else {
Serial.println("Unknown error");
return p;
}
// found a match!
Serial.print("Found ID #"); Serial.print(finger.fingerID);
Serial.print(" with confidence of "); Serial.println(finger.confidence);
return finger.fingerID;
}
// 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;
}

Now, let’s configure the real time clock. This module has its own battery so even when the Arduino is not powered, it will still keep the real time for more than a year. But first, we have to tell it the real time. Connect it below this to the Arduinos i2c port. Now open the set time example code from below and make sure you install the DS32 31 library you will also find below.
// DS3231: SDA pin -> Arduino UNO: A4 pin / Ardunino MEGA: SDA pin
// SCL pin -> Arduino UNO: A5 pin / Ardunino MEGA: SCL pin
#include <DS3231.h> //Downlaod library here: https://www.electronoobs.com/eng_arduino_ds3231.php
DS3231 rtc(SDA, SCL);
void setup()
{
// Setup Serial connection
Serial.begin(115200);
// Uncomment the next line if you are using an Arduino Leonardo
//while (!Serial) {}
// Initialize the rtc object
rtc.begin();
// The following lines can be uncommented to set the date and time
//rtc.setDOW(MONDAY); // Set Day-of-Week to SUNDAY
//rtc.setTime(11, 47, 0); // Set the time to 12:00:00 (24hr format)
//rtc.setDate(28, 8, 2018); // Set the date to January 1st, 2014
}
void loop()
{
// Send Day-of-Week
Serial.print(rtc.getDOWStr());
Serial.print(" ");
// Send date
Serial.print(rtc.getDateStr());
Serial.print(" -- ");
// Send time
Serial.println(rtc.getTimeStr());
// Wait one second before repeating :)
delay (1000);
}

Here in the code above, uncomment the 3 lines in the setup loop and add the exact date and time. Add the day, month, year and then the hour, minute and seconds and upload the code. Then comment back the lines and upload the code once again. Open serial monitor, and there you have it, this is the real time you get from the sensor and all you have to do is to use the get time and get date functions of the DS32 31 library. So, now we know how to use the RTL module as well.

We already seen how the SD card module works in the 3D scanner tutorial. Check that video for more details. You need to install the SD library you will find below as well. Using the SD open and SD print function we can write data to the SD card in an txt format.
That’s it. Now the final code is quite long. I’ve placed comments to help you understand it. The main idea goes like this. The buttons will activate the loops for scanning, adding new user or close the door. After each loop, there is an SD card log print and in each SD print, we read the real time. Mount the enxt schematic below and then upload the final code and gieve it a test.

Below the void loop, we have two functions. One is to scan the finger and the other is to add new user to the database. In the bit of code below you can change which ID is the main user, in my case is ID 1 and only this ID can add new users. Also, there is the maximum and minimum angle of the servo motor for open and close the door. Change these values in case you need others angle. That’s it, upload this code to the Arduino mega and make sure you have this schematic for the final project.
* Webpage: https://www.electronoobs.com/eng_arduino_tut41.php
* Schematic: https://www.electronoobs.com/eng_arduino_tut40_sch1.php
* Code: https://www.electronoobs.com/eng_arduino_tut40_code3.php
* Youtube Channel: https://www.youtube.com/c/Electronoobs */
////////////////////////////////////INCLUDE ALL LIBRARIES/////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27,20,4); //sometimes the adress is not 0x3f. Change to 0x27 if it dosn't work.
//Fingerprint libraries
#include <Adafruit_Fingerprint.h>
#include <SoftwareSerial.h>
int getFingerprintIDez();
SoftwareSerial mySerial(10, 11); // pin #2 is IN from sensor (GREEN wire)/ pin #3 is OUT from arduino (WHITE wire)
Adafruit_Fingerprint finger = Adafruit_Fingerprint(&mySerial);
//Real time clock libraries
#include <DS3231.h>
DS3231 rtc(SDA, SCL);// Init the DS3231 using the hardware interface
//SD card read/write libraries
#include <SPI.h>
#include <SD.h>
File myFile;
//servo library
#include <Servo.h>
Servo miServo;
/////////////////////////////////////Input and outputs////////////////////////////////////////////////
int scan_pin = 13; //Pin for the scan push button
int add_id_pin = 12; //Pin for the add new ID push button
int close_door = 9; //Pin to close the door button
int green_led = 8; //Extra LEDs for open or close door labels
int red_led = 7;
int servo = 6; //Pin for the Servo PWM signal
//////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////Editable variables//////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////
int main_user_ID = 1; //Change this value if you want a different main user
int door_open_degrees = 180;
int door_close_degrees = 0;
String file_name_to_save = "blackBox.txt";
//////////////////////////////////////////////////////////////////////////////////////////////////////
//Other used variables in the code. Do not change!
bool scanning = false;
int counter = 0;
int id_ad_counter = 0;
bool id_ad = false;
uint8_t num = 1;
bool id_selected = false;
uint8_t id;
bool first_read = false;
bool main_user = false;
bool add_new_id = false;
bool door_locked = true;
void setup() {
Serial.begin(57600); //Start serial communication for fingerprint TX RX data.
rtc.begin(); //Start the real time clock (remember to set time before this code)
SD.begin(53); //Start SD card module with CS pin connected to D53 of the Arduino MEGA. The other pins are SPI pins
/*Now we open the new created file, write the data, and close it back*/
myFile = SD.open(file_name_to_save, FILE_WRITE); //Create a new file on the SD card named before
myFile.print("Door lock system started at ");
myFile.print(rtc.getTimeStr()); myFile.print(" and day "); myFile.print(rtc.getDateStr());
myFile.println(" ");myFile.println(" ");
myFile.close();
lcd.init(); //Init the LCD with i2c communication and print text
lcd.backlight();
lcd.setCursor(0,0);
lcd.print(" Press SCAN ");
lcd.setCursor(0,1);
lcd.print(" -door locked- ");
//Define pins as outputs or inputs
pinMode(scan_pin,INPUT);
pinMode(add_id_pin,INPUT);
pinMode(close_door,INPUT);
miServo.attach(servo);
miServo.write(door_close_degrees); //Door close
digitalWrite(red_led,HIGH); //Red LED turned ON, shows door CLOSED
digitalWrite(green_led,LOW); //Green LED turned OFF
finger.begin(57600); // set the data rate for the sensor serial port
}
//////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////VOID LOOP////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////
void loop() {
/////////////////////////////////////////DOOR CLOSE BUTTON PRESSED///////////////////////////////////
if(digitalRead(close_door))
{
door_locked = true;
miServo.write(door_close_degrees); //Door close
digitalWrite(red_led,HIGH); //Red LED turned ON, shows door CLOSED
digitalWrite(green_led,LOW); //Green LED turned OFF
lcd.setCursor(0,0);
lcd.print(" Door closed! ");
lcd.setCursor(0,1);
lcd.print(" ");
delay(2000);
lcd.setCursor(0,0);
lcd.print(" Press SCAN ");
lcd.setCursor(0,1);
lcd.print(" -door locked- ");
myFile = SD.open(file_name_to_save, FILE_WRITE);
myFile.print(rtc.getDateStr()); myFile.print(" -- "); myFile.print(rtc.getTimeStr());
myFile.println(" -- Door was closed by a user");
myFile.close();
}
////////////////////////////////Scan button pressed/////////////////////////////////////////////////
if(digitalRead(scan_pin) && !id_ad)
{
myFile = SD.open(file_name_to_save, FILE_WRITE);
myFile.print(rtc.getDateStr()); myFile.print(" -- "); myFile.print(rtc.getTimeStr());
myFile.println(" -- Attempt of openning door");
myFile.close();
scanning = true;
lcd.setCursor(0,0);
lcd.print(" Place finger ");
lcd.setCursor(0,1);
lcd.print("SCANNING--------");
}
while(scanning && counter <= 60)
{
getFingerprintID();
delay(100);
counter = counter + 1;
if(counter == 10)
{
lcd.setCursor(0,0);
lcd.print(" Place finger ");
lcd.setCursor(0,1);
lcd.print("SCANNING ------");
}
if(counter == 20)
{
lcd.setCursor(0,0);
lcd.print(" Place finger ");
lcd.setCursor(0,1);
lcd.print("SCANNING ----");
}
if(counter == 40)
{
lcd.setCursor(0,0);
lcd.print(" Place finger ");
lcd.setCursor(0,1);
lcd.print("SCANNING --");
}
if(counter == 50)
{
lcd.setCursor(0,0);
lcd.print(" Place finger ");
lcd.setCursor(0,1);
lcd.print("SCANNING ");
}
if(counter == 59)
{
lcd.setCursor(0,0);
lcd.print(" Timeout! ");
lcd.setCursor(0,1);
lcd.print(" Try again! ");
myFile = SD.open(file_name_to_save, FILE_WRITE);
myFile.print(rtc.getDateStr()); myFile.print(" -- "); myFile.print(rtc.getTimeStr());
myFile.println(" -- Scanning timeout!");
myFile.close();
delay(2000);
if(door_locked)
{
lcd.setCursor(0,0);
lcd.print(" Press SCAN ");
lcd.setCursor(0,1);
lcd.print(" -door locked- ");
}
else
{
lcd.setCursor(0,0);
lcd.print(" Press SCAN ");
lcd.setCursor(0,1);
lcd.print(" -door open- ");
}
}
}
scanning = false;
counter = 0;
///////////////////////////////END WITH SCANNING PART
//////////////////////////////////////////Add new button pressed///////////////////////////////////////////
if(digitalRead(add_id_pin) && !id_ad)
{
myFile = SD.open(file_name_to_save, FILE_WRITE);
myFile.print(rtc.getDateStr()); myFile.print(" -- "); myFile.print(rtc.getTimeStr());
myFile.println(" -- Add new user attempt. Require identification!");
myFile.close();
add_new_id = true;
lcd.setCursor(0,0);
lcd.print(" Scan main user ");
lcd.setCursor(0,1);
lcd.print(" finger first! ");
while (id_ad_counter < 40 && !main_user)
{
getFingerprintID();
delay(100);
id_ad_counter = id_ad_counter+1;
if(!add_new_id)
{
id_ad_counter = 40;
}
}
id_ad_counter = 0;
add_new_id = false;
if(main_user)
{
lcd.setCursor(0,0);
lcd.print(" Add new ID# to ");
lcd.setCursor(0,1);
lcd.print(" the database ");
delay(1500);
print_num(num);
id_ad = true;
myFile = SD.open(file_name_to_save, FILE_WRITE);
myFile.print(rtc.getDateStr()); myFile.print(" -- "); myFile.print(rtc.getTimeStr());
myFile.println(" -- Add new user permission granted");
myFile.close();
}
else
{
lcd.setCursor(0,0);
lcd.print("ERROR! Only main");
lcd.setCursor(0,1);
lcd.print("user can add IDs");
delay(1500);
if(door_locked)
{
lcd.setCursor(0,0);
lcd.print(" Press SCAN ");
lcd.setCursor(0,1);
lcd.print(" -door locked- ");
}
else
{
lcd.setCursor(0,0);
lcd.print(" Press SCAN ");
lcd.setCursor(0,1);
lcd.print(" -door open- ");
}
id_ad = false;
myFile = SD.open(file_name_to_save, FILE_WRITE);
myFile.print(rtc.getDateStr()); myFile.print(" -- "); myFile.print(rtc.getTimeStr());
myFile.println(" -- The user does not have permission to add new user");
myFile.close();
}
}
if(digitalRead(scan_pin) && id_ad)
{
id=num;
while (! getFingerprintEnroll() );
id_ad = false;
lcd.clear();
lcd.setCursor(0,0);
lcd.print(" New ID saved ");
lcd.setCursor(4,1);
lcd.print("as ID #");
lcd.setCursor(11,1);
lcd.print(id);
delay(3000);
if(door_locked)
{
lcd.setCursor(0,0);
lcd.print(" Press SCAN ");
lcd.setCursor(0,1);
lcd.print(" -door locked- ");
}
else
{
lcd.setCursor(0,0);
lcd.print(" Press SCAN ");
lcd.setCursor(0,1);
lcd.print(" -door open- ");
}
add_new_id = false;
main_user = false;
id_ad = false;
}
if(digitalRead(add_id_pin) && id_ad)
{
num = num + 1;
if(num > 16)
{
num=1;
}
print_num(num);
}
}//end of void
//////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////
/*This function will print the ID numbers when adding new ID*/
void print_num(uint8_t)
{
if (num == 1)
{
lcd.setCursor(0,0);
lcd.print("Select ID number");
lcd.setCursor(0,1);
lcd.print(">1 2 3 4 ");
delay(500);
}
if (num == 2)
{
lcd.setCursor(0,0);
lcd.print("Select ID number");
lcd.setCursor(0,1);
lcd.print(" 1 >2 3 4 ");
delay(500);
}
if (num == 3)
{
lcd.setCursor(0,0);
lcd.print("Select ID number");
lcd.setCursor(0,1);
lcd.print(" 1 2 >3 4 ");
delay(500);
}
if (num == 4)
{
lcd.setCursor(0,0);
lcd.print("Select ID number");
lcd.setCursor(0,1);
lcd.print(" 1 2 3 >4 ");
delay(500);
}
if (num == 5)
{
lcd.setCursor(0,0);
lcd.print("Select ID number");
lcd.setCursor(0,1);
lcd.print(">5 6 7 8 ");
delay(500);
}
if (num == 6)
{
lcd.setCursor(0,0);
lcd.print("Select ID number");
lcd.setCursor(0,1);
lcd.print(" 5 >6 7 8 ");
delay(500);
}
if (num == 7)
{
lcd.setCursor(0,0);
lcd.print("Select ID number");
lcd.setCursor(0,1);
lcd.print(" 5 6 >7 8 ");
delay(500);
}
if (num == 8)
{
lcd.setCursor(0,0);
lcd.print("Select ID number");
lcd.setCursor(0,1);
lcd.print(" 5 6 7 >8 ");
delay(500);
}
if (num == 9)
{
lcd.setCursor(0,0);
lcd.print("Select ID number");
lcd.setCursor(0,1);
lcd.print(">9 10 11 12 ");
delay(500);
}
if (num == 10)
{
lcd.setCursor(0,0);
lcd.print("Select ID number");
lcd.setCursor(0,1);
lcd.print(" 9 >10 11 12 ");
delay(500);
}
if (num == 11)
{
lcd.setCursor(0,0);
lcd.print("Select ID number");
lcd.setCursor(0,1);
lcd.print(" 9 10 >11 12 ");
delay(500);
}
if (num == 12)
{
lcd.setCursor(0,0);
lcd.print("Select ID number");
lcd.setCursor(0,1);
lcd.print(" 9 10 11 >12 ");
delay(500);
}
if (num == 13)
{
lcd.setCursor(0,0);
lcd.print("Select ID number");
lcd.setCursor(0,1);
lcd.print(">13 14 15 16 ");
delay(500);
}
if (num == 14)
{
lcd.setCursor(0,0);
lcd.print("Select ID number");
lcd.setCursor(0,1);
lcd.print(" 13 >14 15 16 ");
delay(500);
}
if (num == 15)
{
lcd.setCursor(0,0);
lcd.print("Select ID number");
lcd.setCursor(0,1);
lcd.print(" 13 14 >15 16 ");
delay(500);
}
if (num == 16)
{
lcd.setCursor(0,0);
lcd.print("Select ID number");
lcd.setCursor(0,1);
lcd.print(" 13 14 15 >16 ");
delay(500);
}
}
/*This function will read the fingerprint placed on the sensor*/
uint8_t getFingerprintID()
{
uint8_t p = finger.getImage();
switch (p)
{
case FINGERPRINT_OK:
break;
case FINGERPRINT_NOFINGER: return p;
case FINGERPRINT_PACKETRECIEVEERR: return p;
case FINGERPRINT_IMAGEFAIL: return p;
default: return p;
}
// OK success!
p = finger.image2Tz();
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;
}
// OK converted!
p = finger.fingerFastSearch();
if (p == FINGERPRINT_OK)
{
scanning = false;
counter = 0;
if(add_new_id)
{
if(finger.fingerID == main_user_ID)
{
main_user = true;
id_ad = false;
}
else
{
add_new_id = false;
main_user = false;
id_ad = false;
}
}
else
{
miServo.write(door_open_degrees); //degrees so door is open
digitalWrite(red_led,LOW); //Red LED turned OFF
digitalWrite(green_led,HIGH); //Green LED turned ON, shows door OPEN
lcd.clear();
lcd.setCursor(0,0);
lcd.print(" User match ");
lcd.setCursor(0,1);
lcd.print(" ID: #");
lcd.setCursor(6,1);
lcd.print(finger.fingerID);
lcd.setCursor(9,1);
lcd.print("%: ");
lcd.setCursor(12,1);
lcd.print(finger.confidence);
myFile = SD.open(file_name_to_save, FILE_WRITE);
myFile.print(rtc.getDateStr()); myFile.print(" -- "); myFile.print(rtc.getTimeStr());
myFile.print(" -- User match for ID# "); myFile.print(finger.fingerID);
myFile.print(" with confidence: "); myFile.print(finger.confidence); myFile.println(" - door open");
myFile.close();
door_locked = false;
delay(4000);
lcd.setCursor(0,0);
lcd.print(" Press SCAN ");
lcd.setCursor(0,1);
lcd.print(" -door open- ");
delay(50);
}
}//end finger OK
else if(p == FINGERPRINT_NOTFOUND)
{
scanning = false;
id_ad = false;
counter = 0;
lcd.setCursor(0,0);
lcd.print(" No match ");
lcd.setCursor(0,1);
lcd.print(" Try again! ");
add_new_id = false;
main_user = false;
myFile = SD.open(file_name_to_save, FILE_WRITE);
myFile.print(rtc.getDateStr()); myFile.print(" -- "); myFile.print(rtc.getTimeStr());
myFile.print(" -- No match for any ID. Door status still the same");
myFile.close();
delay(2000);
if(door_locked)
{
lcd.setCursor(0,0);
lcd.print(" Press SCAN ");
lcd.setCursor(0,1);
lcd.print(" -door locked- ");
}
else
{
lcd.setCursor(0,0);
lcd.print(" Press SCAN ");
lcd.setCursor(0,1);
lcd.print(" -door open- ");
}
delay(2);
return p;
}//end finger error
}// 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!
return finger.fingerID;
}
//////////////////////////////////////////
/*This function will add new ID to the database*/
uint8_t getFingerprintEnroll() {
int p = -1;
if(!first_read)
{
lcd.setCursor(0,0);
lcd.print("Add new as ID# ");
lcd.setCursor(14,0);
lcd.print(id);
lcd.setCursor(0,1);
lcd.print(" Place finger ");
}
while (p != FINGERPRINT_OK) {
p = finger.getImage();
switch (p) {
case FINGERPRINT_OK:
lcd.setCursor(0,0);
lcd.print(" Image taken! ");
lcd.setCursor(0,1);
lcd.print(" ");
delay(100);
first_read = true;
break;
case FINGERPRINT_NOFINGER:
lcd.setCursor(0,0);
lcd.print("Add new as ID# ");
lcd.setCursor(14,0);
lcd.print(id);
lcd.setCursor(0,1);
lcd.print(" Place finger ");
break;
case FINGERPRINT_PACKETRECIEVEERR:
lcd.setCursor(0,0);
lcd.print(" Comunication ");
lcd.setCursor(0,1);
lcd.print(" ERROR! ");
delay(1000);
break;
case FINGERPRINT_IMAGEFAIL:
lcd.setCursor(0,0);
lcd.print(" -Image ");
lcd.setCursor(0,1);
lcd.print(" ERROR! ");
delay(1000);
break;
default:
lcd.setCursor(0,0);
lcd.print(" -Unknown ");
lcd.setCursor(0,1);
lcd.print(" ERROR! ");
delay(1000);
break;
}
}
// OK success!
p = finger.image2Tz(1);
switch (p) {
case FINGERPRINT_OK:
lcd.setCursor(0,0);
lcd.print("Image converted!");
lcd.setCursor(0,1);
lcd.print(" ");
break;
case FINGERPRINT_IMAGEMESS:
lcd.setCursor(0,0);
lcd.print("Image too messy!");
lcd.setCursor(0,1);
lcd.print(" ");
delay(1000);
return p;
case FINGERPRINT_PACKETRECIEVEERR:
lcd.setCursor(0,0);
lcd.print(" Comunication ");
lcd.setCursor(0,1);
lcd.print(" ERROR! ");
delay(1000);
return p;
case FINGERPRINT_FEATUREFAIL:
lcd.setCursor(0,0);
lcd.print(" No fingerprint ");
lcd.setCursor(0,1);
lcd.print("features found ");
delay(1000);
return p;
case FINGERPRINT_INVALIDIMAGE:
lcd.setCursor(0,0);
lcd.print(" No fingerprint ");
lcd.setCursor(0,1);
lcd.print("features found ");
delay(1000);
return p;
default:
lcd.setCursor(0,0);
lcd.print(" -Unknown ");
lcd.setCursor(0,1);
lcd.print(" ERROR! ");
delay(1000);
return p;
}
lcd.setCursor(0,0);
lcd.print(" Remove finger! ");
lcd.setCursor(0,1);
lcd.print(" ");
delay(2000);
p = 0;
while (p != FINGERPRINT_NOFINGER) {
p = finger.getImage();
}
lcd.setCursor(0,1);
lcd.print("ID# ");
lcd.setCursor(4,1);
lcd.print(id);
p = -1;
lcd.setCursor(0,0);
lcd.print("Place again the ");
lcd.setCursor(0,1);
lcd.print("same finger ");
while (p != FINGERPRINT_OK) {
p = finger.getImage();
switch (p) {
case FINGERPRINT_OK:
lcd.setCursor(0,0);
lcd.print(" Image taken! ");
lcd.setCursor(0,1);
lcd.print(" ");
break;
case FINGERPRINT_NOFINGER:
lcd.setCursor(0,0);
lcd.print("Place again the ");
lcd.setCursor(0,1);
lcd.print("same finger ");
break;
case FINGERPRINT_PACKETRECIEVEERR:
lcd.setCursor(0,0);
lcd.print(" Comunication ");
lcd.setCursor(0,1);
lcd.print(" ERROR! ");
delay(1000);
break;
case FINGERPRINT_IMAGEFAIL:
lcd.setCursor(0,0);
lcd.print(" -Image ");
lcd.setCursor(0,1);
lcd.print(" ERROR! ");
delay(1000);
break;
default:
lcd.setCursor(0,0);
lcd.print(" -Unknown ");
lcd.setCursor(0,1);
lcd.print(" ERROR! ");
delay(1000);
break;
}
}
// OK success!
p = finger.image2Tz(2);
switch (p) {
case FINGERPRINT_OK:
lcd.setCursor(0,0);
lcd.print("Image converted!");
lcd.setCursor(0,1);
lcd.print(" ");
break;
case FINGERPRINT_IMAGEMESS:
lcd.setCursor(0,0);
lcd.print("Image too messy!");
lcd.setCursor(0,1);
lcd.print(" ");
delay(1000);
return p;
case FINGERPRINT_PACKETRECIEVEERR:
lcd.setCursor(0,0);
lcd.print(" Comunication ");
lcd.setCursor(0,1);
lcd.print(" ERROR! ");
delay(1000);
return p;
case FINGERPRINT_FEATUREFAIL:
lcd.setCursor(0,0);
lcd.print(" No fingerprint ");
lcd.setCursor(0,1);
lcd.print("features found ");
delay(1000);
return p;
case FINGERPRINT_INVALIDIMAGE:
lcd.setCursor(0,0);
lcd.print(" Comunication ");
lcd.setCursor(0,1);
lcd.print(" ERROR! ");
delay(1000);
return p;
default:
lcd.setCursor(0,0);
lcd.print(" -Unknown ");
lcd.setCursor(0,1);
lcd.print(" ERROR! ");
delay(1000);
return p;
}
// OK converted!
lcd.setCursor(0,0);
lcd.print(" Creating model ");
lcd.setCursor(0,1);
lcd.print("for ID# ");
lcd.setCursor(8,1);
lcd.print(id);
p = finger.createModel();
if (p == FINGERPRINT_OK) {
lcd.setCursor(0,0);
lcd.print(" Print matched! ");
lcd.setCursor(0,1);
lcd.print(" ");
delay(1000);
} else if (p == FINGERPRINT_PACKETRECIEVEERR) {
lcd.setCursor(0,0);
lcd.print(" Comunication ");
lcd.setCursor(0,1);
lcd.print(" ERROR! ");
delay(1000);
return p;
} else if (p == FINGERPRINT_ENROLLMISMATCH) {
lcd.setCursor(0,0);
lcd.print("Fingerprint did ");
lcd.setCursor(0,1);
lcd.print("not match ");
delay(1000);
return p;
} else {
lcd.setCursor(0,0);
lcd.print(" -Unknown ");
lcd.setCursor(0,1);
lcd.print(" ERROR! ");
delay(1000);
return p;
}
lcd.setCursor(0,1);
lcd.print("ID# ");
lcd.setCursor(4,1);
lcd.print(id);
p = finger.storeModel(id);
if (p == FINGERPRINT_OK) {
lcd.setCursor(0,0);
lcd.print(" Stored ");
lcd.setCursor(0,1);
lcd.print(" ");
myFile = SD.open(file_name_to_save, FILE_WRITE);
myFile.print(rtc.getDateStr()); myFile.print(" -- "); myFile.print(rtc.getTimeStr());
myFile.print(" -- New fingerprint stored for ID# "); myFile.println(id);
myFile.close();
delay(1000);
first_read = false;
id_ad = false;
} else if (p == FINGERPRINT_PACKETRECIEVEERR) {
lcd.setCursor(0,0);
lcd.print(" Comunication ");
lcd.setCursor(0,1);
lcd.print(" ERROR! ");
delay(1000);
return p;
} else if (p == FINGERPRINT_BADLOCATION) {
lcd.setCursor(0,0);
lcd.print("Could not store ");
lcd.setCursor(0,1);
lcd.print("in that location");
delay(1000);
return p;
} else if (p == FINGERPRINT_FLASHERR) {
lcd.setCursor(0,0);
lcd.print("Error writing to");
lcd.setCursor(0,1);
lcd.print("flash ");
delay(1000);
return p;
} else {
lcd.setCursor(0,0);
lcd.print(" -Unknown ");
lcd.setCursor(0,1);
lcd.print(" ERROR! ");
delay(1000);
return p;
}
}
Now we have the final schematic and code. All we need is the 3D printed case that you could downlaod froma link below and 3D print it. Fit the LCD in place and the Arduino MEGA using m3 screws. Then using wires we make all the connections and our door lock is ready. There is space for 3 push buttons as well.

Now the case and project is ready. I hope that you've enjoyed the tutorial and that you have learned something new. Now you know how to use the fingerprint sensor, RTC module and the SD card module and create a black box door lock with fingerprint security. Consider helping me on PATREON.
Leave a comment
Please login in order to comment.