Skip to content

Instantly share code, notes, and snippets.

@lazygyu
Created April 19, 2014 14:20
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save lazygyu/11085745 to your computer and use it in GitHub Desktop.
Save lazygyu/11085745 to your computer and use it in GitHub Desktop.
#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