pcDuino指纹识别
- - 极客范 - GeekFan.net指纹,由于其具有终身不变性、唯一性和方便性,已几乎成为生物特征识别的代名词. 今天就给大家展示一下如何在 pcDuino上进行指纹识别. FM-206系列光学指纹模块 x 1. 白线(左数第二根)连接gpio 1. 绿线(左数第三根)连接gpio 0. 黑线(左数第一根)连接GND. 红线(左数第四根)连接 pcduino 上的5v输出.
指纹,由于其具有终身不变性、唯一性和方便性,已几乎成为生物特征识别的代名词。由于科学技术的日益发展。指纹模块也渐渐深入人们生活中。今天就给大家展示一下如何在 pcDuino上进行指纹识别。
pcduino V2 x 1
FM-206系列光学指纹模块 x 1
白线(左数第二根)连接gpio 1
绿线(左数第三根)连接gpio 0
黑线(左数第一根)连接GND
红线(左数第四根)连接 pcduino 上的5v输出
注意:
模块本身自带的线是没有脚的,可能导致接触不良从而实验无法成功,最好如图焊上。
指纹模块录入代码:
/***************** fingerprint_enroll.cpp *****************/ #include <core.h> #include <stdlib.h> #define FINGERPRINT_TIMEOUT 0xFF #define FINGERPRINT_BADPACKET 0xFE #define FINGERPRINT_ACKPACKET 0×07 uint8_t lc = 0; uint8_t i = 0; const uint8_t Verify[] = {0xEF, 0×01, 0xFF, 0xFF, 0xFF, 0xFF, 0×01, 0×00, 0×07, 0×13, 0×00, 0×00, 0×00, 0×00, 0×00, 0x1B}; const uint8_t Getimage[] = {0xEF, 0×01, 0xFF, 0xFF, 0xFF, 0xFF, 0×01, 0×00, 0×03, 0×01, 0×00, 0×05}; const uint8_t Img2tz_1[] = {0xEF, 0×01, 0xFF, 0xFF, 0xFF, 0xFF, 0×01, 0×00, 0×04, 0×02, 0×01, 0×00, 0×08}; const uint8_t Img2tz_2[] = {0xEF, 0×01, 0xFF, 0xFF, 0xFF, 0xFF, 0×01, 0×00, 0×04, 0×02, 0×02, 0×00, 0×09}; const uint8_t Match[] = {0xEF, 0×01, 0xFF, 0xFF, 0xFF, 0xFF, 0×01, 0×00, 0×03, 0×03, 0×00, 0×07}; const uint8_t Regmodel[] = {0xEF, 0×01, 0xFF, 0xFF, 0xFF, 0xFF, 0×01, 0×00, 0×03, 0×05, 0×00, 0×09}; void cmd_fun (const uint8_t *p, uint8_t len){ // printf (“cmd_fun have begin!\n”); // Serial.flush(); for (lc = 0; lc < len; lc++){ Serial.write (*p++); delay (1); } } uint8_t get_reply (uint8_t packet[], uint16_t timeout){ printf (“\n”); // printf (“begin get_reply!\n”); uint8_t reply[20], idx; uint16_t timer = 0; idx = 0; // printf (“begin to loop in get_reply\n”); while (1){ // printf (“begin to loop in while(1)\n”); while (!(Serial.available () > 0)){ delay(1); timer++; if (timer >= timeout) return FINGERPRINT_TIMEOUT; } // printf (“begin to read something!\n”); reply[idx] = Serial.read (); printf(“reply[%x] = %02x “, idx, reply[idx]); if ((idx == 0) && (reply[0] != 0xEF)) continue; idx++; // printf (“idx = %x\n”, idx); if (idx >= 9){ if ((reply[0] != 0xEF) || (reply[1] != 0×01)) return FINGERPRINT_BADPACKET; uint16_t len = reply[7]; len <<= 8; len |= reply[8]; len -= 2; // printf (“len = %x\n”, len); if (idx <= (len + 10)) continue; packet[0] = reply[6]; // printf (“packet[0] = %x\n”, reply[6]); for (uint8_t i = 0; i < len; i++){ packet[1 + i] = reply[9 + i]; // printf (“packet[%x] = %x”,i + 1,packet[1 + i]); } return len; } } } boolean verify_fun (void){ printf (“verify_fun begin!\n”); uint8_t packet[] = {}; cmd_fun (Verify, 16); printf (“packet have send!\n”); uint8_t len = get_reply (packet,5000); printf (“len = %x\n”, len); if ((len != 1) && (packet[0] != FINGERPRINT_ACKPACKET)) return -1; return true; } uint8_t getimage_fun (void){ uint8_t packet[] = {}; cmd_fun (Getimage, 12); uint8_t len = get_reply (packet, 1000); if ((len != 1) && (packet[0] != FINGERPRINT_ACKPACKET)) return -1; return packet[1]; } uint8_t img2tz_1_fun (void){ uint8_t packet[] = {}; cmd_fun (Img2tz_1, 13); uint8_t len = get_reply (packet, 1000); if ((len != 1) && (packet[0] != FINGERPRINT_ACKPACKET)) return -1; return packet[1]; } uint8_t img2tz_2_fun (void){ uint8_t packet[] = {}; cmd_fun (Img2tz_2, 13); uint8_t len = get_reply (packet, 1000); if ((len != 1) && (packet[0] != FINGERPRINT_ACKPACKET)) return -1; return packet[1]; } uint8_t regmodel_fun (void){ uint8_t packet[] = {}; cmd_fun (Regmodel, 12); uint8_t len = get_reply (packet, 1000); if ((len != 1) && (packet[0] != FINGERPRINT_ACKPACKET)) return -1; return packet[1]; } uint8_t store_fun (uint16_t id){ printf (“请输入指纹对应的ID:”); scanf (“%x”, &id); printf (“确认指纹ID : %u\n”, id); uint8_t packet[] = {}; const uint8_t Store[] = {0xEF, 0×01, 0xFF, 0xFF, 0xFF, 0xFF, 0×01, 0×00, 0×06, 0×06, 0×01, id >> 8, id & 0xFF, 0×00, 0x0F}; cmd_fun (Store, 15); uint8_t len = get_reply (packet, 1000); if ((len != 1) && (packet[0] != FINGERPRINT_ACKPACKET)) return -1; return packet[1]; } uint8_t fingerprint_enroll (void){ uint8_t p = -1; p = verify_fun (); p = getimage_fun (); if (p == 0×00){ printf (“\n”); printf (“image_1 taken!\n”); } else { printf (“\n”); printf (“get image_1 failed!\n”); getimage_fun(); } p = img2tz_1_fun (); if (p == 0×00){ printf (“\n”); printf (“image_1 converted!\n”); } else { printf (“\n”); printf (“convert image_1 failed!\n”); } printf (“wait for verification again!\n”); delay(2000); printf (“it’s starting to verify fingerprint again \n”); p = getimage_fun (); if (p == 0×00){ printf (“\n”); printf (“image_2 taken!\n”); } else { printf (“\n”); printf (“take image_2 failed!\n”); } p = img2tz_2_fun (); if (p == 0×00){ printf (“\n”); printf (“image_2 converted!\n”); } else { printf (“\n”); printf (“convert image_2 failed!\n”); } p = regmodel_fun (); if (p == 0×00){ printf (“\n”); printf (“match image successed!\n”); } else { printf (“\n”); printf (“match image failed!\n”); } p = store_fun (2); if (p == 0×00){ printf (“\n”); printf (“store image successed!\n”); exit(0); } else { printf (“\n”); printf (“store image failed!\n”); } } void setup (){ Serial.begin (57600); printf (“fingertest\n”); } void loop () { fingerprint_enroll (); } 指纹模块识别代码: /******************** fingerprint_search.cpp ********************/ #include <core.h> #define FINGERPRINT_TIMEOUT 0xFF #define FINGERPRINT_BADPACKET 0xFE #define FINGERPRINT_ACKPACKET 0×07 uint8_t i = 0; uint8_t lc = 0; uint16_t fingerID; uint16_t score; const uint8_t Verify[] = {0xEF, 0×01, 0xFF, 0xFF, 0xFF, 0xFF, 0×01, 0×00, 0×07, 0×13, 0×00, 0×00, 0×00, 0×00, 0×00, 0x1B}; const uint8_t Getimage[] = {0xEF, 0×01, 0xFF, 0xFF, 0xFF, 0xFF, 0×01, 0×00, 0×03, 0×01, 0×00, 0×05}; const uint8_t Img2tz[] = {0xEF, 0×01, 0xFF, 0xFF, 0xFF, 0xFF, 0×01, 0×00, 0×04, 0×02, 0×01, 0×00, 0×08}; const uint8_t Search[] = {0xEF,0×01,0xFF,0xFF,0xFF,0xFF,0×01,0×00,0×08,0x1B,0×01,0×00,0×00,0×00,0xA3,0×00,0xC8}; void cmd_fun (const uint8_t *p, uint8_t len){ for (lc = 0; lc < len; lc++){ Serial.write (*p++); // delay (1); } // delay (100); } uint8_t get_reply (uint8_t packet[], uint16_t timeout){ // printf (“begin get_reply!\n”); uint8_t reply[300]; uint8_t idx; uint16_t timer = 0; idx = 0; // printf (“begin to loop in get_reply\n”); while (1){ // printf (“begin to loop in while(1)\n”); while (!(Serial.available () > 0)){ delay(1); timer++; if (timer >= timeout) return FINGERPRINT_TIMEOUT; } // printf (“begin to read something!\n”); reply[idx] = Serial.read (); printf(“reply[%x] = %02x “, idx, reply[idx]); if ((idx == 0) && (reply[0] != 0xEF)) continue; idx++; // printf (“idx = %x\n”, idx); if (idx >= 9){ if ((reply[0] != 0xEF) || (reply[1] != 0×01)) return FINGERPRINT_BADPACKET; uint16_t len = reply[7]; len <<= 8; len |= reply[8]; len -= 2; // printf (“len = %x\n”, len); if (idx <= (len + 10)) continue; packet[0] = reply[6]; // printf (“packet[0] = %x\n”, reply[6]); for (uint8_t i = 0; i < len; i++){ packet[1 + i] = reply[9 + i]; // printf (“packet[%x] = %x”,i + 1,packet[1 + i]); } return len; } } } boolean varify_fun (void){ uint8_t packet[30]; cmd_fun (Verify, 16); uint8_t len = get_reply (packet, 1000); if ((packet[1] != FINGERPRINT_ACKPACKET) && (len != 1)){ return false; } else { return true; } while (Serial.read() >= 0); } uint8_t getimage_fun (void){ uint8_t packet[30]; cmd_fun (Getimage, 12); uint8_t len = get_reply (packet, 1000); if ((packet[1] != FINGERPRINT_ACKPACKET) && (len != 1)){ return -1; } else { return packet[1]; } while (Serial.read() >= 0); } uint8_t imgtz_fun (void){ uint8_t packet[30]; cmd_fun (Img2tz, 13); uint8_t len = get_reply (packet, 1000); if ((packet[1] != FINGERPRINT_ACKPACKET) && (len != 1)){ return -1; } else { return packet[1]; } while (Serial.read() >= 0); } uint8_t search_fun (void){ uint8_t packet[30]; cmd_fun (Search, 17); uint8_t len = get_reply(packet, 1000); if ((packet[0] != FINGERPRINT_ACKPACKET) || (len < 5)){ return -1; } else { fingerID = packet[2]; fingerID <<= 8; fingerID |= packet[3]; score = packet[4]; score <<= 8; score |= packet[5]; if ((packet [1] == 0×00) && (fingerID != 0×00)){ printf (“fingerID is %d\n”, fingerID); printf (“match score is %d\n”, score); } return packet[1]; } } uint8_t getid_fun (){ uint8_t p = -1; p = varify_fun (); if (p == true){ printf (“Varify successed!\n”); } else { printf (“Varify failed!\n”); // return p; } // delay (100); p = getimage_fun (); if (p == 0×00){ printf (“Get Image successed!\n”); } else { printf (“Get Image Failed!\n”); // return p; } // delay (100); p = imgtz_fun (); if (p == 0×00){ printf (“Converted Image successed!\n”); } else { printf (“Converted Image Failed!\n”); // return p; } // delay (100); p = search_fun (); if (p == 0×00){ printf (“Search finger successed!\n”); exit(0); } else if (p == 0×09){ printf (“No finger!\n”); // return p; } else { printf (“Search finger failed\n”); // return p; } } void setup (){ Serial.begin (57600); } void loop (){ getid_fun (); }
如果在pcduino上配置好了arduino编译环境可以通过在终端输入
$gcc ***/fingerprin_enroll.cpp -larduino (***/是你存放代码的路径)
然后手指放在指纹模块上运行a.out文件就行。
没有配置环境的朋友也可以把代码内容拷贝到pcduino自带的IDE来进行编译。
手指放在模块上,运行代码首先会提示一些错误信息。不过没关系。
reply数组存储模块返回的指令。我们可以通过这些指令信息来判断模块是否对我们发送过去的指令有着正确的回应。终端显示“store image successed!”表示指纹已经成功录入。
如果成功找到指纹的话屏幕会打印出“Search finger successed!”
还有对应的ID 和分数。
实验过程可能偶尔失败一两次属于正常现象。
附上FM-206指纹模块手册:
有兴趣进一步开发的朋友可以研究研究。