Fingerprint Scanner API using GT511C3 fingerprint scanner.

Dependencies:   4DGL-uLCD-SE GT511C3 SDFileSystem mbed

Fork of GT511C3test by Toshihisa T

The fingerprint scanner is designed to take attendance over a group of students. It requires a the group owner to store a preloaded list of student id numbers in a .txt file to the memory (SD card) in return of a 5 digits keypass to gain access to the database when taking attendance.

While there may exist multiple group owner and a group owner with multiple databases, each group will be uniquely identified by the 5 digits keypass. The program limits each scanner to open ONE session at a time where only one group will be able to take attendance during its session. Once a session is closed, a report of the attendance taken during the open session is generated and sent via ethernet to owner and there is no way to reopen the session again.

For the initial setup, each fingerprint database needs to be populated by the students. This set up can be done continuously during a session while taking attendance that session.

main.cpp

Committer:
yoshua0207
Date:
2015-12-01
Revision:
8:a1ba925cf903
Parent:
7:8b9ef3211cd0

File content as of revision 8:a1ba925cf903:

#include "GT511C3.hpp"
#include "uLCD_4DGL.h"
#include "SDFileSystem.h"
#include <string>


// LCD, IO
uLCD_4DGL uLCD(p28, p27, p30);
Serial debug(USBTX,USBRX);
GT511C3 finger(p9,p10);
SDFileSystem sd(p5, p6, p7, p8, "sd");

// Set these variables to 0 after each read
// KEYPAD_BOTTOM LEFT
DigitalOut is_cancelled(LED1);//10
// KEYPAD_BOTTOM_RIGHT
DigitalOut is_entered(LED2); //11

// FUNCTIONS:
void user_menu();
void open_existing_system();
void start_session();
void close_session();
void read_from_fingerprint_scanner();
void close_session();
int read_keypad(char* readable, int how_many);
void upload_to_scanner();
void download_to_memory();
void send_file_via_wifi();
int owner_database_contains(char* gid);
void wait_cancelled_or_entered();

// CONSTANT VARIABLES
const int id_size = 5;
const int group_size = 200;
const int owner_id_size = 20;
string owner_id_file = "owner_id_file.txt";
string sid_file = "sid_file.txt";

// VARIABLES
char group_id[id_size]; // group_id null >> no open session
int this_session_id[group_size];
int student_id_number[group_size];
char* from_user;

int main() {
    user_menu();
    return 0;
}

void user_menu() {
    
    uLCD.printf("***********************\n");
    uLCD.printf("* Fingerprint Scanner *\n");
    uLCD.printf("***********************\n\n");
    uLCD.printf("Welcome!\n\n");
    open_existing_system();
}

/*
 * Starts the program by asking the user which database
 * the user is going to be using for the session.
 */
void open_existing_system() {
    
    int is_done = 0;
    while (!is_done){
        
        //Ask for user input
        uLCD.printf("Enter group ID: ");
            
        // get user input >> read group id ******
        from_user = "41811";
        
        // check the input against owner data
        if (owner_database_contains(from_user)) {
            start_session();
        }
    }
}

/*
 * This method checks whether the database contains the specific group
 * that the user specified using the id
 * 
 * @param char* gid user specified string id "****" of length id_size
 * @return int 1 if true, 0 otherwise
 */
int owner_database_contains(char* gid) {
    string fileName = "/sd/"  + owner_id_file;
    const char* conv_file = fileName.c_str();
    FILE *file = fopen(conv_file, "r");
    debug.printf("Opening file %s \n",fileName);
    if (file) {
        char c;
        char* temp[id_size];
        c = fgetc(file);
        while(c != "\n")
        {
            temp.putc(c);
            c = fgetc(file);
        }
        debug.printf("temp is %s\n", temp);
        while (temp) {
            if (int(*gid) == int(*temp)) {
                fclose(file);
                return 1;
            }
            char c;
            char temp[id_size];
            c = fgetc(file);
            while(c ~= "\n")
            {
                temp.putc(c);
                c = fgetc(file);
            }
        }

    }
    fclose(file);
    return -1;
}

int sid_file_contains(char* sid) {
    string fileName = "/sd/"  + string(group_id) + "/" + sid_file;
    const char* conv_file = fileName.c_str();
    FILE *file = fopen(conv_file, "r");
    debug.printf("Opening file %s\n",fileName);
    if (file) {
        char temp[15];
        file.getline(temp, 15);
        while(temp)
        {
            digitC = strtok(temp, " ");
            if(strcmp(digitC[1],sid))
            {
                fclose(file);
                return (int)digitC[0];
            }
            file.getline(temp, 15);
        }
    }
    fclose(file);
    return -1;
}

/*
 * Start session is called once a group database has been identified
 * and loaded to the fingerprint scanner. Start session will allow
 * users to start scanning fingerprints for the current session.
 *
 * @param: none
 * @return: none
 */
void start_session() {
    
    // upload the specified database to the fingerprint
    upload_to_scanner();

    // display options to user via LCD
    uLCD.printf("Session <session_name> is open.\n");
    uLCD.printf("Press (1) Scan fingerprint!\n\n");
    uLCD.printf("Press (2) Add fingerprint!\n\n");
    uLCD.printf("Press (11) to close session\n");
    uLCD.printf("Press (10) to go back\n");
    
    int is_closed = 0;
    while (!is_closed) {
        
//        int digit = get_digit_keypad();
        int digit = 2;
        if (digit = 1) {
            // scan the fingerprint
            read_from_fingerprint_scanner();
        }
        
        if(digit = 2){
            // add new fingerprints
            add_new_fingerprint();
            
        } 
        
        // read whether is_closed is updated
        if (digit = 10) {
                
            // read the keypad for group id and put it in input_group_id
            char input_group_id[id_size];
            read_keypad(input_group_id, id_size);
            
            if (atoi(input_group_id) - atoi(group_id) == 0) {
                is_closed = 1;
            } else {
                uLCD.printf("Group ID does not match!\nUnable to close session.\n");
            }
        }
    }
    close_session();
}

