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 が代わりにタイプしてくれる」だけです.
実用を考えた時,セキュリティ強度は 強くはないでしょう.このテストプログラムは,パスワードを生文字列で抱き込んでいるので,バイナリレベルで解析すればすぐに生文字列が分かってしまいます.なので指紋認証器モドキです.
GT511C3.cpp
- Committer:
- tosihisa
- Date:
- 2014-01-03
- Revision:
- 3:459a4f985a45
- Parent:
- 2:34a647292050
- Child:
- 4:3dd0f98e6f09
File content as of revision 3:459a4f985a45:
#include "mbed.h" #include "GT511C3.h" #define SET_AND_SUMADD(idx,val) sendbuf[idx]=((unsigned char)(val));sum += sendbuf[idx] int GT511C3::Init(void) { baud(9600); ClearLine(); return 0; } int GT511C3::SendCommand(unsigned long Parameter,unsigned short Command) { unsigned char sendbuf[12]; unsigned short sum = 0; int idx = 0; int i; SET_AND_SUMADD(idx,0x55); idx++; SET_AND_SUMADD(idx,0xAA); idx++; SET_AND_SUMADD(idx,0x01); idx++; SET_AND_SUMADD(idx,0x00); idx++; SET_AND_SUMADD(idx,Parameter & 0xff); idx++; SET_AND_SUMADD(idx,(Parameter >> 8) & 0xff); idx++; SET_AND_SUMADD(idx,(Parameter >> 16) & 0xff); idx++; SET_AND_SUMADD(idx,(Parameter >> 24) & 0xff); idx++; SET_AND_SUMADD(idx,Command & 0xff); idx++; SET_AND_SUMADD(idx,(Command >> 8) & 0xff); idx++; sendbuf[idx] = sum & 0xff; idx++; sendbuf[idx] = (sum >> 8) & 0xff; idx++; for(i = 0;i < idx;i++){ while(!writeable()); putc(sendbuf[i]); } return 0; } int GT511C3::RecvResponse(unsigned long *Parameter,unsigned short *Response) { unsigned char buf[12]; unsigned short sum = 0; int i; *Parameter = 0; *Response = CMD_Nack; for(i = 0;i < sizeof(buf);i++){ while(!readable()); buf[i] = getc(); if(i < 9){ sum += buf[i]; } if((i == 0) && (buf[i] != 0x55)) return -1; if((i == 1) && (buf[i] != 0xAA)) return -1; } if(buf[10] != (sum & 0xff)) return -2; if(buf[11] != ((sum >> 8) & 0xff)) return -2; *Parameter = buf[7]; *Parameter = (*Parameter << 8) | buf[6]; *Parameter = (*Parameter << 8) | buf[5]; *Parameter = (*Parameter << 8) | buf[4]; *Response = buf[9]; *Response = (*Response << 8) | buf[8]; 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); } return sts; } int GT511C3::ClearLine(void) { while(readable()){ (void)getc(); } return 0; } int GT511C3::WaitPress(int press) { while(IsPress() != press); return 0; } int GT511C3::CmosLed(int onoff) { unsigned long Parameter = onoff & 1; unsigned short Response = 0; int sts = 0; sts = SendRecv(CMD_CmosLed,&Parameter,&Response); if((sts != 0) || (Response != CMD_Ack)) return -1; return 0; } int GT511C3::IsPress(void) { unsigned long Parameter = 0; unsigned short Response = 0; int sts = 0; sts = SendRecv(CMD_IsPressFinger,&Parameter,&Response); if((sts != 0) || (Response != CMD_Ack)) return 0; if(Parameter != 0) return 0; return 1; } int GT511C3::Capture(int best) { unsigned long Parameter = best; unsigned short Response = 0; int sts = 0; sts = SendRecv(CMD_CaptureFinger,&Parameter,&Response); if((sts != 0) || (Response != CMD_Ack)) return -1; return 0; } int GT511C3::Enroll_N(int N) { unsigned long Parameter = 0; unsigned short Response = 0; int sts = 0; enum Command cmd; switch(N){ default: case 1: cmd = CMD_Enroll1; break; case 2: cmd = CMD_Enroll2; break; case 3: cmd = CMD_Enroll3; break; } sts = SendRecv(cmd,&Parameter,&Response); if((sts != 0) || (Response != CMD_Ack)) return -1; return 0; } int GT511C3::Identify(void) { unsigned long Parameter = 0; unsigned short Response = 0; int sts = 0; sts = SendRecv(CMD_Identify,&Parameter,&Response); if((sts != 0) || (Response != CMD_Ack)) return -1; return Parameter; }