Overview:
Security is essential in protecting our things, loved ones, and ourselves. Security at homes and buildings involves locks which can be purely mechanical or electromechanical. Other forms of security are being introduced such as biometrics, where a certain body part, a finger for example is scanned to create a unique identification of the owner to grant access. This project combines biometrics with electromagnetic locks to create Biometrics – Controlled Solenoid Lock with an alarm feature.
Hardware and Software Components:
Hardware:
Software:
Application Discussion:
- Optical Fingerprint Reader
- Small size with low voltage consumption of 3.3V - 6V
- Operating temperature of -20C to +50C and humidity of 40%-85% RH
- It can produce fingerprint image in less than a second
- It can enroll up to 162 fingerprints which is stored in the sensor's flash memory
- Features the UART communication interface to exchange data between the sensor and the arduino
- The Adafruit_Fingerprint library is needed for the sensor to enroll and read fingerprints.
- Solenoid Electro Magnetic Lock LP
- Mostly used for locking vending machines, shelfs, cabinets, etc.
- Uses a 12V power supply to operate
- Solenoid Lock works by introducing current, generating a strong magnetic field around which attracts the actuator arm to lock/unlock.
What is a Solenoid?
A solenoid is a device comprised of a coil of wire, the housing and a moveable plunger (armature). The coil is made of many turns of tightly wound copper wire. When an electrical current flows through this wire, a strong magnetic field/flux is created. The housing, usually made of iron or steel, surrounds the coil concentrating the magnetic field generated by the coil. The plunger is attracted to the stop through the concentration of the magnetic field providing the mechanical force to do work.
- Arduino Uno
- The Arduino-compatible UNO R3 board differs from official Arduino UNO R3 board in that it does not use the expensive FTDI USB-to-serial driver chip.
- Instead, it features the CH340 USB-to-serial converter chip which makes it low cost and 100% Arduino UNO R3 compatible.
- 1-Channel Relay Module
- Operating voltage of 5V/10A, which can be operated using Arduino
- An electromagnetic switch capable of controlling a much larger current by introducing a small current to the circuit.
- Composed of 3 terminals; the common (COM), normally opened (NO), and normally closed (NC) terminal
How relay works?
Relay works on the principle of electromagnetic induction. A switch is used to apply direct current to the load. In the relay, the copper coil and the iron core acts as electromagnet. When the electromagnet is applied with some current, it induces a magnetic field around it, then attracts the contact. When the supply is removed, it reverts back to its original position.
- Passive Buzzer
- Operating voltage of 3V - 5V
- Consists of a Piezo element within and has two pins, one for power and other for ground
- Also known as Transducer, it uses AC power that is driven through an onboard circuit. The frequency is dependent on the input square wave signal, as it changes so does the frequency, hence offering more variance in its usage
- RGB LED
- Operating Voltage of 1.8V-2.2V(Red), and 3V-3.4V (Green/Blue)
- An LED package that can produce almost any color. It can be used in different applications such as outdoor decoration lighting, stage lighting designs, home decoration lighting, LED matrix display, and more.
- RGB LEDs have three internal LEDs (Red, Green, and Blue) that can be combined to produce almost any color output depending on the intensity of each LED
Hardware Set-up:
Schematic Diagram:
-
Fingerprint Sensor
- VCC is connected to Arduino 5V pin
- GND is connected to Arduino GND pin
- TX (Transmitter) is connected to Arduino pin 2
- RX (Receiver) is connected to Arduino pin 3
-
Single-channel Relay
- VCC is connected to Arduino 5V pin
- GND is connected to the Arduino GND pin
- IN1 (input 1) is connected to Arduino pin 8 which serves as the trigger for the solenoid lock
- The VCC wire of the 12V power supply is connected to the common (com) pin for the solenoid lock to function
-
Solenoid Lock
- GND wire of solenoid lock is connected with GND of the 12V power supply
- VCC wire is connected to the NO (Normally Open) pin of the single-channel relay
-
RGB LED
- The RGB LED used for this project is a common cathode (+) meaning there’s only one GND connection which is connected to Arduino GND pin
- The red terminal is connected to Arduino pin 5
- The green terminal is connected to Arduino pin 6
-
Buzzer
- The positive terminal is connected to Arduino pin 7
- The GND terminal is connected to the Arduino GND pin
Software Set-up:
Code:
#include <Adafruit_Fingerprint.h>
#if (defined(__AVR__) || defined(ESP8266)) && !defined(__AVR_ATmega2560__)
// For UNO and others without hardware serial, we must use software serial...
// pin #2 is IN from sensor (GREEN wire)
// pin #3 is OUT from arduino (WHITE wire)
// Set up the serial port to use softwareserial..
SoftwareSerial mySerial(2, 3);
#else
// On Leonardo/M0/etc, others with hardware serial, use hardware serial!
// #0 is green wire, #1 is white
#define mySerial Serial1
#endif
Adafruit_Fingerprint finger = Adafruit_Fingerprint(&mySerial);
//FINGERPRINT ID
uint8_t id;
//RELAY PIN
const int relay = 8;
//RGB LED pins
const int red = 5;
const int green = 6;
//BUZZER pin
const int buzzer = 7;
void setup() {
Serial.begin(9600);
while (!Serial);
delay(100);
Serial.println("\n\nAdafruit finger detect test");
// set the data rate for the sensor serial port
finger.begin(57600);
delay(5);
if (finger.verifyPassword()) {
Serial.println("Found fingerprint sensor!");
} else {
Serial.println("Did not find fingerprint sensor :(");
while (1) { delay(1); }
}
Serial.println(F("Reading sensor parameters"));
finger.getParameters();
Serial.print(F("Status: 0x")); Serial.println(finger.status_reg, HEX);
Serial.print(F("Sys ID: 0x")); Serial.println(finger.system_id, HEX);
Serial.print(F("Capacity: ")); Serial.println(finger.capacity);
Serial.print(F("Security level: ")); Serial.println(finger.security_level);
Serial.print(F("Device address: ")); Serial.println(finger.device_addr, HEX);
Serial.print(F("Packet len: ")); Serial.println(finger.packet_len);
Serial.print(F("Baud rate: ")); Serial.println(finger.baud_rate);
//RGB LED
pinMode(red,OUTPUT);
pinMode(green,OUTPUT);
//RELAY
pinMode(relay,OUTPUT);
}
//READ INPUT NUMBER
uint8_t readnumber(void) {
uint8_t num = 0;
while (num == 0) {
while (! Serial.available());
num = Serial.parseInt();
}
return num;
}
void loop() {
//DEFAULT STATE
//led
digitalWrite(red,LOW);
digitalWrite(green,LOW);
//relay
digitalWrite(relay,HIGH);
//CHECK SENSOR FOR STORED FINGERPRINT TEMPLATES
finger.getTemplateCount();
Serial.print("Sensor contains "); Serial.print(finger.templateCount); Serial.println(" templates");
if (finger.templateCount == 0) {
Serial.print("Sensor doesn't contain any fingerprint data.");
//INPUT FINGERPRINT STORAGE NUMBER
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() ); //loop number request when no input number else advance to fingerprint registration
} else {
Serial.println("Waiting for valid finger...");
//FINGERPRINT IDENTIFICATION
getFingerprintID(); //fingerprint identification process
}
delay(500); //loop delay
}
//FINGERPRINT VERIFICATION MAIN CLASS
uint8_t getFingerprintID() {
//SCAN FINGERPRINT
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;
}
//CHECK FINGERPRINT IMAGE AND CONVERT IT TO DATA FOR COMPARISON
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;
}
//CHECK MATCHING FINGERPRINT FROM MEMORY
p = finger.fingerSearch();
if (p == FINGERPRINT_OK) {
Serial.println("Found a print match!");
//FINGERPRINT MATCHED = UNLOCK
//led
digitalWrite(red,LOW);
digitalWrite(green,HIGH);
//buzzer
tone(buzzer, 450);
delay(500);
noTone(buzzer);
delay(250);
tone(buzzer, 450); //450 frequency
delay(500);
noTone(buzzer);
//relay
digitalWrite(relay,LOW);
delay(500);
} else if (p == FINGERPRINT_PACKETRECIEVEERR) {
Serial.println("Communication error");
return p;
} else if (p == FINGERPRINT_NOTFOUND) {
Serial.println("Did not find a match");
//FINGERPRINT UNIDENTIFIED = LOCK
//led
digitalWrite(red,HIGH);
digitalWrite(green,LOW);
//buzzer
tone(buzzer, 450);
delay(1000);
noTone(buzzer);
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;
}
//FINGERPRINT REGISTRATION MAIN CLASS
uint8_t getFingerprintEnroll() {
int p = -1; //
//SCANNING FINGERPRINT
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!
//SCANNED FINGERPRINT IMAGE PROCESSING
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;
}
//RESCANNING FINGERPRINT FOR SECURITY
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!
//RESCANNED FINGERPRINT IMAGE PROCESSING
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);
//SCANNED AND RESCANNED FINGERPRINT COMPARISON AND MODEL CREATION
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;
}
//FINGERPRINT MODEL STORAGE
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;
}
return true;
}
Code Breakdown:
Libraries:
- #include <Adafruit_Fingerprint.h>
-
The library to be used to control the fingerprint sensor
- Can be downloaded in the Arduino Library Manager or on the website
Variables:
-
SoftwareSerial mySerial(2, 3);
- Set the pins to use for reading data
- Pin #2 is the TX wire (YELLOW)
- Pin #3 is the RX wire (WHITE)
-
Adafruit_Fingerprint finger = Adafruit_Fingerprint(&mySerial);
- Sets the serial as object for the library to get data
-
uint8_t id;
- 8-bit unsigned int for fingerprint id
- Uint8_t is preferable when running the code in other processors
Functions:
Setup
-
verifyPassword()
- check fingerprint sensor connectivity
-
getParameters()
- get the fingerprint sensor’s information
-
getTemplateCount()
- check sensor memory for existing fingerprint models
- returns finger.templateCount
Loop
@Fingerprint Identification
-
getFingerprintID()
- contains the functions for fingerprint verification
-
getImage()
- get scanned fingerprint image
-
image2Tz()
- process the scanned image and convert it to data
-
fingerSearch()
- match fingerprint data to saved models from the sensor memory
- returns finger.fingerID and finger.confidence
@Fingerprint Registration
-
readnumber()
- get the input number from the serial monitor
-
getFingerprintEnroll()
- contains methods for the fingerprint registration
-
getImage()
- get scanned fingerprint image
-
image2Tz(1)
- process the scanned image and convert it to data
-
getImage()
- get rescanned fingerprint image
-
image2Tz(2)
- process the rescanned image and convert it to data
-
createModel()
- create a fingerprint model from the image data
-
storeModel(id)
- store fingerprint model to sensor memory
Video:
Conclusion:
A solenoid lock with Biometrics authentication provides a more secure way of preventing unauthorized access to doors or containers. The fingerprint sensor scanner is sensitive and is prone to dirt and overlapping fingerprints which can affect its scanning efficiency.
This project mainly used the serial terminal of Arduino to show values. You can interface an LCD with I2C to show values and also a keypad for input. The code only used the fingerprint registration and verification example in Arduino. You can incorporate the fingerprint deletion or the sensor database clear example to complete the sensor functions.
References:
- https://www.aboutmechanics.com/what-is-a-solenoid-door-lock.htm
- https://www.tlxtech.com/articles/solenoid-101-what-is-a-solenoid
- https://artofcircuits.com/product/uno-r3-ch340-board-with-usb-cable
- https://robu.in/product/r307-optical-fingerprint-reader-module-sensor/
- https://www.engineersgarage.com/arduino-adafruit-r30x-r307-fingerprint-scanner/
- https://www.circuitbasics.com/basics-uart-communication/
- https://lastminuteengineers.com/one-channel-relay-module-arduino-tutorial/
- https://www.electronicshub.org/what-is-relay-and-how-it-works/
- https://microdaz.com/what-is-a-passive-buzzer/
- https://www.circuitbread.com/tutorials/how-rgb-leds-work-and-how-to-control-color
- https://www.elprocus.com/what-is-three-rgb-led-and-its-working/
- https://www.lightwaveuk.com/led-technology/how-does-rgb-work/
- https://create.arduino.cc/projecthub/MissionCritical/how-to-set-up-fingerprint-sensor-with-arduino-ebd543