指紋認証入門
私のいる高専ではICカードを使った認証をよく使っていて私もPasoriで遊んでみたりしていました。
blackuma.hatenablog.com
ただしこれにはデメリットもあり、例えば出席管理でICカードを使う場合は他の人に託してしまえるのでよく「監視しておく人」というのが設けられます。
せっかく自動化・効率化の技術を使うのに、一時的に生産性が著しく低い人間が生まれてしまうというのは私のプライドが許しませんでした。
他の認証を考えた時、生体認証しか思いつかなかった私は、Ali Express で指紋認証モジュールを約2000円で購入しました。(生体認証のデメリットは調べてない...)
ja.aliexpress.com
海外の文献は充実していたので基本的な認証動作はすぐにできました。
How to work with Fingerprint scanner using Arduino nano — Steemit
これだけでも十分使えますが、出席管理を想定して誰がいないかを表示できるようにステップ3.2を編集します。
#include <Adafruit_Fingerprint.h> #include <SoftwareSerial.h> SoftwareSerial mySerial(2, 3); Adafruit_Fingerprint finger = Adafruit_Fingerprint(&mySerial); // 127個の1の配列 int List[127]; void setup() { int i; for (i = 0; i < 127; i++ ) { List[i] = 1; } 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); if (finger.verifyPassword()) { Serial.println("Found fingerprint sensor!"); } else { Serial.println("Did not find fingerprint sensor :("); while (1) { delay(1); } } finger.getTemplateCount(); Serial.print("Sensor contains "); Serial.print(finger.templateCount); Serial.println(" templates"); Serial.println("Waiting for valid finger..."); } void loop() { if(Serial.available()>0) { switch(Serial.read()) { case 'a': //データが'a'であれば次を実行する int i; for (i = 0; i < 127; i = i + 1) { if (List[i]==1){ Serial.print(i+1);Serial.print(" "); } } break; default: break; } } getFingerprintIDez(); delay(50); } 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"); 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.fingerFastSearch(); if (p == FINGERPRINT_OK) { Serial.println("Found a print match!"); } else if (p == FINGERPRINT_PACKETRECIEVEERR) { Serial.println("Communication error"); return p; } else if (p == FINGERPRINT_NOTFOUND) { 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); List[finger.fingerID-1] = 0; return finger.fingerID; }
ステップ3.1に「from 1 to 127」とあったから127個の配列にしていますが128でも登録&認証できたのでたぶん無限に増やせます。
シリアル通信で"a"を送信してやると配列が表示されるようになっていて、認証が済んだ番号の配列は次から表示されなくなります。
番号と人との対応表を作ったうえで、127の所をすべて登録人数に置き換えてやると出席管理ツールの出来上がりです。