指紋傳感器是應用廣泛的感知元件,本項目以R502/R503電容式指紋傳感器為例,演示如何通過Arduino開發(fā)板錄入和檢測指紋。項目BOM清單如下:
Arduino開發(fā)板 1
指紋傳感器R503 1
杜邦線 20
面包板 1
了解電容式指紋傳感器
與光學指紋傳感器的創(chuàng)建指紋圖像不同,電容式產(chǎn)品采用微電容電路組成的陣列來收集數(shù)據(jù)。當手指按壓到采集面上時,手指的脊和谷在表皮和芯片之間產(chǎn)生不同的微小電容,芯片通過測量空間中的不同的電磁場得到完整的指紋信息,并通過運放和ADC進行處理。例如,R502/R503就能識別干、濕指紋,而前者更輕巧。
以R503為例,該傳感器內(nèi)嵌指紋識別算法和協(xié)議,具有指紋采集、比對、搜索和模板存儲等功能。R503圖像大小192*192,分辨率達508 DPI,可存儲200個指紋,F(xiàn)RR≤0.01%,F(xiàn)AR≤0.00001%,支持Arduino、Android、Windows、Linux等。
R503支持低功耗手指檢測,工作電壓3.3V,采集電流不超過18mA,平均待機電流僅2uA。R503通過RS232 UART接口,通訊速率達57600bps,用于電腦外設、指紋門鎖、指紋掛鎖、保險柜等。
把R502/R503與Arduino連接,電電路很簡單。
.
把R502/R503的VCC、GND、Tx (黃線)、Rx (綠線)四個引腳分別連接到Arduino開發(fā)板的3.3V、GND、D2、D3引腳.,藍色的中斷線不用連接,白色引線接到3.3V引腳上。
源代碼及編程
Github倉庫有Adafruit編寫的關(guān)于R502/R503指紋傳感器的Arduino庫文件。指紋錄入和閱讀是分開的,錄入代碼保存在EEPROM存儲器中,閱讀代碼從EEPROM中讀取數(shù)據(jù)并與掃描到的指紋數(shù)據(jù)校驗匹配。
指紋錄入代碼如下:
#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 port
finger.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;
}
上傳代碼后,打開Serial Monitor,監(jiān)視器將詢問位于1-127之間的指紋ID 。
現(xiàn)在Serial Monitor顯示屏中輸入ID號,并發(fā)送,然后按照屏幕指令提示錄入指紋。
把希望錄入的手指放在傳感器上。
一個手指錄入成功后,你也可以按照同樣的方式再錄入其他幾個手指的指紋。
指紋讀取代碼如下:
#include
int 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 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);
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;
}
一旦指紋錄入成功,就可以上傳上述代碼,以讀取存儲在指紋數(shù)據(jù)庫中的指紋信息,通過比對匹配實現(xiàn)門禁、考勤、開機等操作。
審核編輯:湯梓紅
-
接口
+關(guān)注
關(guān)注
33文章
8667瀏覽量
151526 -
開發(fā)板
+關(guān)注
關(guān)注
25文章
5093瀏覽量
97802 -
指紋傳感器
+關(guān)注
關(guān)注
6文章
196瀏覽量
63497 -
Arduino
+關(guān)注
關(guān)注
188文章
6474瀏覽量
187432
發(fā)布評論請先 登錄
相關(guān)推薦
評論