GT-511C3 제품의 재고가 없어서 Grove FingerSensor를 사용하였습니다.
* 키패드 비밀번호 입력 >> 지문인식 등록 >> 지문 확인 >> 열림 순으로 동작합니다.
지문 등록 >> 비밀번호 입력 >> 지문인식 입력 >> 열림 순으로 동작시키고 싶습니다.
-----------------------------------------------------------------------------------------------------------------------
#include <Keypad.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <Servo.h>
#include <Adafruit_Fingerprint.h>
LiquidCrystal_I2C lcd(0x27, 16, 2);
Servo myservo;
SoftwareSerial mySerial(12, 13);
char secretCode[4] = {'1', '1', '1', '1'};
char input[4];
char key;
int wrong = 0;
int i = 0;
int j = 0;
int pos = 90;
int a = 0;
int b = 0;
int judge_finger = 0; // 각각 비번과 지문이 일치할 때, 1의 값을 반환함.
const byte rows = 4;
const byte cols = 4;
boolean c = false;
char keys[rows][cols] =
{
{'1', '2', '3', 'A'},
{'4', '5', '6', 'B'},
{'7', '8', '9', 'C'},
{'*', '0', '#', 'D'}
};
byte rowPins[rows] = {A0, A1, A2, A3};
byte colPins[cols] = {5, 4, 3, 2};
Keypad keypad = Keypad(makeKeymap(keys), rowPins, colPins, rows, cols);
void input_key();
void password();
void password_check();
Adafruit_Fingerprint finger = Adafruit_Fingerprint(&mySerial);
// 지문 센서 사용을 위한 객체선언
uint8_t id; // 지문을 구분하는 아이디(숫자 1~127)
//=========================================================
void setup()
{
Serial.begin(9600);
while (!Serial);
lcd.begin();
myservo.attach(10);
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); }
}
finger.getTemplateCount();
Serial.print("Sensor contains ");
Serial.print(finger.templateCount);
Serial.println(" templates");
Serial.println("Waiting for valid finger...");
}
void loop()
{
int stat = 0, count = 0;
while(a == 0)//비밀번호가 일치하지 않을경우
{
input_key(); // Password Input Mode
password(); // Confirm Password
password_check(); // Display current state
if(count >= 5){
Serial.println("비밀번호 5회 이상 실패!");
break;
}
count++;
}
/*if(count >= 5){ // 비밀번호를 5회 이상 실패시 뒤의 과정 생략 후, 맨 처음으로
count = 0;
stat = 1;
} else count = 0; // 지문 인식을 위해 카운트 초기화 */
if(keypad.getKey() == '#'){ // 입력한 키패드가 #이면 지문 등록 모드로 진입
id = readnumber(); // 1~127 ID에 지문을 등록
// 지문 등록 모드시 지문 등록을 완료할 때까지 대기상태로 들어감.
Serial.print("Enrolling ID #");
Serial.println(id);
while (! getFingerprintEnroll() ); // 지문 등록
}
if (id == 0) {// ID #0 not allowed, try again!
return;
}
while (b == 0)//지문이 일치하지 않을 경우 일치할 때까지 반복.
{
if(stat == 1){
break;
}
int judge = 0;
getFingerprintIDez(); // 인식이 실패할 경우 -1을 반환함
delay(50);
if(judge == -1){
count++;
Serial.println("지문이 일치하지 않습니다.");
} else{
b = 1;
break;
}
if(count >= 5){
Serial.println("지문인식 5회 이상 실패!");
break;
}
}
/*if(count >= 5){ // 지문을 5회 이상 실패시 뒤의 과정 생략 후, 맨 처음으로.
count = 0;
continue;
} else count = 0; // 다음 작업을 위해 초기화 */
if(a == 1 && b == 1){ // 비밀번호와 지문이 일치한다면
lcd.clear();
lcd.setCursor(0, 0);
//pinMode(10, OUTPUT);
myservo.write(180); //열림
lcd.print("perfect complete");
delay(2000);
if (keypad.getKey() == '*')// '*'을 누르면 잠근다.(getkey는 한 글자만 입력받음)
{
a = 0; // Clear Flag
b = 0; // Clear Flag
lcd.clear();
lcd.setCursor(0, 0);
myservo.write(90); //잠김
lcd.print(" Lock ON");
delay(2000);
}
}
}
//=========================================================
void input_key()
{
lcd.clear();
lcd.setCursor(0, 0);
lcd.print(" Password");
for (i = 0; i < 4; i++)
{
key = keypad.waitForKey();
input[i] = key;
lcd.setCursor(i + 6, 1);
lcd.print("*");
Serial.print(input[i], DEC);
Serial.print("*");
if (i == 3)
{
Serial.println("");
}
}
}
//=========================================================
void password()
{
wrong = 0;
for (j = 0; j < 4; j++)
{
if (secretCode[j] == input[j])
{
}
else if (secretCode[j] != input[j])
{
wrong += 1;
}
}
}//input배열에 입력한 숫자가 설정한 비밀번호와 같으면 wrong = 0, 아니면 1~4의 값을 가짐
//=========================================================
void password_check()
{
if (wrong == 0) // 입력한 숫자가 비밀번호와 같을 때
{
Serial.println("correct");
lcd.clear();
lcd.setCursor(0, 0);
lcd.print(" PASS");
delay(2000);
a = 1;
lcd.clear();
}// a = 1
else if (wrong != 0) //입력한 숫자가 비밀번호와 같지 않을 때
{
Serial.println("wrong");
lcd.clear();
lcd.setCursor(0, 0);
lcd.print(" wrong");
delay(2000);
a = 0;
lcd.clear();
wrong = 0;
}//a = 0
}
//=========================================================
int getFingerprintIDez() { // -1를 반환하면 인식 실패, 그 외에는 ID를 반환
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;
}
//=========================================================
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;
}
//=========================================================
uint8_t readnumber(void) { // 1~127 번호 등록을 위한 함수.
uint8_t num = 0;
while (num == 0) {
while (! Serial.available());
num = Serial.parseInt(); // 시리얼 모니터에 정수 입력
}
return num;
}
//=========================================================
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;
}
}
|