The fingerprint sensor is a widely used sensing element. This project takes the R502/R503 capacitive fingerprint sensor as an example to demonstrate how to enroll and detect fingerprints using the Arduino development board. The project BOM list is as follows: Arduino development board 1, fingerprint sensor R503 1, Dupont wires 20, breadboard 1.
Understanding Capacitive Fingerprint Sensors
Unlike optical fingerprint sensors that create fingerprint images, capacitive products use an array of micro-capacitive circuits to collect data. When a finger presses against the sensing surface, the ridges and valleys of the finger create different small capacitances between the epidermis and the chip. The chip obtains complete fingerprint information by measuring the different electromagnetic fields in the space and processes it through operational amplifiers and ADC. For example, the R502/R503 can recognize both dry and wet fingerprints, with the former being lighter.
Taking the R503 as an example, this sensor has built-in fingerprint recognition algorithms and protocols, with functions such as fingerprint collection, comparison, searching, and template storage. The R503 image size is 192*192, with a resolution of 508 DPI, capable of storing 200 fingerprints, with FRR ≤ 0.01%, FAR ≤ 0.00001%, supporting Arduino, Android, Windows, Linux, etc.
The R503 supports low-power finger detection, with a working voltage of 3.3V, a collection current not exceeding 18mA, and an average standby current of only 2uA. The R503 communicates through the RS232 UART interface, with a communication rate of up to 57600 bps, used for computer peripherals, fingerprint door locks, fingerprint padlocks, safes, etc.
Connecting the R502/R503 to Arduino is straightforward.
Connect the VCC, GND, Tx (yellow wire), and Rx (green wire) pins of the R502/R503 to the 3.3V, GND, D2, and D3 pins of the Arduino development board, respectively. The blue interrupt line does not need to be connected, and the white wire is connected to the 3.3V pin.
Source Code and Programming
The GitHub repository contains the Arduino library files for the R502/R503 fingerprint sensor written by Adafruit. The fingerprint enrollment and reading are separate; the enrollment code is stored in the EEPROM memory, while the reading code retrieves data from the EEPROM and verifies it against the scanned fingerprint data.
The fingerprint enrollment code is as follows:
#include
#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);
uint8_t id;
void setup(){Serial.begin(9600);while (!Serial);// For Yun/Leo/Micro/Zero/...delay(100);Serial.println("\n\nAdafruit Fingerprint sensor enrollment");
// set the data rate for the sensor serial portfinger.begin(57600);
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);}
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;}
return true;}
After uploading the code, open the Serial Monitor, and the monitor will ask for a fingerprint ID between 1-127.
Now enter the ID number on the Serial Monitor and send it, then follow the on-screen instructions to enroll the fingerprint.
Place the finger you want to enroll on the sensor.
Once one finger is successfully enrolled, you can also enroll other fingers in the same way.
The fingerprint reading code is as follows:
#includeint u=0;int relay=5;
#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);
void setup(){pinMode(relay,OUTPUT);Serial.begin(9600);while (!Serial);// For Yun/Leo/Micro/Zero/...delay(100);Serial.println("\n\nAdafruit finger detect test");
// set the data rate for the sensor serial portfinger.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);
finger.getTemplateCount();
if (finger.templateCount == 0) {Serial.print("Sensor doesn't contain any fingerprint data. Please run the 'enroll' example.");}else {Serial.println("Waiting for valid finger...");Serial.print("Sensor contains "); Serial.print(finger.templateCount); Serial.println(" templates");}}
void loop() // run over and over again{getFingerprintID();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");finger.LEDcontrol(FINGERPRINT_LED_OFF, 0, FINGERPRINT_LED_BLUE);finger.LEDcontrol(FINGERPRINT_LED_OFF, 0, FINGERPRINT_LED_RED);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.fingerSearch();if (p == FINGERPRINT_OK) {Serial.println("Found a print match!");finger.LEDcontrol(FINGERPRINT_LED_FLASHING, 25, FINGERPRINT_LED_PURPLE, 10);delay(1000);if(u==0){digitalWrite(relay,HIGH);u=1;}else if(u==1){digitalWrite(relay,LOW);u=0;}} else if (p == FINGERPRINT_PACKETRECIEVEERR) {Serial.println("Communication error");return p;} else if (p == FINGERPRINT_NOTFOUND) {finger.LEDcontrol(FINGERPRINT_LED_FLASHING, 25, FINGERPRINT_LED_RED, 10);delay(1000);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;}
Once the fingerprint enrollment is successful, you can upload the above code to read the fingerprint information stored in the fingerprint database, achieving access control, attendance, booting, and other operations.
Author: Hard City Allchips, Source: Breadboard Community
Link: https://mbb.eet-china.com/blog/3975615-433079.html
Copyright Notice: This article is original by the author, and reproduction is prohibited without permission!
Leave a Comment
Your email address will not be published. Required fields are marked *