/*
 * Compare whether the currently scanned fingerprint is contained
 * in the existing database. Set the this_session_id data structure
 * to 1 if yes to notify that the person has signed in for this
 * session.
 *
 * @param none
 * @return none
 */
void read_from_fingerprint_scanner() {
    int FID = -1;
    
    //Talk to the fingerprint and get an ID back 
    uLCD.printf("Press finger for Identify\n");
    finger.WaitPress(1);
    if(finger.Capture(1) != 0)
        continue;
    FID = finger.Identify();
    uLCD.printf("ID = %d\n",ID); 
    uLCD.printf("Remove finger\n");
    finger.WaitPress(0);
    
    if (FID >= 0 & FID < group_size) {
        this_session_id[FID] = 1;
        
        uLCD.printf("Welcome, %s!", STUDENT_NAME);
        // make this
    } else {
        uLCD.printf("Sorry, ID failed!");
    }
}
/*
 * Add new fingerprint into the existing class session
 *
 * @param none
 * @return none
 */
void add_new_fingerprint() {
    
    while(finger.CheckEnrolled(EnrollID)==0) {
        EnrollID++;
    }
    uLCD.printf("Insert student ID :\n");
    temp = "903091568";
    debug.printf("%s\n", temp);
    EnrollID = sid_file_contains(temp);
    finger.Enroll(EnrollID, progress);

}


/*
 * Close session is called when a group database
 * has been uploaded to the fingerprint scanner
 * 
 */
void close_session() {
    download_to_memory();
    send_file_via_wifi();
    // TODO: put changed data in mbed to the micro sd and other housekeeping stuff
    // Reset the id to be none
    group_id = 0;
}

/* Reads from the keypad id_size digits of input
 * until the user presses the enter button.
 * If the user presses the cancel button, discard the
 * digits read and return.
 * @param char* readable the pointer to put the input read from user
 * @return int 0 if no change made to the parameter, 1 otherwise
 */
int read_keypad(char* readable, int how_many) {
    
    char from_user[how_many];

    int index = 0;
    while (1) {
        if (index < how_many) {
            int keypad = get_digit_keypad();
            
            if (keypad = 10) {
                return 0;
            } else if (keypad = 11) {
                from_user = readable;
                return 1;
            } else {
                from_user[index] = keypad;
            }
            
            uLCD.printf("%d\n",from_user[index]);
            uLCD.printf(" * \n");
        } else if (index == how_many) {
            index--;        
        }
        index++;
    }
}

int get_digit_keypad() {
    int key_code=0;
    int i=0;
    int value=keypad.read(0x00);
    value +=keypad.read(0x01)<<8;
    
    i=0;
    // puts key number out to LEDs for demo
    for (i=0; i<12; i++) {
        if (((value>>i)&0x01)==1) key_code=i+1;
    }
    
    if 
    
    uLCD.printf("Key pressed is: %d",key_code); // TODO: DEBUG ONLY
    return key_code;  
}

void upload_to_scanner() 
{
     if(finger.DeleteAll == 0)
     {
        debug.printf("All fingerprints deleted");
     }
     EnrollID = 1;
//     group_id = "4180";
     directory = "/sd/" + group_id ;
     char ID[3];
     sprintf(ID, "%d\n",EnrollID);
     fileName = directory + "/" + ID + ".dat";
     debug.printf("Attempt to find file %s", fileName);
     const char* conv_file = fileName.c_str();
     FILE *templateFile = fopen(conv_file, "r");
     while(templateFile != NULL)
     {
        if(finger.SetTemplate(templateFile, EnrollID, 0 ) == 0)
        {
            EnrollID++;  
            fclose(templateFile); 
        }
        char ID[3];
        sprintf(ID, "%d\n",EnrollID);
        fileName = directory + "/" + ID + ".dat";
        const char* conv_file = fileName.c_str();
        FILE *templateFile = fopen(conv_file, "r");
     }
}

void download_to_memory() 
{
    EnrollID = 1;
    directory = "/sd/" + group_id ;
    const char* conv_dir = directory.c_str();
    debug.printf("%s", directory);
    mkdir(conv_dir, 0777);
    while(finger.GetTemplate(EnrollID)==0)
    {
        finger.RecvData(data, 498);
        char ID[3];
        sprintf(ID, "%d\n",EnrollID);
        fileName = directory + "/" + ID + ".dat";
        debug.printf("Attempt to write to file %s", fileName);
        const char* conv_file = fileName.c_str();
        FILE *templateFile = fopen(conv_file, "w");
        if(templateFile == NULL) {
                debug.printf("Could not open file for write\n");
            }
        fprintf(templateFile, data, EnrollID);
        fclose(templateFile); 
        EnrollID++;
    }
}

void send_file_via_wifi() {
    // TODO: Yo
    // make file

    for (int i = 0; i < group_size; i++) {
        if (this_session_id[i]) {
            // append the data to the file to be exported
        }
    }
    // send data
}
void getNewLine(File *fp, char *buf, size_t bufsize)
{
    char c;
    size_t receivedChars = 0;
    for(;;)
    {
        c = fgetc(fp);
        if (c == '\r' || c == '\n')
            break;
        buf.putc(c);
    }
    return buf;
}