Test Program of GT-511C3 / GT-511C31 Fingerprint reader module.
GT-511-C31 指紋スキャンモジュールを mbed で動かしてみる
年末に大阪日本橋にあるデジットに行くと,指紋スキャンモジュールを販売していました.
値段は少しお高め(三千円〜八千円超え)ですが,使えると色々と応用が出来そうなので,GT-511-C31を購入して mbed で動かしてみました.
使い方とか
このページにある GT511C3test をそのままプログラムとしてインポートして下さい.
クラスライブラリ化していますので,クラスライブラリを使う場合は,以下からインポートして下さい. ドキュメントが追いついていなくてすみません.テストプログラムを参考にして頂けたらと思います...
Import libraryGT511C3
Class library of fingerprint reader module "GT-511C3 / GT-511C31"
テストプログラムでは,mbed と p28,p27 でシリアル通信します.Vin と GND はそのまま mbed の 3.3V と GND が使えます.
finger.Enroll(11,progress); この関数の呼び出しで,ID番号11番に指紋を登録します.同じ指紋を3回あてると登録できます.
その後,finger.Identify(); の呼び出しで指紋があたっていれば認識して,同じ指紋であればID番号11番を返すはずです. それ以外の指紋があたっていると -1 を返します.
注意点として,指紋の登録あるいは認識をする場合は,必ず CmosLed を点灯させて下さい.点灯させると指紋検出面が青く光ります.これが消灯していると,指紋の検出が出来ないようです.
雑感
指紋の認識は,感覚的にですが1秒ほどで認識します.10本の指それぞれで色々な角度であててみましたが,誤認識無く,登録した指紋があたるとIDが返ります.説明書によると,「違う指紋を同じ指紋として誤る確率:0.001%未満」と言うことなので,10万回に1回の確率で間違えそうですが,実用レベルだと感じます.
うまく使うと,mbed で生体認証チックな事ができそうですね.
指紋認証器モドキ(自動ログインのデモ)
これは,青mbed ではなく,lpclcd と指紋スキャンモジュールを組み合わせて,指紋認証器モドキを作って Mac に自動ログインするプロトタイプです.
lpclcd は mbed と同じように USBKeyboard の様に振る舞わせることが出来ますので,登録された指紋があたると,lpclcd で USBKeyboard::printf("パスワード\n"); を実行してあたかもパスワードがUSB Keyboard で打ち込まれたかの様に動作させています.
この指紋認証器モドキのメリットは,PCから見ればUSBキーボードの様に見えるので,特別なドライバを必要としないことです.要するに「登録された指紋があたれば事前にプログラムされた文字列を lpclcd が代わりにタイプしてくれる」だけです.
実用を考えた時,セキュリティ強度は 強くはないでしょう.このテストプログラムは,パスワードを生文字列で抱き込んでいるので,バイナリレベルで解析すればすぐに生文字列が分かってしまいます.なので指紋認証器モドキです.
Revision 4:3dd0f98e6f09, committed 2014-01-03
- Comitter:
- tosihisa
- Date:
- Fri Jan 03 14:12:18 2014 +0000
- Parent:
- 3:459a4f985a45
- Child:
- 5:d3ebe6d1ed92
- Commit message:
- Add LICENSE.;
Changed in this revision
--- a/GT511C3.cpp Fri Jan 03 12:56:03 2014 +0000 +++ b/GT511C3.cpp Fri Jan 03 14:12:18 2014 +0000 @@ -1,3 +1,32 @@ +/** + * @section LICENSE + * + * Copyright (c) 2013 @tosihisa, MIT License + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software + * and associated documentation files (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, publish, distribute, + * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or + * substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING + * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * @section DESCRIPTION + * + * Fingerprint reader module "GT-511C3" class. + * + * http://www.adh-tech.com.tw/?22,gt-511c3-gt-511c31 + * http://www.adh-tech.com.tw/files/GT-511C3_datasheet_V1%201_20131127[1].pdf + * https://www.sparkfun.com/products/11792 + * https://github.com/sparkfun/Fingerprint_Scanner-TTL/ + */ #include "mbed.h" #include "GT511C3.h" @@ -40,6 +69,7 @@ int GT511C3::RecvResponse(unsigned long *Parameter,unsigned short *Response) { + const unsigned char fixedbuf[4] = { 0x55,0xAA,0x01,0x00 }; unsigned char buf[12]; unsigned short sum = 0; int i; @@ -53,10 +83,11 @@ if(i < 9){ sum += buf[i]; } - if((i == 0) && (buf[i] != 0x55)) - return -1; - if((i == 1) && (buf[i] != 0xAA)) - return -1; + if(i < 4){ + if(buf[i] != fixedbuf[i]){ + return -1; + } + } } if(buf[10] != (sum & 0xff)) return -2; @@ -74,12 +105,43 @@ return 0; } +int GT511C3::RecvData(unsigned char *data,unsigned long size) +{ + const unsigned char fixedbuf[4] = { 0x5A,0xA5,0x01,0x00 }; + unsigned short sum = 0; + int i; + + for(i = 0;i < size;i++){ + while(!readable()); + *(data + i) = getc(); + if(i < (size-2)){ + sum += *(data + i); + } + if(i < 4){ + if(*(data + i) != fixedbuf[i]){ + return -1; + } + } + } + if(*(data + size - 2) != (sum & 0xff)) + return -2; + if(*(data + size - 1) != ((sum >> 8) & 0xff)) + return -2; + return 0; +} + int GT511C3::SendRecv(unsigned short Command,unsigned long *Parameter,unsigned short *Response) { int sts; - sts = SendCommand(*Parameter,Command); - if(sts == 0){ - sts = RecvResponse(Parameter,Response); + if((sts = SendCommand(*Parameter,Command)) == 0){ + *Parameter = 0; + if((sts = RecvResponse(Parameter,Response)) != 0){ + *Response = CMD_Nack; + *Parameter = NACK_IO_ERR; + } + } + if(*Response == CMD_Nack){ + LastError = *Parameter; } return sts; } @@ -92,6 +154,28 @@ return 0; } +int GT511C3::Open(void) +{ + unsigned long Parameter = 1; + unsigned short Response = 0; + unsigned char buf[4+sizeof(FirmwareVersion)+sizeof(IsoAreaMaxSize)+sizeof(DeviceSerialNumber)+2]; + int sts = 0; + + if((sts = Init()) != 0) + return -1; + + sts = SendRecv(CMD_Open,&Parameter,&Response); + if((sts != 0) || (Response != CMD_Ack)){ + return -1; + } + if((sts = RecvData(buf,sizeof(buf))) == 0){ + memcpy(&FirmwareVersion,&buf[4+0],sizeof(FirmwareVersion)); + memcpy(&IsoAreaMaxSize,&buf[4+sizeof(FirmwareVersion)],sizeof(IsoAreaMaxSize)); + memcpy(DeviceSerialNumber,&buf[4+sizeof(FirmwareVersion)+sizeof(IsoAreaMaxSize)],sizeof(DeviceSerialNumber)); + } + return sts; +} + int GT511C3::WaitPress(int press) { while(IsPress() != press); @@ -105,8 +189,9 @@ int sts = 0; sts = SendRecv(CMD_CmosLed,&Parameter,&Response); - if((sts != 0) || (Response != CMD_Ack)) + if((sts != 0) || (Response != CMD_Ack)){ return -1; + } return 0; } @@ -165,3 +250,4 @@ return -1; return Parameter; } +
--- a/GT511C3.h Fri Jan 03 12:56:03 2014 +0000 +++ b/GT511C3.h Fri Jan 03 14:12:18 2014 +0000 @@ -1,4 +1,35 @@ - +/** + * @section LICENSE + * + * Copyright (c) 2013 @tosihisa, MIT License + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software + * and associated documentation files (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, publish, distribute, + * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or + * substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING + * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * @section DESCRIPTION + * + * Fingerprint reader module "GT-511C3" class. + * + * http://www.adh-tech.com.tw/?22,gt-511c3-gt-511c31 + * http://www.adh-tech.com.tw/files/GT-511C3_datasheet_V1%201_20131127[1].pdf + * https://www.sparkfun.com/products/11792 + * https://github.com/sparkfun/Fingerprint_Scanner-TTL/ + * http://blog.digit-parts.com/archives/51894096.html + */ +#ifndef __GT511C3_H +#define __GT511C3_H #include "mbed.h" class GT511C3 : public Serial { @@ -55,13 +86,21 @@ NACK_CAPTURE_CANCELED = 0x1010, // NACK_CAPTURE_CANCELED 0x1010 Obsolete, The capturing is canceled NACK_INVALID_PARAM = 0x1011, // NACK_INVALID_PARAM 0x1011 Invalid parameter NACK_FINGER_IS_NOT_PRESSED = 0x1012, // NACK_FINGER_IS_NOT_PRESSED 0x1012 Finger is not pressed + NACK_IO_ERR = 0xF000, // ORIGINAL ERROR CODE. Serial line error. }; - GT511C3(PinName _tx, PinName _rx) : Serial(_tx,_rx){} + unsigned long LastError; + unsigned long FirmwareVersion; + unsigned long IsoAreaMaxSize; + unsigned char DeviceSerialNumber[16]; + + GT511C3(PinName _tx, PinName _rx) : Serial(_tx,_rx) , LastError(0) {} int Init(void); int SendCommand(unsigned long Parameter,unsigned short Command); int RecvResponse(unsigned long *Parameter,unsigned short *Response); + int RecvData(unsigned char *data,unsigned long size); int SendRecv(unsigned short Command,unsigned long *Parameter,unsigned short *Response); int ClearLine(void); + int Open(void); int WaitPress(int press); int CmosLed(int onoff); int IsPress(void); @@ -69,3 +108,5 @@ int Enroll_N(int N); int Identify(void); }; + +#endif //__GT511C3_H
--- a/main.cpp Fri Jan 03 12:56:03 2014 +0000 +++ b/main.cpp Fri Jan 03 14:12:18 2014 +0000 @@ -72,22 +72,26 @@ } int main() { - unsigned long Parameter; - unsigned short Response; int sts = 0; - int count = 0; - int ispress; - int ID; + int ispress = 0; + int ID = 0; debug.format(8,Serial::None,1); debug.baud(115200); - debug.printf("Init\n"); - finger.Init(); debug.printf("Open\n"); - Parameter = 0; - sts = finger.SendRecv(GT511C3::CMD_Open,&Parameter,&Response); - debug.printf("sts = %d,Response=0x%04x\n",sts,Response); + sts = finger.Open(); + debug.printf("sts = %d\n",sts); + if(sts == 0){ + int i; + debug.printf("FirmwareVersion = %lx\n",finger.FirmwareVersion); + debug.printf("IsoAreaMaxSize = %ld\n",finger.IsoAreaMaxSize); + debug.printf("DeviceSerialNumber = "); + for(i = 0; i < sizeof(finger.DeviceSerialNumber);i++){ + debug.printf("%02X",finger.DeviceSerialNumber[i]); + } + debug.printf("\n"); + } if(1){ Enroll(); @@ -103,12 +107,5 @@ ID = finger.Identify(); debug.printf("ID = %d\n",ID); } -#if 0 - myled = 1; - wait(0.5); - myled = 0; - wait(0.5); -#endif - count++; } }