Trung Nguyen
/
FINAL_PROJECT_4180
asdasdasd
Fork of FINAL_PROJECT_4180 by
FPScanner.cpp
- Committer:
- nyengele
- Date:
- 2016-04-25
- Revision:
- 2:1b1c0502bb08
File content as of revision 2:1b1c0502bb08:
/* 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; };