Created
April 19, 2014 14:20
-
-
Save lazygyu/11085745 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <LiquidCrystal.h> | |
#include "FPS_GT511C3.h" | |
#include<SoftwareSerial.h> | |
// Mode definitions | |
#define MODE_IDLE 0 | |
#define MODE_WELCOME 1 | |
#define MODE_ENROLL 2 | |
#define MODE_DEROLL 3 | |
// Buttons definition | |
#define BTN_MODE A0 | |
#define BTN_SELECT A1 | |
#define BTN_NEXT A2 | |
// Other things.. | |
#define BACKLIGHT A3 | |
#define MOTION_SENSOR A4 | |
#define DOOR 12 | |
#define IDLE_TIME 300 | |
#define MAX_ID 200 | |
// Emoticons | |
#define CH_LOCK 1 | |
#define CH_OPEN 2 | |
#define CH_PERSON 3 | |
#define CH_SELECT 4 | |
#define CH_NEXT 5 | |
// Emoticons | |
byte locked[8] = { | |
0b00000, | |
0b01110, | |
0b10001, | |
0b10001, | |
0b11111, | |
0b11111, | |
0b11111, | |
0b00000 | |
}; | |
byte opened[8] = { | |
0b01110, | |
0b10001, | |
0b10001, | |
0b00001, | |
0b11111, | |
0b11111, | |
0b11111, | |
0b00000 | |
}; | |
byte person[8] = { | |
0b01110, | |
0b11111, | |
0b01110, | |
0b00100, | |
0b01110, | |
0b11111, | |
0b11111, | |
0b11111 | |
}; | |
byte sel[8] = { | |
0b00000, | |
0b00001, | |
0b00010, | |
0b10010, | |
0b01100, | |
0b01100, | |
0b00000, | |
0b00000 | |
}; | |
byte next[8] = { | |
0b00000, | |
0b00000, | |
0b00100, | |
0b00110, | |
0b11111, | |
0b00110, | |
0b00100, | |
0b00000 | |
}; | |
// variables | |
LiquidCrystal lcd(8, 9, 4, 5, 6, 7); | |
int curMode = MODE_WELCOME; | |
int idleTimer = 0; | |
FPS_GT511C3 fps(2, 3); | |
// Utility functions | |
// open the door with emoticon | |
void openDoor(){ | |
lcd.setCursor(0,0); | |
lcd.write(CH_OPEN); | |
lcd.print(" Open.. "); | |
Serial.println("Open door"); | |
digitalWrite(DOOR, LOW); | |
delay(250); | |
digitalWrite(DOOR, HIGH); | |
lcd.setCursor(0,0); | |
lcd.write(CH_LOCK); | |
lcdprint(1, "Door opened!"); | |
delay(1000); | |
} | |
// get enrolled id | |
int getNextId(int cur){ | |
int i = 0; | |
for(i = cur+1; i < MAX_ID; i++){ | |
if( fps.CheckEnrolled(i) ) return i; | |
} | |
for(i = 0; i < cur; i++){ | |
if( fps.CheckEnrolled(i) ) return i; | |
} | |
return -1; | |
} | |
int getAvailableId(int cur){ | |
int i = 0; | |
for(i = cur + 1; i < MAX_ID; i++){ | |
if( !fps.CheckEnrolled(i) ) return i; | |
} | |
for(i = 0; i < cur; i++){ | |
if( !fps.CheckEnrolled(i) ) return i; | |
} | |
return -1; | |
} | |
void checkMotion(){ | |
if( digitalRead(MOTION_SENSOR) == HIGH ){ | |
idleTimer = IDLE_TIME; | |
} | |
} | |
void turnBacklight(bool a){ | |
if( a ) { | |
digitalWrite(BACKLIGHT, HIGH); | |
}else{ | |
digitalWrite(BACKLIGHT, LOW); | |
} | |
} | |
void lcdprint(int row, char* msg){ | |
lcd.setCursor(0, row); | |
int len = strlen(msg); | |
int i = 0; | |
lcd.print(msg); | |
for(i=len-1;i<16;i++){ | |
lcd.print(" "); | |
} | |
lcd.setCursor(len, row); | |
} | |
// main routines | |
void setup(){ | |
Serial.begin(9600); | |
Serial.println("Make emoticons"); | |
lcd.createChar(1, locked); | |
lcd.createChar(2, opened); | |
lcd.createChar(3, person); | |
lcd.createChar(4, sel); | |
lcd.createChar(5, next); | |
Serial.println("LCD initialize"); | |
lcd.begin(16, 2); | |
Serial.println("Pin mode setting"); | |
pinMode(BTN_MODE, INPUT_PULLUP); | |
pinMode(BTN_SELECT, INPUT_PULLUP); | |
pinMode(BTN_NEXT, INPUT_PULLUP); | |
pinMode(MOTION_SENSOR, INPUT); | |
pinMode(BACKLIGHT, OUTPUT); | |
pinMode(DOOR, OUTPUT); | |
delay(100); | |
Serial.println("Finger print scanner initialize"); | |
//fps.UseSerialDebug = true; | |
fps.Open(); | |
Serial.println("Ready"); | |
digitalWrite(DOOR, HIGH); | |
} | |
void enroll(){ | |
int enrollCount = 0; | |
enrollCount = fps.GetEnrollCount(); | |
lcd.setCursor(11, 0); | |
lcd.print("("); | |
lcd.print(enrollCount); | |
lcd.print(")"); | |
lcd.setCursor(0,1); | |
lcd.write(CH_SELECT); | |
lcd.print(" to start"); | |
while(true){ | |
idleTimer--; | |
if( idleTimer <= 0 ){ | |
changeMode(MODE_IDLE); | |
return; | |
} | |
if( digitalRead(BTN_MODE) == LOW ){ | |
changeMode(MODE_DEROLL); | |
delay(100); | |
return; | |
} | |
if( digitalRead(BTN_SELECT) == LOW){ | |
break; | |
} | |
checkMotion(); | |
delay(10); | |
} | |
// enrolling | |
int enrollId = -1; | |
int i; | |
bool used = true; | |
bool bret = false; | |
// find enroll id | |
lcdprint(1, "Looking slot"); | |
for(i = 0; i < 200; i++){ | |
used = fps.CheckEnrolled(i); | |
if( !used ){ | |
enrollId = i; | |
break; | |
} | |
} | |
if( enrollId == -1 ){ | |
lcdprint(1, "Slots full"); | |
delay(1000); | |
changeMode(MODE_WELCOME); | |
return; | |
} | |
fps.EnrollStart(enrollId); | |
lcdprint(1, "Put finger (1/3)"); | |
while(fps.IsPressFinger() == false){ | |
if( digitalRead(BTN_MODE) == LOW ){ | |
fps.Close(); | |
fps.Open(); | |
changeMode(MODE_DEROLL); | |
} | |
} | |
bret = fps.CaptureFinger(true); | |
if( bret == false ){ | |
lcdprint(1, "Capture fail!"); | |
delay(1000); | |
changeMode(MODE_WELCOME); | |
return; | |
} | |
lcdprint(1, "Remove finger"); | |
fps.Enroll1(); | |
while(fps.IsPressFinger() == true) delay(100); | |
lcdprint(1, "Put finger (2/3)"); | |
while(fps.IsPressFinger() == false){ | |
if( digitalRead(BTN_MODE) == LOW ){ | |
changeMode(MODE_DEROLL); | |
} | |
} | |
bret = fps.CaptureFinger(true); | |
if( bret == false ){ | |
lcdprint(1, "Capture fail!"); | |
delay(1000); | |
changeMode(MODE_WELCOME); | |
return; | |
} | |
lcdprint(1, "Remove finger"); | |
fps.Enroll2(); | |
while(fps.IsPressFinger() == true) delay(100); | |
lcdprint(1, "Put finger (3/3)"); | |
while(fps.IsPressFinger() == false){ | |
if( digitalRead(BTN_MODE) == LOW ){ | |
changeMode(MODE_DEROLL); | |
} | |
} | |
bret = fps.CaptureFinger(true); | |
if( bret == false ){ | |
lcdprint(1, "Capture fail!"); | |
delay(1000); | |
changeMode(MODE_WELCOME); | |
return; | |
} | |
lcdprint(1, "Remove finger"); | |
int iret; | |
iret = fps.Enroll3(); | |
if( iret == 0 ){ | |
lcdprint(1, "Enroll OK : "); | |
lcd.write(CH_PERSON); | |
lcd.print(enrollId); | |
}else{ | |
lcdprint(1, "Enrolling failed."); | |
} | |
delay(1000); | |
changeMode(MODE_WELCOME); | |
} | |
void changeMode(int mode){ | |
lcd.clear(); | |
if ( mode != MODE_IDLE ){ | |
idleTimer = IDLE_TIME; | |
turnBacklight(true); | |
fps.SetLED(true); | |
lcd.display(); | |
Serial.println("Idle mode"); | |
}else{ | |
idleTimer = 0; | |
turnBacklight(false); | |
fps.SetLED(false); | |
lcd.noDisplay(); | |
Serial.print("Mode change to "); | |
Serial.println(mode); | |
} | |
switch(mode){ | |
case MODE_WELCOME: | |
lcd.setCursor(0,0); | |
lcd.write(CH_LOCK); | |
lcd.print(" Welcome!"); | |
lcd.setCursor(0,1); | |
lcd.print("Put your finger"); | |
break; | |
case MODE_ENROLL: | |
lcd.setCursor(0,0); | |
lcd.write(CH_PERSON); | |
lcd.print(" ADD MODE"); | |
break; | |
case MODE_DEROLL: | |
lcd.setCursor(0,0); | |
lcd.write(CH_PERSON); | |
lcd.print(" REMOVE MODE"); | |
break; | |
} | |
curMode = mode; | |
delay(100); | |
} | |
// Idle mode process | |
void idle(){ | |
if( digitalRead(BTN_MODE) == LOW || digitalRead(MOTION_SENSOR) == HIGH){ | |
changeMode(MODE_WELCOME); | |
return; | |
} | |
if( digitalRead(BTN_SELECT) == LOW ){ | |
idleTimer = IDLE_TIME; | |
openDoor(); | |
changeMode(MODE_IDLE); | |
return; | |
} | |
delay(100); | |
} | |
// Welcome mode process | |
void welcome(){ | |
// change mode to the idle without no action while IDLE_TIME | |
idleTimer--; | |
if( idleTimer <= 0 ){ | |
changeMode(MODE_IDLE); | |
return; | |
} | |
// if the mode button pressed | |
if( digitalRead(BTN_MODE) == LOW ){ | |
changeMode(MODE_ENROLL); | |
return; | |
} | |
// if the select button pressed | |
if( digitalRead(BTN_SELECT) == LOW ){ | |
idleTimer = IDLE_TIME; | |
openDoor(); | |
changeMode(MODE_WELCOME); | |
return; | |
} | |
//if finger pressed | |
if( fps.IsPressFinger() ){ | |
fps.CaptureFinger(false); | |
int id = fps.Identify1_N(); | |
if( id < 200 ){ | |
lcd.setCursor(0,1); | |
lcd.write(CH_PERSON); | |
lcd.print(id); | |
lcd.print(" verified!"); | |
openDoor(); | |
changeMode(MODE_WELCOME); | |
return; | |
}else{ | |
idleTimer = IDLE_TIME; | |
lcdprint(1, "Who are you?"); | |
} | |
} | |
checkMotion(); | |
delay(10); | |
} | |
void deroll(){ | |
// press select button to start | |
lcdprint(1, " "); | |
lcd.setCursor(0,1); | |
lcd.write(CH_SELECT); | |
lcd.print(" to start"); | |
while(true){ | |
idleTimer--; | |
if( idleTimer <= 0 ){ | |
changeMode(MODE_IDLE); | |
return; | |
} | |
if( digitalRead(BTN_MODE) == LOW ){ | |
changeMode(MODE_WELCOME); | |
return; | |
} | |
if( digitalRead(BTN_SELECT) == LOW){ | |
break; | |
} | |
checkMotion(); | |
delay(10); | |
} | |
// if user press the button | |
// first of all, get the enrolled user count | |
int enrollCount = 0; | |
enrollCount = fps.GetEnrollCount(); | |
// this mode needs to 1 or more ids | |
if( enrollCount <= 0 ){ | |
lcdprint(1, "No user"); | |
delay(1000); | |
changeMode(MODE_WELCOME); | |
return; | |
} | |
int cur = -1; | |
cur = getNextId(cur); | |
if( cur == -1 ){ | |
lcdprint(1, "No user"); | |
delay(1000); | |
changeMode(MODE_WELCOME); | |
return; | |
} | |
lcdprint(0, " "); | |
lcd.setCursor(0,0); | |
lcd.write(CH_NEXT); | |
lcd.print(" to next"); | |
lcdprint(1, " "); | |
lcd.setCursor(0,1); | |
lcd.write(CH_SELECT); | |
lcd.print(" to remove "); | |
lcd.write(CH_PERSON); | |
lcd.print(cur); | |
while(true){ | |
if( digitalRead(BTN_NEXT) == LOW ){ | |
cur = getNextId(cur); | |
lcdprint(1, " "); | |
lcd.setCursor(0,1); | |
lcd.write(CH_SELECT); | |
lcd.print(" to remove "); | |
lcd.write(CH_PERSON); | |
lcd.print(cur); | |
}else if(digitalRead(BTN_SELECT) == LOW ){ | |
bool bret = false; | |
bret = fps.DeleteID(cur); | |
if( bret ){ | |
lcdprint(1, " "); | |
lcd.setCursor(0,1); | |
lcd.write(CH_PERSON); | |
lcd.print(cur); | |
lcd.print(" Deleted!"); | |
delay(1000); | |
changeMode(MODE_WELCOME); | |
}else{ | |
lcdprint(1, "error.."); | |
delay(1000); | |
changeMode(MODE_WELCOME); | |
} | |
}else if(digitalRead(BTN_MODE) == LOW){ | |
changeMode(MODE_WELCOME); | |
return; | |
} | |
checkMotion(); | |
delay(10); | |
} | |
changeMode(MODE_WELCOME); | |
} | |
void loop(){ | |
switch(curMode){ | |
case MODE_IDLE: | |
idle(); | |
break; | |
case MODE_WELCOME: | |
welcome(); | |
break; | |
case MODE_ENROLL: | |
enroll(); | |
break; | |
case MODE_DEROLL: | |
deroll(); | |
break; | |
} | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment