Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of FINAL_PROJECT_4180 by
Revision 2:1b1c0502bb08, committed 2016-04-25
- Comitter:
- nyengele
- Date:
- Mon Apr 25 00:36:32 2016 +0000
- Parent:
- 1:0e5e9821d89d
- Child:
- 3:83415d375d36
- Commit message:
- fingerprint scanner done!
Changed in this revision
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/FPScanner.cpp Mon Apr 25 00:36:32 2016 +0000
@@ -0,0 +1,601 @@
+/*
+ FPScanner.h v1.0 - Library for controlling the GT-511C3 Finger Print Scanner (FPS)
+ Created by Josh Hawley, July 23rd 2013
+ Licensed for non-commercial use, must include this license message
+ basically, Feel free to hack away at it, but just give me credit for my work =)
+ TLDR; Wil Wheaton's Law
+*/
+
+#include "FPScanner.h"
+
+
+// returns the 12 bytes of the generated command packet
+// remember to call delete on the returned array
+byte* Command_Packet::GetPacketBytes()
+{
+ byte* packetbytes= new byte[12];
+
+ // update command before calculating checksum (important!)
+ word cmd = Command;
+ command[0] = GetLowByte(cmd);
+ command[1] = GetHighByte(cmd);
+
+ word checksum = _CalculateChecksum();
+
+ packetbytes[0] = COMMAND_START_CODE_1;
+ packetbytes[1] = COMMAND_START_CODE_2;
+ packetbytes[2] = COMMAND_DEVICE_ID_1;
+ packetbytes[3] = COMMAND_DEVICE_ID_2;
+ packetbytes[4] = Parameter[0];
+ packetbytes[5] = Parameter[1];
+ packetbytes[6] = Parameter[2];
+ packetbytes[7] = Parameter[3];
+ packetbytes[8] = command[0];
+ packetbytes[9] = command[1];
+ packetbytes[10] = GetLowByte(checksum);
+ packetbytes[11] = GetHighByte(checksum);
+
+ return packetbytes;
+}
+
+// Converts the int to bytes and puts them into the paramter array
+void Command_Packet::ParameterFromInt(int i)
+{
+ Parameter[0] = (i & 0x000000ff);
+ Parameter[1] = (i & 0x0000ff00) >> 8;
+ Parameter[2] = (i & 0x00ff0000) >> 16;
+ Parameter[3] = (i & 0xff000000) >> 24;
+}
+
+// Returns the high byte from a word
+byte Command_Packet::GetHighByte(word w)
+{
+ return (byte)(w>>8)&0x00FF;
+}
+
+// Returns the low byte from a word
+byte Command_Packet::GetLowByte(word w)
+{
+ return (byte)w&0x00FF;
+}
+
+word Command_Packet::_CalculateChecksum()
+{
+ word w = 0;
+ w += COMMAND_START_CODE_1;
+ w += COMMAND_START_CODE_2;
+ w += COMMAND_DEVICE_ID_1;
+ w += COMMAND_DEVICE_ID_2;
+ w += Parameter[0];
+ w += Parameter[1];
+ w += Parameter[2];
+ w += Parameter[3];
+ w += command[0];
+ w += command[1];
+
+ return w;
+}
+
+Command_Packet::Command_Packet()
+{
+};
+
+// creates and parses a response packet from the finger print scanner
+Response_Packet::Response_Packet(byte* buffer)
+{
+ // CheckParsing(buffer[0], COMMAND_START_CODE_1, COMMAND_START_CODE_1);
+ // CheckParsing(buffer[1], COMMAND_START_CODE_2, COMMAND_START_CODE_2);
+ // CheckParsing(buffer[2], COMMAND_DEVICE_ID_1, COMMAND_DEVICE_ID_1);
+ // CheckParsing(buffer[3], COMMAND_DEVICE_ID_2, COMMAND_DEVICE_ID_2);
+ // CheckParsing(buffer[8], 0x30, 0x31);
+ if (buffer[8] == 0x30) ACK = true; else ACK = false;
+ // CheckParsing(buffer[9], 0x00, 0x00);
+
+ word checksum = CalculateChecksum(buffer, 10);
+ byte checksum_low = GetLowByte(checksum);
+ byte checksum_high = GetHighByte(checksum);
+ // CheckParsing(buffer[10], checksum_low, checksum_low);
+ // CheckParsing(buffer[11], checksum_high, checksum_high);
+
+ Error = ErrorCodes::ParseFromBytes(buffer[5], buffer[4]);
+
+ ParameterBytes[0] = buffer[4];
+ ParameterBytes[1] = buffer[5];
+ ParameterBytes[2] = buffer[6];
+ ParameterBytes[3] = buffer[7];
+ ResponseBytes[0]=buffer[8];
+ ResponseBytes[1]=buffer[9];
+ for (int i=0; i < 12; i++)
+ {
+ RawBytes[i]=buffer[i];
+ }
+}
+
+// parses bytes into one of the possible errors from the finger print scanner
+Response_Packet::ErrorCodes::Errors_Enum Response_Packet::ErrorCodes::ParseFromBytes(byte high, byte low)
+{
+ Errors_Enum e = INVALID;
+ if (high == 0x00)
+ {
+ }
+ if (high == 0x01)
+ {
+ switch(low)
+ {
+ case 0x00: e = NO_ERROR; break;
+ case 0x01: e = NACK_TIMEOUT; break;
+ case 0x02: e = NACK_INVALID_BAUDRATE; break;
+ case 0x03: e = NACK_INVALID_POS; break;
+ case 0x04: e = NACK_IS_NOT_USED; break;
+ case 0x05: e = NACK_IS_ALREADY_USED; break;
+ case 0x06: e = NACK_COMM_ERR; break;
+ case 0x07: e = NACK_VERIFY_FAILED; break;
+ case 0x08: e = NACK_IDENTIFY_FAILED; break;
+ case 0x09: e = NACK_DB_IS_FULL; break;
+ case 0x0A: e = NACK_DB_IS_EMPTY; break;
+ case 0x0B: e = NACK_TURN_ERR; break;
+ case 0x0C: e = NACK_BAD_FINGER; break;
+ case 0x0D: e = NACK_ENROLL_FAILED; break;
+ case 0x0E: e = NACK_IS_NOT_SUPPORTED; break;
+ case 0x0F: e = NACK_DEV_ERR; break;
+ case 0x10: e = NACK_CAPTURE_CANCELED; break;
+ case 0x11: e = NACK_INVALID_PARAM; break;
+ case 0x12: e = NACK_FINGER_IS_NOT_PRESSED; break;
+ }
+ }
+ return e;
+}
+
+// Gets an int from the parameter bytes
+int Response_Packet::IntFromParameter()
+{
+ int retval = 0;
+ retval = (retval << 8) + ParameterBytes[3];
+ retval = (retval << 8) + ParameterBytes[2];
+ retval = (retval << 8) + ParameterBytes[1];
+ retval = (retval << 8) + ParameterBytes[0];
+ return retval;
+}
+
+// calculates the checksum from the bytes in the packet
+word Response_Packet::CalculateChecksum(byte* buffer, int length)
+{
+ word checksum = 0;
+ for (int i=0; i<length; i++)
+ {
+ checksum +=buffer[i];
+ }
+ return checksum;
+}
+
+// Returns the high byte from a word
+byte Response_Packet::GetHighByte(word w)
+{
+ return (byte)(w>>8)&0x00FF;
+}
+
+// Returns the low byte from a word
+byte Response_Packet::GetLowByte(word w)
+{
+ return (byte)w&0x00FF;
+}
+
+// checks to see if the byte is the proper value, and logs it to the serial channel if not
+bool Response_Packet::CheckParsing(byte b, byte propervalue, byte alternatevalue)
+{
+ bool retval = (b == propervalue) || (b == alternatevalue);
+ return retval;
+
+}
+
+
+// Creates a new object to interface with the fingerprint scanner
+FPScanner::FPScanner(PinName tx, PinName rx)
+ : _serial(tx,rx)
+{
+ pin_TX = tx;
+ pin_RX = rx;
+ _serial.baud(9600);
+};
+
+
+//Initialises the device and gets ready for commands
+void FPScanner::Open()
+{
+ Command_Packet* cp = new Command_Packet();
+ cp->Command = Command_Packet::Commands::Open;
+ cp->Parameter[0] = 0x00;
+ cp->Parameter[1] = 0x00;
+ cp->Parameter[2] = 0x00;
+ cp->Parameter[3] = 0x00;
+ byte* packetbytes = cp->GetPacketBytes();
+ SendCommand(packetbytes, 12);
+ Response_Packet* rp = GetResponse();
+ delete cp;
+ delete rp;
+ delete [] packetbytes;
+}
+
+// According to the DataSheet, this does nothing...
+// Implemented it for completeness.
+void FPScanner::Close()
+{
+ Command_Packet* cp = new Command_Packet();
+ cp->Command = Command_Packet::Commands::Close;
+ cp->Parameter[0] = 0x00;
+ cp->Parameter[1] = 0x00;
+ cp->Parameter[2] = 0x00;
+ cp->Parameter[3] = 0x00;
+ byte* packetbytes = cp->GetPacketBytes();
+ SendCommand(packetbytes, 12);
+ Response_Packet* rp = GetResponse();
+ delete cp;
+ delete rp;
+ delete [] packetbytes;
+};
+
+// Turns on or off the LED backlight
+// Parameter: true turns on the backlight, false turns it off
+// Returns: True if successful, false if not
+bool FPScanner::SetLED(bool on)
+{
+ Command_Packet* cp = new Command_Packet();
+ cp->Command = Command_Packet::Commands::CmosLed;
+ if (on)
+ {
+ cp->Parameter[0] = 0x01;
+ }
+ else
+ {
+ cp->Parameter[0] = 0x00;
+ }
+ cp->Parameter[1] = 0x00;
+ cp->Parameter[2] = 0x00;
+ cp->Parameter[3] = 0x00;
+ byte* packetbytes = cp->GetPacketBytes();
+ SendCommand(packetbytes, 12);
+ Response_Packet* rp = GetResponse();
+ bool retval = true;
+ if (rp->ACK == false) retval = false;
+ delete rp;
+ delete [] packetbytes;
+ delete cp;
+ return retval;
+};
+
+// Changes the baud rate of the connection
+// Parameter: 9600, 19200, 38400, 57600, 115200
+// Returns: True if success, false if invalid baud
+// NOTE: Untested (don't have a logic level changer and a voltage divider is too slow)
+bool FPScanner::ChangeBaudRate(int baud)
+{
+ if ((baud == 9600) || (baud == 19200) || (baud == 38400) || (baud == 57600) || (baud == 115200))
+ {
+
+ Command_Packet* cp = new Command_Packet();
+ cp->Command = Command_Packet::Commands::Open;
+ cp->ParameterFromInt(baud);
+ byte* packetbytes = cp->GetPacketBytes();
+ SendCommand(packetbytes, 12);
+ Response_Packet* rp = GetResponse();
+ bool retval = rp->ACK;
+ if (retval)
+ {
+ _serial.baud(baud);
+ }
+ delete cp;
+ delete rp;
+ delete [] packetbytes;
+ return retval;
+ }
+ return false;
+}
+
+// Gets the number of enrolled fingerprints
+// Return: The total number of enrolled fingerprints
+int FPScanner::GetEnrollCount()
+{
+ Command_Packet* cp = new Command_Packet();
+ cp->Command = Command_Packet::Commands::GetEnrollCount;
+ cp->Parameter[0] = 0x00;
+ cp->Parameter[1] = 0x00;
+ cp->Parameter[2] = 0x00;
+ cp->Parameter[3] = 0x00;
+ byte* packetbytes = cp->GetPacketBytes();
+ SendCommand(packetbytes, 12);
+ Response_Packet* rp = GetResponse();
+
+ int retval = rp->IntFromParameter();
+ delete cp;
+ delete rp;
+ delete [] packetbytes;
+ return retval;
+}
+
+// checks to see if the ID number is in use or not
+// Parameter: 0-199
+// Return: True if the ID number is enrolled, false if not
+bool FPScanner::CheckEnrolled(int id)
+{
+ Command_Packet* cp = new Command_Packet();
+ cp->Command = Command_Packet::Commands::CheckEnrolled;
+ cp->ParameterFromInt(id);
+ byte* packetbytes = cp->GetPacketBytes();
+ SendCommand(packetbytes, 12);
+ Response_Packet* rp = GetResponse();
+ bool retval = false;
+ retval = rp->ACK;
+ delete cp;
+ delete rp;
+ delete [] packetbytes;
+ return retval;
+}
+
+// Starts the Enrollment Process
+// Parameter: 0-199
+// Return:
+// 0 - ACK
+// 1 - Database is full
+// 2 - Invalid Position
+// 3 - Position(ID) is already used
+int FPScanner::EnrollStart(int id)
+{
+ Command_Packet* cp = new Command_Packet();
+ cp->Command = Command_Packet::Commands::EnrollStart;
+ cp->ParameterFromInt(id);
+ byte* packetbytes = cp->GetPacketBytes();
+ delete cp;
+ SendCommand(packetbytes, 12);
+ delete [] packetbytes;
+ Response_Packet* rp = GetResponse();
+ int retval = 0;
+ if (rp->ACK == false)
+ {
+ if (rp->Error == Response_Packet::ErrorCodes::NACK_DB_IS_FULL) retval = 1;
+ if (rp->Error == Response_Packet::ErrorCodes::NACK_INVALID_POS) retval = 2;
+ if (rp->Error == Response_Packet::ErrorCodes::NACK_IS_ALREADY_USED) retval = 3;
+ }
+ delete rp;
+ return retval;
+}
+
+// Gets the first scan of an enrollment
+// Return:
+// 0 - ACK
+// 1 - Enroll Failed
+// 2 - Bad finger
+// 3 - ID in use
+int FPScanner::Enroll1()
+{
+ Command_Packet* cp = new Command_Packet();
+ cp->Command = Command_Packet::Commands::Enroll1;
+ byte* packetbytes = cp->GetPacketBytes();
+ delete cp;
+ SendCommand(packetbytes, 12);
+ delete [] packetbytes;
+ Response_Packet* rp = GetResponse();
+ int retval = rp->IntFromParameter();
+ if (retval < 200) retval = 3; else retval = 0;
+ if (rp->ACK == false)
+ {
+ if (rp->Error == Response_Packet::ErrorCodes::NACK_ENROLL_FAILED) retval = 1;
+ if (rp->Error == Response_Packet::ErrorCodes::NACK_BAD_FINGER) retval = 2;
+ }
+ delete rp;
+ if (rp->ACK) return 0; else return retval;
+}
+
+// Gets the Second scan of an enrollment
+// Return:
+// 0 - ACK
+// 1 - Enroll Failed
+// 2 - Bad finger
+// 3 - ID in use
+int FPScanner::Enroll2()
+{
+ Command_Packet* cp = new Command_Packet();
+ cp->Command = Command_Packet::Commands::Enroll2;
+ byte* packetbytes = cp->GetPacketBytes();
+ delete cp;
+ SendCommand(packetbytes, 12);
+ delete [] packetbytes;
+ Response_Packet* rp = GetResponse();
+ int retval = rp->IntFromParameter();
+ if (retval < 200) retval = 3; else retval = 0;
+ if (rp->ACK == false)
+ {
+ if (rp->Error == Response_Packet::ErrorCodes::NACK_ENROLL_FAILED) retval = 1;
+ if (rp->Error == Response_Packet::ErrorCodes::NACK_BAD_FINGER) retval = 2;
+ }
+ delete rp;
+ if (rp->ACK) return 0; else return retval;
+}
+
+// Gets the Third scan of an enrollment
+// Finishes Enrollment
+// Return:
+// 0 - ACK
+// 1 - Enroll Failed
+// 2 - Bad finger
+// 3 - ID in use
+int FPScanner::Enroll3()
+{
+ Command_Packet* cp = new Command_Packet();
+ cp->Command = Command_Packet::Commands::Enroll3;
+ byte* packetbytes = cp->GetPacketBytes();
+ delete cp;
+ SendCommand(packetbytes, 12);
+ delete [] packetbytes;
+ Response_Packet* rp = GetResponse();
+ int retval = rp->IntFromParameter();
+ if (retval < 200) retval = 3; else retval = 0;
+ if (rp->ACK == false)
+ {
+ if (rp->Error == Response_Packet::ErrorCodes::NACK_ENROLL_FAILED) retval = 1;
+ if (rp->Error == Response_Packet::ErrorCodes::NACK_BAD_FINGER) retval = 2;
+ }
+ delete rp;
+ if (rp->ACK) return 0; else return retval;
+}
+
+// Checks to see if a finger is pressed on the FPS
+// Return: true if finger pressed, false if not
+bool FPScanner::IsPressFinger()
+{
+ Command_Packet* cp = new Command_Packet();
+ cp->Command = Command_Packet::Commands::IsPressFinger;
+ byte* packetbytes = cp->GetPacketBytes();
+ SendCommand(packetbytes, 12);
+ Response_Packet* rp = GetResponse();
+ bool retval = false;
+ int pval = rp->ParameterBytes[0];
+ pval += rp->ParameterBytes[1];
+ pval += rp->ParameterBytes[2];
+ pval += rp->ParameterBytes[3];
+ if (pval == 0) retval = true;
+ delete rp;
+ delete [] packetbytes;
+ delete cp;
+ return retval;
+}
+
+// Deletes the specified ID (enrollment) from the database
+// Parameter: 0-199 (id number to be deleted)
+// Returns: true if successful, false if position invalid
+bool FPScanner::DeleteID(int id)
+{
+ Command_Packet* cp = new Command_Packet();
+ cp->Command = Command_Packet::Commands::DeleteID;
+ cp->ParameterFromInt(id);
+ byte* packetbytes = cp->GetPacketBytes();
+ SendCommand(packetbytes, 12);
+ Response_Packet* rp = GetResponse();
+ bool retval = rp->ACK;
+ delete rp;
+ delete [] packetbytes;
+ delete cp;
+ return retval;
+}
+
+// Deletes all IDs (enrollments) from the database
+// Returns: true if successful, false if db is empty
+bool FPScanner::DeleteAll()
+{
+ Command_Packet* cp = new Command_Packet();
+ cp->Command = Command_Packet::Commands::DeleteAll;
+ byte* packetbytes = cp->GetPacketBytes();
+ SendCommand(packetbytes, 12);
+ Response_Packet* rp = GetResponse();
+ bool retval = rp->ACK;
+ delete rp;
+ delete [] packetbytes;
+ delete cp;
+ return retval;
+}
+
+// Checks the currently pressed finger against a specific ID
+// Parameter: 0-199 (id number to be checked)
+// Returns:
+// 0 - Verified OK (the correct finger)
+// 1 - Invalid Position
+// 2 - ID is not in use
+// 3 - Verified FALSE (not the correct finger)
+int FPScanner::Verify1_1(int id)
+{
+ Command_Packet* cp = new Command_Packet();
+ cp->Command = Command_Packet::Commands::Verify1_1;
+ cp->ParameterFromInt(id);
+ byte* packetbytes = cp->GetPacketBytes();
+ SendCommand(packetbytes, 12);
+ Response_Packet* rp = GetResponse();
+ int retval = 0;
+ if (rp->ACK == false)
+ {
+ if (rp->Error == Response_Packet::ErrorCodes::NACK_INVALID_POS) retval = 1;
+ if (rp->Error == Response_Packet::ErrorCodes::NACK_IS_NOT_USED) retval = 2;
+ if (rp->Error == Response_Packet::ErrorCodes::NACK_VERIFY_FAILED) retval = 3;
+ }
+ delete rp;
+ delete [] packetbytes;
+ delete cp;
+ return retval;
+}
+
+// Checks the currently pressed finger against all enrolled fingerprints
+// Returns:
+// 0-199: Verified against the specified ID (found, and here is the ID number)
+// 200: Failed to find the fingerprint in the database
+int FPScanner::Identify1_N()
+{
+ Command_Packet* cp = new Command_Packet();
+ cp->Command = Command_Packet::Commands::Identify1_N;
+ byte* packetbytes = cp->GetPacketBytes();
+ SendCommand(packetbytes, 12);
+ Response_Packet* rp = GetResponse();
+ int retval = rp->IntFromParameter();
+ if (retval > 200) retval = 200;
+ delete rp;
+ delete [] packetbytes;
+ delete cp;
+ return retval;
+}
+
+// Captures the currently pressed finger into onboard ram use this prior to other commands
+// Parameter: true for high quality image(slower), false for low quality image (faster)
+// Generally, use high quality for enrollment, and low quality for verification/identification
+// Returns: True if ok, false if no finger pressed
+bool FPScanner::CaptureFinger(bool highquality)
+{
+ Command_Packet* cp = new Command_Packet();
+ cp->Command = Command_Packet::Commands::CaptureFinger;
+ if (highquality)
+ {
+ cp->ParameterFromInt(1);
+ }
+ else
+ {
+ cp->ParameterFromInt(0);
+ }
+ byte* packetbytes = cp->GetPacketBytes();
+ SendCommand(packetbytes, 12);
+ Response_Packet* rp = GetResponse();
+ bool retval = rp->ACK;
+ delete rp;
+ delete [] packetbytes;
+ delete cp;
+ return retval;
+
+}
+
+
+// Sends the command to the software serial channel
+void FPScanner::SendCommand(byte cmd[], int length)
+{
+ for (int i = 0; i < length; i++) {
+ _serial.putc(cmd[i]);
+ }
+};
+
+// Gets the response to the command from the software serial channel (and waits for it)
+Response_Packet* FPScanner::GetResponse()
+{
+ byte firstbyte = 0;
+ bool done = false;
+ while (done == false)
+ {
+ firstbyte = (byte)_serial.getc();
+ if (firstbyte == Response_Packet::COMMAND_START_CODE_1)
+ {
+ done = true;
+ }
+ }
+ byte* resp = new byte[12];
+ resp[0] = firstbyte;
+ for (int i=1; i < 12; i++)
+ {
+ resp[i]= (byte) _serial.getc();
+ }
+ Response_Packet* rp = new Response_Packet(resp);
+ delete [] resp;
+ return rp;
+};
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/FPScanner.h Mon Apr 25 00:36:32 2016 +0000
@@ -0,0 +1,262 @@
+/*
+ FPScanner.h v1.0 - Library for controlling the GT-511C3 Finger Print Scanner (FPS)
+ Created by Josh Hawley, July 23rd 2013
+ Licensed for non-commercial use, must include this license message
+ basically, Feel free to hack away at it, but just give me credit for my work =)
+ TLDR; Wil Wheaton's Law
+*/
+
+#ifndef FPScanner_H
+#define FPScanner_H
+
+#include "mbed.h"
+
+typedef uint8_t byte;
+typedef uint16_t word;
+
+
+class Command_Packet
+{
+ public:
+ class Commands
+ {
+ public:
+ enum Commands_Enum
+ {
+ NotSet = 0x00, // Default value for enum. Scanner will return error if sent this.
+ Open = 0x01, // Open Initialization
+ Close = 0x02, // Close Termination
+ UsbInternalCheck = 0x03, // UsbInternalCheck Check if the connected USB device is valid
+ ChangeEBaudRate = 0x04, // ChangeBaudrate Change UART baud rate
+ SetIAPMode = 0x05, // SetIAPMode Enter IAP Mode In this mode, FW Upgrade is available
+ CmosLed = 0x12, // CmosLed Control CMOS LED
+ GetEnrollCount = 0x20, // Get enrolled fingerprint count
+ CheckEnrolled = 0x21, // Check whether the specified ID is already enrolled
+ EnrollStart = 0x22, // Start an enrollment
+ Enroll1 = 0x23, // Make 1st template for an enrollment
+ Enroll2 = 0x24, // Make 2nd template for an enrollment
+ Enroll3 = 0x25, // Make 3rd template for an enrollment, merge three templates into one template, save merged template to the database
+ IsPressFinger = 0x26, // Check if a finger is placed on the sensor
+ DeleteID = 0x40, // Delete the fingerprint with the specified ID
+ DeleteAll = 0x41, // Delete all fingerprints from the database
+ Verify1_1 = 0x50, // Verification of the capture fingerprint image with the specified ID
+ Identify1_N = 0x51, // Identification of the capture fingerprint image with the database
+ VerifyTemplate1_1 = 0x52, // Verification of a fingerprint template with the specified ID
+ IdentifyTemplate1_N = 0x53, // Identification of a fingerprint template with the database
+ CaptureFinger = 0x60, // Capture a fingerprint image(256x256) from the sensor
+ MakeTemplate = 0x61, // Make template for transmission
+ GetImage = 0x62, // Download the captured fingerprint image(256x256)
+ GetRawImage = 0x63, // Capture & Download raw fingerprint image(320x240)
+ GetTemplate = 0x70, // Download the template of the specified ID
+ SetTemplate = 0x71, // Upload the template of the specified ID
+ GetDatabaseStart = 0x72, // Start database download, obsolete
+ GetDatabaseEnd = 0x73, // End database download, obsolete
+ UpgradeFirmware = 0x80, // Not supported
+ UpgradeISOCDImage = 0x81, // Not supported
+ Ack = 0x30, // Acknowledge.
+ Nack = 0x31 // Non-acknowledge
+ };
+ };
+
+ Commands::Commands_Enum Command;
+ byte Parameter[4]; // Parameter 4 bytes, changes meaning depending on command
+ byte* GetPacketBytes(); // returns the bytes to be transmitted
+ void ParameterFromInt(int i);
+
+ Command_Packet();
+
+ private:
+ static const byte COMMAND_START_CODE_1 = 0x55; // Static byte to mark the beginning of a command packet - never changes
+ static const byte COMMAND_START_CODE_2 = 0xAA; // Static byte to mark the beginning of a command packet - never changes
+ static const byte COMMAND_DEVICE_ID_1 = 0x01; // Device ID Byte 1 (lesser byte) - theoretically never changes
+ static const byte COMMAND_DEVICE_ID_2 = 0x00; // Device ID Byte 2 (greater byte) - theoretically never changes
+ byte command[2]; // Command 2 bytes
+
+ word _CalculateChecksum(); // Checksum is calculated using byte addition
+ byte GetHighByte(word w);
+ byte GetLowByte(word w);
+};
+
+
+/*
+ Response_Packet represents the returned data from the finger print scanner
+*/
+class Response_Packet
+{
+ public:
+ class ErrorCodes
+ {
+ public:
+ enum Errors_Enum
+ {
+ NO_ERROR = 0x0000, // Default value. no error
+ NACK_TIMEOUT = 0x1001, // Obsolete, capture timeout
+ NACK_INVALID_BAUDRATE = 0x1002, // Obsolete, Invalid serial baud rate
+ NACK_INVALID_POS = 0x1003, // The specified ID is not between 0~199
+ NACK_IS_NOT_USED = 0x1004, // The specified ID is not used
+ NACK_IS_ALREADY_USED = 0x1005, // The specified ID is already used
+ NACK_COMM_ERR = 0x1006, // Communication Error
+ NACK_VERIFY_FAILED = 0x1007, // 1:1 Verification Failure
+ NACK_IDENTIFY_FAILED = 0x1008, // 1:N Identification Failure
+ NACK_DB_IS_FULL = 0x1009, // The database is full
+ NACK_DB_IS_EMPTY = 0x100A, // The database is empty
+ NACK_TURN_ERR = 0x100B, // Obsolete, Invalid order of the enrollment (The order was not as: EnrollStart -> Enroll1 -> Enroll2 -> Enroll3)
+ NACK_BAD_FINGER = 0x100C, // Too bad fingerprint
+ NACK_ENROLL_FAILED = 0x100D, // Enrollment Failure
+ NACK_IS_NOT_SUPPORTED = 0x100E, // The specified command is not supported
+ NACK_DEV_ERR = 0x100F, // Device Error, especially if Crypto-Chip is trouble
+ NACK_CAPTURE_CANCELED = 0x1010, // Obsolete, The capturing is canceled
+ NACK_INVALID_PARAM = 0x1011, // Invalid parameter
+ NACK_FINGER_IS_NOT_PRESSED = 0x1012, // Finger is not pressed
+ INVALID = 0XFFFF // Used when parsing fails
+ };
+
+ static Errors_Enum ParseFromBytes(byte high, byte low);
+ };
+ Response_Packet(byte* buffer);
+ ErrorCodes::Errors_Enum Error;
+ byte RawBytes[12];
+ byte ParameterBytes[4];
+ byte ResponseBytes[2];
+ bool ACK;
+ static const byte COMMAND_START_CODE_1 = 0x55; // Static byte to mark the beginning of a command packet - never changes
+ static const byte COMMAND_START_CODE_2 = 0xAA; // Static byte to mark the beginning of a command packet - never changes
+ static const byte COMMAND_DEVICE_ID_1 = 0x01; // Device ID Byte 1 (lesser byte) - theoretically never changes
+ static const byte COMMAND_DEVICE_ID_2 = 0x00; // Device ID Byte 2 (greater byte) - theoretically never changes
+ int IntFromParameter();
+
+ private:
+ bool CheckParsing(byte b, byte propervalue, byte alternatevalue);
+ word CalculateChecksum(byte* buffer, int length);
+ byte GetHighByte(word w);
+ byte GetLowByte(word w);
+};
+
+
+/*
+ Object for controlling the GT-511C3 Finger Print Scanner (FPS)
+*/
+class FPScanner
+{
+
+ public:
+
+ // Creates a new object to interface with the fingerprint scanner
+ FPScanner(PinName tx, PinName rx);
+
+ //Initialises the device and gets ready for commands
+ void Open();
+
+ // Does not actually do anything (according to the datasheet)
+ // I implemented open, so had to do closed too... lol
+ void Close();
+
+ // Turns on or off the LED backlight
+ // LED must be on to see fingerprints
+ // Parameter: true turns on the backlight, false turns it off
+ // Returns: True if successful, false if not
+ bool SetLED(bool on);
+
+ // Changes the baud rate of the connection
+ // Parameter: 9600 - 115200
+ // Returns: True if success, false if invalid baud
+ // NOTE: Untested (don't have a logic level changer and a voltage divider is too slow)
+ bool ChangeBaudRate(int baud);
+
+ // Gets the number of enrolled fingerprints
+ // Return: The total number of enrolled fingerprints
+ int GetEnrollCount();
+
+ // checks to see if the ID number is in use or not
+ // Parameter: 0-199
+ // Return: True if the ID number is enrolled, false if not
+ bool CheckEnrolled(int id);
+
+ // Starts the Enrollment Process
+ // Parameter: 0-199
+ // Return:
+ // 0 - ACK
+ // 1 - Database is full
+ // 2 - Invalid Position
+ // 3 - Position(ID) is already used
+ int EnrollStart(int id);
+
+ // Gets the first scan of an enrollment
+ // Return:
+ // 0 - ACK
+ // 1 - Enroll Failed
+ // 2 - Bad finger
+ // 3 - ID in use
+ int Enroll1();
+
+ // Gets the Second scan of an enrollment
+ // Return:
+ // 0 - ACK
+ // 1 - Enroll Failed
+ // 2 - Bad finger
+ // 3 - ID in use
+ int Enroll2();
+
+ // Gets the Third scan of an enrollment
+ // Finishes Enrollment
+ // Return:
+ // 0 - ACK
+ // 1 - Enroll Failed
+ // 2 - Bad finger
+ // 3 - ID in use
+ int Enroll3();
+
+ // Checks to see if a finger is pressed on the FPS
+ // Return: true if finger pressed, false if not
+ bool IsPressFinger();
+
+ // Deletes the specified ID (enrollment) from the database
+ // Returns: true if successful, false if position invalid
+ bool DeleteID(int ID);
+
+ // Deletes all IDs (enrollments) from the database
+ // Returns: true if successful, false if db is empty
+ bool DeleteAll();
+
+ // Checks the currently pressed finger against a specific ID
+ // Parameter: 0-199 (id number to be checked)
+ // Returns:
+ // 0 - Verified OK (the correct finger)
+ // 1 - Invalid Position
+ // 2 - ID is not in use
+ // 3 - Verified FALSE (not the correct finger)
+ int Verify1_1(int id);
+
+ // Checks the currently pressed finger against all enrolled fingerprints
+ // Returns:
+ // 0-199: Verified against the specified ID (found, and here is the ID number)
+ // 200: Failed to find the fingerprint in the database
+ int Identify1_N();
+
+ // Captures the currently pressed finger into onboard ram
+ // Parameter: true for high quality image(slower), false for low quality image (faster)
+ // Generally, use high quality for enrollment, and low quality for verification/identification
+ // Returns: True if ok, false if no finger pressed
+ bool CaptureFinger(bool highquality);
+
+
+ // resets the Data_Packet class, and gets ready to download
+ // Not implemented due to memory restrictions on the arduino
+ // may revisit this if I find a need for it
+ //void StartDataDownload();
+
+ // Returns the next data packet
+ // Not implemented due to memory restrictions on the arduino
+ // may revisit this if I find a need for it
+ //Data_Packet GetNextDataPacket();
+
+private:
+ void SendCommand(byte cmd[], int length);
+ Response_Packet* GetResponse();
+ PinName pin_RX,pin_TX;
+ Serial _serial;
+};
+
+
+#endif // FPScanner_H
+
--- a/lib.cpp Sun Apr 24 23:37:04 2016 +0000
+++ b/lib.cpp Mon Apr 25 00:36:32 2016 +0000
@@ -22,4 +22,37 @@
pos++;
}
*size = pos - 1;
+}
+
+bool fp_enroll(FPScanner *fp)
+{
+ bool status = true;
+ fp->SetLED(true);
+ while(!fp->IsPressFinger()) wait(0.030);
+ fp->CaptureFinger(true);
+ if (fp->Identify1_N() == 200) {
+ int id = fp->GetEnrollCount();
+ if (fp->EnrollStart(id) == 0) {
+ fp->CaptureFinger(true);
+ fp->Enroll1();
+ fp->CaptureFinger(true);
+ fp->Enroll2();
+ fp->CaptureFinger(true);
+ fp->Enroll3();
+ fp->SetLED(false);
+ } else status = false;
+ } else status = false;
+
+ return status;
+}
+
+bool fp_auth(FPScanner *fp)
+{
+ bool status = false;
+ fp->SetLED(true);
+ while(!fp->IsPressFinger()) wait(0.030);
+ fp->CaptureFinger(true);
+ if (fp->Identify1_N() != 200) status = true;
+ fp->SetLED(false);
+ return status;
}
\ No newline at end of file
--- a/lib.h Sun Apr 24 23:37:04 2016 +0000 +++ b/lib.h Mon Apr 25 00:36:32 2016 +0000 @@ -1,4 +1,7 @@ #include "mbed.h" +#include "FPScanner.h" int hashcode(const char *data, int size); -void read_mag_card(Serial *device, char *dest, int *size); \ No newline at end of file +void read_mag_card(Serial *device, char *dest, int *size); +bool fp_enroll(FPScanner *fp); +bool fp_auth(FPScanner *fp); \ No newline at end of file
