From 9a6b214bdeabbd152b675610a91f3a24c94c9f32 Mon Sep 17 00:00:00 2001 From: Fasgort Date: Sun, 25 Mar 2018 22:47:18 +0200 Subject: [PATCH 01/27] Update README.md --- README.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/README.md b/README.md index 760874d..95a23e8 100644 --- a/README.md +++ b/README.md @@ -16,6 +16,16 @@ Fingerprint Scanner-TTL This is a great fingerprint module from ADH-Tech that communicates over 3.3V TTL Serial so you can easily embed it into your next project. This repository contains Arduino example code to work with it. This code has been tested with GT-521F32, GT-521F52, GT-511C3, and GT-511C1R. +Fork purpose +==================================== +This fork implements a few of the remaining commands needed to extract the fingerprint DB contained in the original device, allowing to implement a server-based IoT service. + +Commands to implement: +* bool GetImage() +* bool GetRawImage() +* int GetTemplate(int) +* int SetTemplate(byte*, int, bool) + Repository Contents ------------------- * **/examples** - Example code to interface with the sensor. From 13ff92afb4e3e16bf708bf5e95a3f5473ec16f37 Mon Sep 17 00:00:00 2001 From: Fasgort Date: Sun, 8 Apr 2018 01:23:35 +0200 Subject: [PATCH 02/27] Implemented Data_Packet and the required methods to send it over Serial. --- src/FPS_GT511C3.cpp | 237 ++++++++++++++++++++++++++++++++++++-------- src/FPS_GT511C3.h | 74 +++++++------- 2 files changed, 230 insertions(+), 81 deletions(-) diff --git a/src/FPS_GT511C3.cpp b/src/FPS_GT511C3.cpp index 2090322..1703f5b 100644 --- a/src/FPS_GT511C3.cpp +++ b/src/FPS_GT511C3.cpp @@ -168,6 +168,24 @@ int Response_Packet::IntFromParameter() return retval; } +// 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, const char* varname, bool UseSerialDebug) +{ + bool retval = (b != propervalue) && (b != alternatevalue); + if ((UseSerialDebug) && (retval)) + { + Serial.print("Response_Packet parsing error "); + Serial.print(varname); + Serial.print(" "); + Serial.print(propervalue, HEX); + Serial.print(" || "); + Serial.print(alternatevalue, HEX); + Serial.print(" != "); + Serial.println(b, HEX); + } + return retval; +} + // calculates the checksum from the bytes in the packet word Response_Packet::CalculateChecksum(byte* buffer, int length) { @@ -190,14 +208,48 @@ byte Response_Packet::GetLowByte(word w) { return (byte)w&0x00FF; } +#ifndef __GNUC__ +#pragma endregion +#endif //__GNUC__ + +#ifndef __GNUC__ +#pragma region -= Data_Packet =- +#endif //__GNUC__ +Data_Packet::Data_Packet(byte* buffer, bool UseSerialDebug) +{ + CheckParsing(buffer[0], DATA_START_CODE_1, DATA_START_CODE_1, "DATA_START_CODE_1", UseSerialDebug); + CheckParsing(buffer[1], DATA_START_CODE_2, DATA_START_CODE_2, "DATA_START_CODE_2", UseSerialDebug); + CheckParsing(buffer[2], DATA_DEVICE_ID_1, DATA_DEVICE_ID_1, "DATA_DEVICE_ID_1", UseSerialDebug); + CheckParsing(buffer[3], DATA_DEVICE_ID_2, DATA_DEVICE_ID_2, "DATA_DEVICE_ID_2", UseSerialDebug); + + Data_Packet.checksum = CalculateChecksum(buffer, 4); +} + +// Get a data packet (128 bytes), calculate checksum and send it to serial +Data_Packet::GetData(byte* buffer, bool UseSerialDebug) +{ + FPS_GT511C3.SendToSerial(buffer, 128); + Data_Packet.checksum = CalculateChecksum(buffer, 128); +} + +// Get the last data packet (<=128 bytes), calculate checksum, validate checksum received and send it to serial +Data_Packet::GetLastData(byte* buffer, int length, bool UseSerialDebug) +{ + FPS_GT511C3.SendToSerial(buffer, length-2); + Data_Packet.checksum = CalculateChecksum(buffer, length); + byte checksum_low = GetLowByte(Data_Packet.checksum); + byte checksum_high = GetHighByte(Data_Packet.checksum); + CheckParsing(buffer[length-2], checksum_low, checksum_low, "Checksum_LOW", UseSerialDebug); + CheckParsing(buffer[length-1], checksum_high, checksum_high, "Checksum_HIGH", UseSerialDebug); +} // 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, const char* varname, bool UseSerialDebug) +bool Data_Packet::CheckParsing(byte b, byte propervalue, byte alternatevalue, const char* varname, bool UseSerialDebug) { bool retval = (b != propervalue) && (b != alternatevalue); if ((UseSerialDebug) && (retval)) { - Serial.print("Response_Packet parsing error "); + Serial.print("Data_Packet parsing error "); Serial.print(varname); Serial.print(" "); Serial.print(propervalue, HEX); @@ -208,18 +260,40 @@ bool Response_Packet::CheckParsing(byte b, byte propervalue, byte alternatevalue } return retval; } -#ifndef __GNUC__ -#pragma endregion -#endif //__GNUC__ -#ifndef __GNUC__ -#pragma region -= Data_Packet =- -#endif //__GNUC__ -//void Data_Packet::StartNewPacket() -//{ -// Data_Packet::NextPacketID = 0; -// Data_Packet::CheckSum = 0; -//} +// calculates the checksum from the bytes in the packet +word Data_Packet::CalculateChecksum(byte* buffer, int length) +{ + word checksum = Data_Packet.checksum; + for (int i=0; i>8)&0x00FF; +} + +// Returns the low byte from a word +byte Data_Packet::GetLowByte(word w) +{ + return (byte)w&0x00FF; +} #ifndef __GNUC__ #pragma endregion #endif //__GNUC__ @@ -655,6 +729,28 @@ bool FPS_GT511C3::CaptureFinger(bool highquality) return retval; } + +// Gets an image that is qvga 160x120 (19200 bytes) and returns it in 150 Data_Packets +// Use StartDataDownload, and then GetNextDataPacket until done +// Returns: True (device confirming download starting) + // Not implemented due to memory restrictions on the arduino + // may revisit this if I find a need for it +/*bool FPS_GT511C3::GetRawImage() +{ + if (UseSerialDebug) Serial.println("FPS - GetRawImage"); + Command_Packet* cp = new Command_Packet(); + cp->Command = Command_Packet::Commands::GetRawImage; + byte* packetbytes = cp->GetPacketBytes(); + delete cp; + SendCommand(packetbytes, 12); + Response_Packet* rp = GetResponse(); + bool retval = rp->ACK; + delete rp; + delete packetbytes; + return retval; + + //return false; +}*/ #ifndef __GNUC__ #pragma endregion #endif //__GNUC__ @@ -674,18 +770,6 @@ bool FPS_GT511C3::CaptureFinger(bool highquality) //return false; //} -// Gets an image that is qvga 160x120 (19200 bytes) and returns it in 150 Data_Packets -// Use StartDataDownload, and then GetNextDataPacket until done -// Returns: True (device confirming download starting) - // Not implemented due to memory restrictions on the arduino - // may revisit this if I find a need for it -//bool FPS_GT511C3::GetRawImage() -//{ - // Not implemented due to memory restrictions on the arduino - // may revisit this if I find a need for it - //return false; -//} - // Gets a template from the fps (498 bytes) in 4 Data_Packets // Use StartDataDownload, and then GetNextDataPacket until done // Parameter: 0-199 ID number @@ -721,23 +805,6 @@ bool FPS_GT511C3::CaptureFinger(bool highquality) //return -1; //} -// 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 FPS_GT511C3::StartDataDownload() -//{ - // Not implemented due to memory restrictions on the arduino - // may revisit this if I find a need for it -//} - -// 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() -//{ -// return 0; -//} - // Commands that are not implemented (and why) // VerifyTemplate1_1 - Couldn't find a good reason to implement this on an arduino // IdentifyTemplate1_N - Couldn't find a good reason to implement this on an arduino @@ -802,6 +869,92 @@ Response_Packet* FPS_GT511C3::GetResponse() return rp; }; +// Gets the data (length bytes) from the software serial channel (and waits for it) +// and sends it over serial sommunications +void FPS_GT511C3::GetData(int length) +{ + byte firstbyte = 0; + byte secondbyte = 0; + bool done = false; + _serial.listen(); + while (done == false) + { + firstbyte = (byte)_serial.read(); + if (firstbyte == Data_Packet()::DATA_START_CODE_1) + { + secondbyte = (byte)_serial.read(); + if (secondbyte == Data_Packet()::DATA_START_CODE_2) + { + done = true; + } + } + } + + byte* firstdata = new byte[4]; + firstdata[0] = firstbyte; + firstdata[1] = secondbyte; + for (int i=2; i < 4; i++) + { + while (_serial.available() == false) delay(10); + firstdata[i]= (byte) _serial.read(); + } + Data_Packet* dp = new Data_Packet(firstdata, UseSerialDebug); + if(UseSerialDebug) + { + Serial.print("FPS - RECV: "); + SendToSerial(firstdata, 4); + Serial.println(); + Serial.println(); + } + delete firstdata; + + numberPacketsNeeded = (length-4) / 128; + bool smallLastPacket = false; + int lastPacketSize = (length-4) % 128; + if(lastPacketSize != 0) + { + numberPacketsNeeded++; + smallLastPacket = true; + } + + for (int packetCount=1; packetCount < numberPacketsNeeded; packetCount++) + { + byte* data = new byte[128]; + for (int i=0; i < 128; i++) + { + while (_serial.available() == false) delay(10); + data[i]= (byte) _serial.read(); + } + dp.GetData(data, UseSerialDebug); + if(UseSerialDebug) + { + Serial.print("FPS - RECV: "); + SendToSerial(data, 128); + Serial.println(); + Serial.println(); + } + delete data; + } + + byte* lastdata = new byte[lastPacketSize]; + for (int i=0; i < lastPacketSize; i++) + { + while (_serial.available() == false) delay(10); + lastdata[i]= (byte) _serial.read(); + } + dp.GetLastData(lastdata, lastPacketSize, UseSerialDebug); + if(UseSerialDebug) + { + Serial.print("FPS - RECV: "); + SendToSerial(lastdata, lastPacketSize); + Serial.println(); + Serial.println(); + } + delete lastdata; + + return; +}; + // sends the bye aray to the serial debugger in our hex format EX: "00 AF FF 10 00 13" void FPS_GT511C3::SendToSerial(byte data[], int length) { diff --git a/src/FPS_GT511C3.h b/src/FPS_GT511C3.h index dba5bfb..bb33967 100644 --- a/src/FPS_GT511C3.h +++ b/src/FPS_GT511C3.h @@ -61,13 +61,13 @@ class Command_Packet }; Commands::Commands_Enum Command; - byte Parameter[4]; // Parameter 4 bytes, changes meaning depending on 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: + 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 @@ -75,7 +75,7 @@ class Command_Packet byte command[2]; // Command 2 bytes word _CalculateChecksum(); // Checksum is calculated using byte addition - byte GetHighByte(word w); + byte GetHighByte(word w); byte GetLowByte(word w); }; #ifndef __GNUC__ @@ -86,7 +86,7 @@ class Command_Packet #pragma region -= Response_Packet =- #endif //__GNUC__ /* - Response_Packet represents the returned data from the finger print scanner + Response_Packet represents the returned data from the finger print scanner */ class Response_Packet { @@ -132,10 +132,10 @@ class Response_Packet static const byte COMMAND_DEVICE_ID_2 = 0x00; // Device ID Byte 2 (greater byte) - theoretically never changes int IntFromParameter(); - private: + private: bool CheckParsing(byte b, byte propervalue, byte alternatevalue, const char* varname, bool UseSerialDebug); word CalculateChecksum(byte* buffer, int length); - byte GetHighByte(word w); + byte GetHighByte(word w); byte GetLowByte(word w); }; #ifndef __GNUC__ @@ -143,22 +143,27 @@ class Response_Packet #endif //__GNUC__ #ifndef __GNUC__ -#pragma region -= Data_Packet =- +#pragma region -= Data_Packet =- #endif //__GNUC__ // Data Mule packet for receiving large data(in 128 byte pieces) from the FPS // This class can only transmit one packet at a time -//class Data_Packet -//{ -//public: -// static int CheckSum; -// int PacketID; -// int ValidByteLength; -// byte Data[128]; -// void StartNewPacket(); -// bool IsLastPacket; -//private: -// static int NextPacketID; -//}; +class Data_Packet +{ +public: + Data_Packet(byte* buffer, bool UseSerialDebug); + word checksum = 0; + static const byte DATA_START_CODE_1 = 0x5A; // Static byte to mark the beginning of a data packet - never changes + static const byte DATA_START_CODE_2 = 0xA5; // Static byte to mark the beginning of a data packet - never changes + static const byte DATA_DEVICE_ID_1 = 0x01; // Device ID Byte 1 (lesser byte) - theoretically never changes + static const byte DATA_DEVICE_ID_2 = 0x00; // Device ID Byte 2 (greater byte) +private: + void GetData(byte* buffer, bool UseSerialDebug); + void GetLastData(byte* buffer, int length, bool UseSerialDebug); + bool CheckParsing(byte b, byte propervalue, byte alternatevalue, const char* varname, bool UseSerialDebug); + word CalculateChecksum(byte* buffer, int length); + byte GetHighByte(word w); + byte GetLowByte(word w); +}; #ifndef __GNUC__ #pragma endregion #endif //__GNUC__ @@ -169,9 +174,9 @@ class Response_Packet */ class FPS_GT511C3 { - + public: - // Enables verbose debug output using hardware Serial + // Enables verbose debug output using hardware Serial bool UseSerialDebug; #ifndef __GNUC__ @@ -179,7 +184,7 @@ class FPS_GT511C3 #endif //__GNUC__ // Creates a new object to interface with the fingerprint scanner FPS_GT511C3(uint8_t rx, uint8_t tx); - + // destructor ~FPS_GT511C3(); #ifndef __GNUC__ @@ -202,7 +207,7 @@ class FPS_GT511C3 // 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 @@ -230,7 +235,7 @@ class FPS_GT511C3 int EnrollStart(int id); // Gets the first scan of an enrollment - // Return: + // Return: // 0 - ACK // 1 - Enroll Failed // 2 - Bad finger @@ -238,7 +243,7 @@ class FPS_GT511C3 int Enroll1(); // Gets the Second scan of an enrollment - // Return: + // Return: // 0 - ACK // 1 - Enroll Failed // 2 - Bad finger @@ -247,7 +252,7 @@ class FPS_GT511C3 // Gets the Third scan of an enrollment // Finishes Enrollment - // Return: + // Return: // 0 - ACK // 1 - Enroll Failed // 2 - Bad finger @@ -315,7 +320,7 @@ class FPS_GT511C3 // Gets a template from the fps (498 bytes) in 4 Data_Packets // Use StartDataDownload, and then GetNextDataPacket until done // Parameter: 0-199 ID number - // Returns: + // Returns: // 0 - ACK Download starting // 1 - Invalid position // 2 - ID not used (no template to download @@ -323,11 +328,11 @@ class FPS_GT511C3 // may revisit this if I find a need for it //int GetTemplate(int id); - // Uploads a template to the fps + // Uploads a template to the fps // Parameter: the template (498 bytes) // Parameter: the ID number to upload // Parameter: Check for duplicate fingerprints already on fps - // Returns: + // Returns: // 0-199 - ID duplicated // 200 - Uploaded ok (no duplicate if enabled) // 201 - Invalid position @@ -359,19 +364,10 @@ class FPS_GT511C3 void serialPrintHex(byte data); void SendToSerial(byte data[], int length); - // 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(); + void GetData(int length); uint8_t pin_RX,pin_TX; SoftwareSerial _serial; }; From e23aeacf83223d8eda274e524e4aa9339c3ece2f Mon Sep 17 00:00:00 2001 From: Fasgort Date: Sun, 8 Apr 2018 01:34:58 +0200 Subject: [PATCH 03/27] Implemented methods GetImage() and GetRawImage(). --- src/FPS_GT511C3.cpp | 32 ++++++++++++++++++++++++-------- src/FPS_GT511C3.h | 18 ++++++------------ 2 files changed, 30 insertions(+), 20 deletions(-) diff --git a/src/FPS_GT511C3.cpp b/src/FPS_GT511C3.cpp index 1703f5b..c29089d 100644 --- a/src/FPS_GT511C3.cpp +++ b/src/FPS_GT511C3.cpp @@ -730,12 +730,28 @@ bool FPS_GT511C3::CaptureFinger(bool highquality) } -// Gets an image that is qvga 160x120 (19200 bytes) and returns it in 150 Data_Packets -// Use StartDataDownload, and then GetNextDataPacket until done -// Returns: True (device confirming download starting) - // Not implemented due to memory restrictions on the arduino - // may revisit this if I find a need for it -/*bool FPS_GT511C3::GetRawImage() +// Gets an image that is 258x202 (52116 bytes) and sends it over serial +// Returns: True (device confirming download) +bool FPS_GT511C3::GetImage() +{ + if (UseSerialDebug) Serial.println("FPS - GetImage"); + Command_Packet* cp = new Command_Packet(); + cp->Command = Command_Packet::Commands::GetRawImage; + byte* packetbytes = cp->GetPacketBytes(); + delete cp; + SendCommand(packetbytes, 12); + Response_Packet* rp = GetResponse(); + bool retval = rp->ACK; + delete rp; + delete packetbytes; + GetData(52116); + return retval; + +} + +// Gets an image that is qvga 160x120 (19200 bytes) and sends it over serial +// Returns: True (device confirming download) +bool FPS_GT511C3::GetRawImage() { if (UseSerialDebug) Serial.println("FPS - GetRawImage"); Command_Packet* cp = new Command_Packet(); @@ -747,10 +763,10 @@ bool FPS_GT511C3::CaptureFinger(bool highquality) bool retval = rp->ACK; delete rp; delete packetbytes; + GetData(19200); return retval; - //return false; -}*/ +} #ifndef __GNUC__ #pragma endregion #endif //__GNUC__ diff --git a/src/FPS_GT511C3.h b/src/FPS_GT511C3.h index bb33967..a3efc3c 100644 --- a/src/FPS_GT511C3.h +++ b/src/FPS_GT511C3.h @@ -303,19 +303,13 @@ class FPS_GT511C3 #ifndef __GNUC__ #pragma region -= Not implemented commands =- #endif //__GNUC__ - // Gets an image that is 258x202 (52116 bytes) and returns it in 407 Data_Packets - // Use StartDataDownload, and then GetNextDataPacket until done - // Returns: True (device confirming download starting) - // Not implemented due to memory restrictions on the arduino - // may revisit this if I find a need for it - //bool GetImage(); + // Gets an image that is 258x202 (52116 bytes) and sends it over serial + // Returns: True (device confirming download) + bool GetImage(); - // Gets an image that is qvga 160x120 (19200 bytes) and returns it in 150 Data_Packets - // Use StartDataDownload, and then GetNextDataPacket until done - // Returns: True (device confirming download starting) - // Not implemented due to memory restrictions on the arduino - // may revisit this if I find a need for it - //bool GetRawImage(); + // Gets an image that is qvga 160x120 (19200 bytes) and sends it over serial + // Returns: True (device confirming download) + bool GetRawImage(); // Gets a template from the fps (498 bytes) in 4 Data_Packets // Use StartDataDownload, and then GetNextDataPacket until done From 4d01c32a14eb1c2e737984d44d5a2e3a328eee24 Mon Sep 17 00:00:00 2001 From: Fasgort Date: Sun, 8 Apr 2018 01:48:45 +0200 Subject: [PATCH 04/27] Updated library info. --- library.json | 2 +- library.properties | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/library.json b/library.json index 0911d5a..e19bb09 100644 --- a/library.json +++ b/library.json @@ -5,7 +5,7 @@ "repository": { "type": "git", - "url": "https://github.com/sparkfun/Fingerprint_Scanner-TTL.git" + "url": "https://github.com/Fasgort/Fingerprint_Scanner-TTL.git" }, "version": "1.1.1", "frameworks": "arduino", diff --git a/library.properties b/library.properties index d6bf25b..d9c6802 100644 --- a/library.properties +++ b/library.properties @@ -1,9 +1,9 @@ name=Fingerprint Scanner TTL version=1.1.0 -author=Josh Hawley -maintainer=SparkFun Electronics +author=Josh Hawley, modified by David López Chica +maintainer=David López Chica sentence=Arduino examples for ADH-Tech's Fingerprint Scanners. paragraph=This is a great fingerprint module from ADH-Tech that communicates over 3.3V TTL Serial so you can easily embed it into your next project. This repository contains Arduino example code to work with it. This code has been tested with GT-521F32, GT-521F52, GT-511C3, and GT-511C1R. category=Sensors -url=https://github.com/sparkfun/Fingerprint_Scanner-TTL +url=https://github.com/Fasgort/Fingerprint_Scanner-TTL architectures=* From 8e5fe6ae1d7befb190ea5465539837d86fa5f879 Mon Sep 17 00:00:00 2001 From: Fasgort Date: Sun, 8 Apr 2018 02:21:23 +0200 Subject: [PATCH 05/27] Bugfix. --- src/FPS_GT511C3.cpp | 62 ++++++++++++++++++++++++++------------------- src/FPS_GT511C3.h | 7 +++-- 2 files changed, 41 insertions(+), 28 deletions(-) diff --git a/src/FPS_GT511C3.cpp b/src/FPS_GT511C3.cpp index c29089d..42fd5c1 100644 --- a/src/FPS_GT511C3.cpp +++ b/src/FPS_GT511C3.cpp @@ -222,23 +222,23 @@ Data_Packet::Data_Packet(byte* buffer, bool UseSerialDebug) CheckParsing(buffer[2], DATA_DEVICE_ID_1, DATA_DEVICE_ID_1, "DATA_DEVICE_ID_1", UseSerialDebug); CheckParsing(buffer[3], DATA_DEVICE_ID_2, DATA_DEVICE_ID_2, "DATA_DEVICE_ID_2", UseSerialDebug); - Data_Packet.checksum = CalculateChecksum(buffer, 4); + this->checksum = CalculateChecksum(buffer, 4); } // Get a data packet (128 bytes), calculate checksum and send it to serial -Data_Packet::GetData(byte* buffer, bool UseSerialDebug) +void Data_Packet::GetData(byte* buffer, bool UseSerialDebug) { - FPS_GT511C3.SendToSerial(buffer, 128); - Data_Packet.checksum = CalculateChecksum(buffer, 128); + SendToSerial(buffer, 128); + this->checksum = CalculateChecksum(buffer, 128); } // Get the last data packet (<=128 bytes), calculate checksum, validate checksum received and send it to serial -Data_Packet::GetLastData(byte* buffer, int length, bool UseSerialDebug) +void Data_Packet::GetLastData(byte* buffer, int length, bool UseSerialDebug) { - FPS_GT511C3.SendToSerial(buffer, length-2); - Data_Packet.checksum = CalculateChecksum(buffer, length); - byte checksum_low = GetLowByte(Data_Packet.checksum); - byte checksum_high = GetHighByte(Data_Packet.checksum); + SendToSerial(buffer, length-2); + this->checksum = CalculateChecksum(buffer, length); + byte checksum_low = GetLowByte(this->checksum); + byte checksum_high = GetHighByte(this->checksum); CheckParsing(buffer[length-2], checksum_low, checksum_low, "Checksum_LOW", UseSerialDebug); CheckParsing(buffer[length-1], checksum_high, checksum_high, "Checksum_HIGH", UseSerialDebug); } @@ -264,18 +264,7 @@ bool Data_Packet::CheckParsing(byte b, byte propervalue, byte alternatevalue, co // calculates the checksum from the bytes in the packet word Data_Packet::CalculateChecksum(byte* buffer, int length) { - word checksum = Data_Packet.checksum; - for (int i=0; ichecksum; for (int i=0; iGetData(data, UseSerialDebug); if(UseSerialDebug) { Serial.print("FPS - RECV: "); @@ -958,7 +968,7 @@ void FPS_GT511C3::GetData(int length) while (_serial.available() == false) delay(10); lastdata[i]= (byte) _serial.read(); } - dp.GetLastData(lastdata, lastPacketSize, UseSerialDebug); + dp->GetLastData(lastdata, lastPacketSize, UseSerialDebug); if(UseSerialDebug) { Serial.print("FPS - RECV: "); diff --git a/src/FPS_GT511C3.h b/src/FPS_GT511C3.h index a3efc3c..48571ad 100644 --- a/src/FPS_GT511C3.h +++ b/src/FPS_GT511C3.h @@ -156,13 +156,16 @@ class Data_Packet static const byte DATA_START_CODE_2 = 0xA5; // Static byte to mark the beginning of a data packet - never changes static const byte DATA_DEVICE_ID_1 = 0x01; // Device ID Byte 1 (lesser byte) - theoretically never changes static const byte DATA_DEVICE_ID_2 = 0x00; // Device ID Byte 2 (greater byte) -private: - void GetData(byte* buffer, bool UseSerialDebug); + + void GetData(byte* buffer, bool UseSerialDebug); void GetLastData(byte* buffer, int length, bool UseSerialDebug); +private: bool CheckParsing(byte b, byte propervalue, byte alternatevalue, const char* varname, bool UseSerialDebug); word CalculateChecksum(byte* buffer, int length); byte GetHighByte(word w); byte GetLowByte(word w); + void serialPrintHex(byte data); + void SendToSerial(byte data[], int length); }; #ifndef __GNUC__ #pragma endregion From 385d74b5ceaa1ee43d350b76df3e0a6b0d2035c3 Mon Sep 17 00:00:00 2001 From: Fasgort Date: Sun, 8 Apr 2018 02:25:44 +0200 Subject: [PATCH 06/27] Moved implemented methods to the correct section. --- src/FPS_GT511C3.h | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/FPS_GT511C3.h b/src/FPS_GT511C3.h index 48571ad..f27a022 100644 --- a/src/FPS_GT511C3.h +++ b/src/FPS_GT511C3.h @@ -299,21 +299,21 @@ class FPS_GT511C3 // 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); -#ifndef __GNUC__ - #pragma endregion -#endif //__GNUC__ -#ifndef __GNUC__ - #pragma region -= Not implemented commands =- -#endif //__GNUC__ - // Gets an image that is 258x202 (52116 bytes) and sends it over serial + // Gets an image that is 258x202 (52116 bytes) and sends it over serial // Returns: True (device confirming download) bool GetImage(); // Gets an image that is qvga 160x120 (19200 bytes) and sends it over serial // Returns: True (device confirming download) bool GetRawImage(); +#ifndef __GNUC__ + #pragma endregion +#endif //__GNUC__ +#ifndef __GNUC__ + #pragma region -= Not implemented commands =- +#endif //__GNUC__ // Gets a template from the fps (498 bytes) in 4 Data_Packets // Use StartDataDownload, and then GetNextDataPacket until done // Parameter: 0-199 ID number From 925db688096803a5ff8fc6e05de050520cb41fa9 Mon Sep 17 00:00:00 2001 From: Fasgort Date: Sun, 8 Apr 2018 03:47:10 +0200 Subject: [PATCH 07/27] Bugfix in ChangeBaudRate. NOTE: Something is not right yet. Further debugging needed. --- src/FPS_GT511C3.cpp | 2 +- src/FPS_GT511C3.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/FPS_GT511C3.cpp b/src/FPS_GT511C3.cpp index 42fd5c1..6f3d4c4 100644 --- a/src/FPS_GT511C3.cpp +++ b/src/FPS_GT511C3.cpp @@ -416,7 +416,7 @@ bool FPS_GT511C3::ChangeBaudRate(unsigned long baud) if (UseSerialDebug) Serial.println("FPS - ChangeBaudRate"); Command_Packet* cp = new Command_Packet(); - cp->Command = Command_Packet::Commands::Open; + cp->Command = Command_Packet::Commands::ChangeBaudRate; cp->ParameterFromInt(baud); byte* packetbytes = cp->GetPacketBytes(); delete cp; diff --git a/src/FPS_GT511C3.h b/src/FPS_GT511C3.h index f27a022..c5412b9 100644 --- a/src/FPS_GT511C3.h +++ b/src/FPS_GT511C3.h @@ -29,7 +29,7 @@ class Command_Packet 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 + ChangeBaudRate = 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 From 400ff3bc5bdb52c95f2ea32dc65a40ca5ed192f4 Mon Sep 17 00:00:00 2001 From: Fasgort Date: Sun, 8 Apr 2018 20:16:30 +0200 Subject: [PATCH 08/27] - Changed variable types to fixed types. - Fixed baudrate method. (SEE NEXT). - Fixed variable type used for parameter (used 2-byte type, it required 4-byte type). - Some minor memory optimizations done. --- src/FPS_GT511C3.cpp | 251 ++++++++++++++++++++++---------------------- src/FPS_GT511C3.h | 111 ++++++++++---------- 2 files changed, 179 insertions(+), 183 deletions(-) diff --git a/src/FPS_GT511C3.cpp b/src/FPS_GT511C3.cpp index 6f3d4c4..f010059 100644 --- a/src/FPS_GT511C3.cpp +++ b/src/FPS_GT511C3.cpp @@ -14,16 +14,16 @@ // returns the 12 bytes of the generated command packet // remember to call delete on the returned array -byte* Command_Packet::GetPacketBytes() +uint8_t* Command_Packet::GetPacketBytes() { - byte* packetbytes= new byte[12]; + uint8_t* packetbytes= new uint8_t[12]; // update command before calculating checksum (important!) - word cmd = Command; + uint16_t cmd = Command; command[0] = GetLowByte(cmd); command[1] = GetHighByte(cmd); - word checksum = _CalculateChecksum(); + uint16_t checksum = _CalculateChecksum(); packetbytes[0] = COMMAND_START_CODE_1; packetbytes[1] = COMMAND_START_CODE_2; @@ -41,30 +41,30 @@ byte* Command_Packet::GetPacketBytes() return packetbytes; } -// Converts the int to bytes and puts them into the paramter array -void Command_Packet::ParameterFromInt(int i) +// Converts the uint32_t to bytes and puts them into the parameter array +void Command_Packet::ParameterFrom(uint32_t u) { - Parameter[0] = (i & 0x000000ff); - Parameter[1] = (i & 0x0000ff00) >> 8; - Parameter[2] = (i & 0x00ff0000) >> 16; - Parameter[3] = (i & 0xff000000) >> 24; + Parameter[0] = (u & 0x000000ff); + Parameter[1] = (u & 0x0000ff00) >> 8; + Parameter[2] = (u & 0x00ff0000) >> 16; + Parameter[3] = (u & 0xff000000) >> 24; } // Returns the high byte from a word -byte Command_Packet::GetHighByte(word w) +uint8_t Command_Packet::GetHighByte(uint16_t w) { - return (byte)(w>>8)&0x00FF; + return (uint8_t)(w>>8)&0x00FF; } // Returns the low byte from a word -byte Command_Packet::GetLowByte(word w) +uint8_t Command_Packet::GetLowByte(uint16_t w) { - return (byte)w&0x00FF; + return (uint8_t)w&0x00FF; } -word Command_Packet::_CalculateChecksum() +uint16_t Command_Packet::_CalculateChecksum() { - word w = 0; + uint16_t w = 0; w += COMMAND_START_CODE_1; w += COMMAND_START_CODE_2; w += COMMAND_DEVICE_ID_1; @@ -90,7 +90,7 @@ Command_Packet::Command_Packet() #pragma region -= Response_Packet Definitions =- #endif //__GNUC__ // creates and parses a response packet from the finger print scanner -Response_Packet::Response_Packet(byte* buffer, bool UseSerialDebug) +Response_Packet::Response_Packet(uint8_t* buffer, bool UseSerialDebug) { CheckParsing(buffer[0], COMMAND_START_CODE_1, COMMAND_START_CODE_1, "COMMAND_START_CODE_1", UseSerialDebug); CheckParsing(buffer[1], COMMAND_START_CODE_2, COMMAND_START_CODE_2, "COMMAND_START_CODE_2", UseSerialDebug); @@ -100,9 +100,9 @@ Response_Packet::Response_Packet(byte* buffer, bool UseSerialDebug) if (buffer[8] == 0x30) ACK = true; else ACK = false; CheckParsing(buffer[9], 0x00, 0x00, "AckNak_HIGH", UseSerialDebug); - word checksum = CalculateChecksum(buffer, 10); - byte checksum_low = GetLowByte(checksum); - byte checksum_high = GetHighByte(checksum); + uint16_t checksum = CalculateChecksum(buffer, 10); + uint8_t checksum_low = GetLowByte(checksum); + uint8_t checksum_high = GetHighByte(checksum); CheckParsing(buffer[10], checksum_low, checksum_low, "Checksum_LOW", UseSerialDebug); CheckParsing(buffer[11], checksum_high, checksum_high, "Checksum_HIGH", UseSerialDebug); @@ -121,7 +121,7 @@ Response_Packet::Response_Packet(byte* buffer, bool UseSerialDebug) } // 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) +Response_Packet::ErrorCodes::Errors_Enum Response_Packet::ErrorCodes::ParseFromBytes(uint8_t high, uint8_t low) { Errors_Enum e = INVALID; if (high == 0x00) @@ -157,10 +157,10 @@ Response_Packet::ErrorCodes::Errors_Enum Response_Packet::ErrorCodes::ParseFromB return e; } -// Gets an int from the parameter bytes -int Response_Packet::IntFromParameter() +// Gets a uint32_t from the parameter bytes +uint32_t Response_Packet::FromParameter() { - int retval = 0; + uint32_t retval = 0; retval = (retval << 8) + ParameterBytes[3]; retval = (retval << 8) + ParameterBytes[2]; retval = (retval << 8) + ParameterBytes[1]; @@ -169,7 +169,7 @@ int Response_Packet::IntFromParameter() } // 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, const char* varname, bool UseSerialDebug) +bool Response_Packet::CheckParsing(uint8_t b, uint8_t propervalue, uint8_t alternatevalue, const char* varname, bool UseSerialDebug) { bool retval = (b != propervalue) && (b != alternatevalue); if ((UseSerialDebug) && (retval)) @@ -187,10 +187,10 @@ bool Response_Packet::CheckParsing(byte b, byte propervalue, byte alternatevalue } // calculates the checksum from the bytes in the packet -word Response_Packet::CalculateChecksum(byte* buffer, int length) +uint16_t Response_Packet::CalculateChecksum(uint8_t* buffer, uint16_t length) { - word checksum = 0; - for (int i=0; i>8)&0x00FF; + return (uint8_t)(w>>8)&0x00FF; } // Returns the low byte from a word -byte Response_Packet::GetLowByte(word w) +uint8_t Response_Packet::GetLowByte(uint16_t w) { - return (byte)w&0x00FF; + return (uint8_t)w&0x00FF; } #ifndef __GNUC__ #pragma endregion @@ -215,7 +215,7 @@ byte Response_Packet::GetLowByte(word w) #ifndef __GNUC__ #pragma region -= Data_Packet =- #endif //__GNUC__ -Data_Packet::Data_Packet(byte* buffer, bool UseSerialDebug) +Data_Packet::Data_Packet(uint8_t* buffer, bool UseSerialDebug) { CheckParsing(buffer[0], DATA_START_CODE_1, DATA_START_CODE_1, "DATA_START_CODE_1", UseSerialDebug); CheckParsing(buffer[1], DATA_START_CODE_2, DATA_START_CODE_2, "DATA_START_CODE_2", UseSerialDebug); @@ -226,25 +226,25 @@ Data_Packet::Data_Packet(byte* buffer, bool UseSerialDebug) } // Get a data packet (128 bytes), calculate checksum and send it to serial -void Data_Packet::GetData(byte* buffer, bool UseSerialDebug) +void Data_Packet::GetData(uint8_t* buffer, bool UseSerialDebug) { SendToSerial(buffer, 128); this->checksum = CalculateChecksum(buffer, 128); } // Get the last data packet (<=128 bytes), calculate checksum, validate checksum received and send it to serial -void Data_Packet::GetLastData(byte* buffer, int length, bool UseSerialDebug) +void Data_Packet::GetLastData(uint8_t* buffer, uint16_t length, bool UseSerialDebug) { SendToSerial(buffer, length-2); this->checksum = CalculateChecksum(buffer, length); - byte checksum_low = GetLowByte(this->checksum); - byte checksum_high = GetHighByte(this->checksum); + uint8_t checksum_low = GetLowByte(this->checksum); + uint8_t checksum_high = GetHighByte(this->checksum); CheckParsing(buffer[length-2], checksum_low, checksum_low, "Checksum_LOW", UseSerialDebug); CheckParsing(buffer[length-1], checksum_high, checksum_high, "Checksum_HIGH", UseSerialDebug); } // checks to see if the byte is the proper value, and logs it to the serial channel if not -bool Data_Packet::CheckParsing(byte b, byte propervalue, byte alternatevalue, const char* varname, bool UseSerialDebug) +bool Data_Packet::CheckParsing(uint8_t b, uint8_t propervalue, uint8_t alternatevalue, const char* varname, bool UseSerialDebug) { bool retval = (b != propervalue) && (b != alternatevalue); if ((UseSerialDebug) && (retval)) @@ -262,10 +262,10 @@ bool Data_Packet::CheckParsing(byte b, byte propervalue, byte alternatevalue, co } // calculates the checksum from the bytes in the packet -word Data_Packet::CalculateChecksum(byte* buffer, int length) +uint16_t Data_Packet::CalculateChecksum(uint8_t* buffer, uint16_t length) { - word checksum = this->checksum; - for (int i=0; ichecksum; + for (uint16_t i=0; i>8)&0x00FF; + return (uint8_t)(w>>8)&0x00FF; } // Returns the low byte from a word -byte Data_Packet::GetLowByte(word w) +uint8_t Data_Packet::GetLowByte(uint16_t w) { - return (byte)w&0x00FF; + return (uint8_t)w&0x00FF; } // sends a byte to the serial debugger in the hex format we want EX "0F" -void Data_Packet::serialPrintHex(byte data) +void Data_Packet::serialPrintHex(uint8_t data) { char tmp[16]; sprintf(tmp, "%.2X",data); Serial.print(tmp); } -// sends the bye aray to the serial debugger in our hex format EX: "00 AF FF 10 00 13" -void Data_Packet::SendToSerial(byte data[], int length) +// sends the byte array to the serial debugger in our hex format EX: "00 AF FF 10 00 13" +void Data_Packet::SendToSerial(uint8_t data[], uint16_t length) { boolean first=true; Serial.print("\""); - for(int i=0; iUseSerialDebug = false; }; @@ -347,7 +347,7 @@ void FPS_GT511C3::Open() cp->Parameter[1] = 0x00; cp->Parameter[2] = 0x00; cp->Parameter[3] = 0x00; - byte* packetbytes = cp->GetPacketBytes(); + uint8_t* packetbytes = cp->GetPacketBytes(); delete cp; SendCommand(packetbytes, 12); Response_Packet* rp = GetResponse(); @@ -366,7 +366,7 @@ void FPS_GT511C3::Close() cp->Parameter[1] = 0x00; cp->Parameter[2] = 0x00; cp->Parameter[3] = 0x00; - byte* packetbytes = cp->GetPacketBytes(); + uint8_t* packetbytes = cp->GetPacketBytes(); delete cp; SendCommand(packetbytes, 12); Response_Packet* rp = GetResponse(); @@ -394,7 +394,7 @@ bool FPS_GT511C3::SetLED(bool on) cp->Parameter[1] = 0x00; cp->Parameter[2] = 0x00; cp->Parameter[3] = 0x00; - byte* packetbytes = cp->GetPacketBytes(); + uint8_t* packetbytes = cp->GetPacketBytes(); delete cp; SendCommand(packetbytes, 12); Response_Packet* rp = GetResponse(); @@ -409,25 +409,21 @@ bool FPS_GT511C3::SetLED(bool on) // 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 FPS_GT511C3::ChangeBaudRate(unsigned long baud) +bool FPS_GT511C3::ChangeBaudRate(uint32_t baud) { - if ((baud == 9600) || (baud == 19200) || (baud == 38400) || (baud == 57600) || (baud == 115200)) + if ((baud == 9600) || (baud == 19200) || (baud == 38400) || (baud == 57600) || (baud == 115200)) { if (UseSerialDebug) Serial.println("FPS - ChangeBaudRate"); Command_Packet* cp = new Command_Packet(); cp->Command = Command_Packet::Commands::ChangeBaudRate; - cp->ParameterFromInt(baud); - byte* packetbytes = cp->GetPacketBytes(); + cp->ParameterFrom(baud); + uint8_t* packetbytes = cp->GetPacketBytes(); delete cp; SendCommand(packetbytes, 12); Response_Packet* rp = GetResponse(); bool retval = rp->ACK; - if (retval) - { - _serial.end(); - _serial.begin(baud); - } + if (retval) _serial.begin(baud); delete rp; delete packetbytes; return retval; @@ -437,7 +433,7 @@ bool FPS_GT511C3::ChangeBaudRate(unsigned long baud) // Gets the number of enrolled fingerprints // Return: The total number of enrolled fingerprints -int FPS_GT511C3::GetEnrollCount() +uint16_t FPS_GT511C3::GetEnrollCount() { if (UseSerialDebug) Serial.println("FPS - GetEnrolledCount"); Command_Packet* cp = new Command_Packet(); @@ -446,12 +442,12 @@ int FPS_GT511C3::GetEnrollCount() cp->Parameter[1] = 0x00; cp->Parameter[2] = 0x00; cp->Parameter[3] = 0x00; - byte* packetbytes = cp->GetPacketBytes(); + uint8_t* packetbytes = cp->GetPacketBytes(); delete cp; SendCommand(packetbytes, 12); Response_Packet* rp = GetResponse(); - int retval = rp->IntFromParameter(); + uint32_t retval = rp->FromParameter(); delete rp; delete packetbytes; return retval; @@ -461,13 +457,13 @@ int FPS_GT511C3::GetEnrollCount() // Parameter: 0-2999, if using GT-521F52 // 0-199, if using GT-521F32/GT-511C3 // Return: True if the ID number is enrolled, false if not -bool FPS_GT511C3::CheckEnrolled(int id) +bool FPS_GT511C3::CheckEnrolled(uint16_t id) { if (UseSerialDebug) Serial.println("FPS - CheckEnrolled"); Command_Packet* cp = new Command_Packet(); cp->Command = Command_Packet::Commands::CheckEnrolled; - cp->ParameterFromInt(id); - byte* packetbytes = cp->GetPacketBytes(); + cp->ParameterFrom(id); + uint8_t* packetbytes = cp->GetPacketBytes(); delete cp; SendCommand(packetbytes, 12); delete packetbytes; @@ -486,18 +482,18 @@ bool FPS_GT511C3::CheckEnrolled(int id) // 1 - Database is full // 2 - Invalid Position // 3 - Position(ID) is already used -int FPS_GT511C3::EnrollStart(int id) +uint8_t FPS_GT511C3::EnrollStart(uint16_t id) { if (UseSerialDebug) Serial.println("FPS - EnrollStart"); Command_Packet* cp = new Command_Packet(); cp->Command = Command_Packet::Commands::EnrollStart; - cp->ParameterFromInt(id); - byte* packetbytes = cp->GetPacketBytes(); + cp->ParameterFrom(id); + uint8_t* packetbytes = cp->GetPacketBytes(); delete cp; SendCommand(packetbytes, 12); delete packetbytes; Response_Packet* rp = GetResponse(); - int retval = 0; + uint8_t retval = 0; if (rp->ACK == false) { if (rp->Error == Response_Packet::ErrorCodes::NACK_DB_IS_FULL) retval = 1; @@ -514,17 +510,17 @@ int FPS_GT511C3::EnrollStart(int id) // 1 - Enroll Failed // 2 - Bad finger // 3 - ID in use -int FPS_GT511C3::Enroll1() +uint8_t FPS_GT511C3::Enroll1() { if (UseSerialDebug) Serial.println("FPS - Enroll1"); Command_Packet* cp = new Command_Packet(); cp->Command = Command_Packet::Commands::Enroll1; - byte* packetbytes = cp->GetPacketBytes(); + uint8_t* packetbytes = cp->GetPacketBytes(); delete cp; SendCommand(packetbytes, 12); delete packetbytes; Response_Packet* rp = GetResponse(); - int retval = rp->IntFromParameter(); + uint32_t retval = rp->FromParameter(); //Change to "retval < 3000", if using GT-521F52 //Leave "reval < 200", if using GT-521F32/GT-511C3 if (retval < 200) retval = 3; else retval = 0; @@ -543,7 +539,7 @@ int FPS_GT511C3::Enroll1() // 1 - Enroll Failed // 2 - Bad finger // 3 - ID in use -int FPS_GT511C3::Enroll2() +uint8_t FPS_GT511C3::Enroll2() { if (UseSerialDebug) Serial.println("FPS - Enroll2"); Command_Packet* cp = new Command_Packet(); @@ -553,7 +549,7 @@ int FPS_GT511C3::Enroll2() SendCommand(packetbytes, 12); delete packetbytes; Response_Packet* rp = GetResponse(); - int retval = rp->IntFromParameter(); + uint32_t retval = rp->FromParameter(); //Change to "retval < 3000", if using GT-521F52 //Leave "reval < 200", if using GT-521F32/GT-511C3 if (retval < 200) retval = 3; else retval = 0; @@ -573,7 +569,7 @@ int FPS_GT511C3::Enroll2() // 1 - Enroll Failed // 2 - Bad finger // 3 - ID in use -int FPS_GT511C3::Enroll3() +uint8_t FPS_GT511C3::Enroll3() { if (UseSerialDebug) Serial.println("FPS - Enroll3"); Command_Packet* cp = new Command_Packet(); @@ -583,7 +579,7 @@ int FPS_GT511C3::Enroll3() SendCommand(packetbytes, 12); delete packetbytes; Response_Packet* rp = GetResponse(); - int retval = rp->IntFromParameter(); + uint32_t retval = rp->FromParameter(); //Change to "retval < 3000", if using GT-521F52 //Leave "reval < 200", if using GT-521F32/GT-511C3 if (retval < 200) retval = 3; else retval = 0; @@ -603,16 +599,17 @@ bool FPS_GT511C3::IsPressFinger() if (UseSerialDebug) Serial.println("FPS - IsPressFinger"); Command_Packet* cp = new Command_Packet(); cp->Command = Command_Packet::Commands::IsPressFinger; - byte* packetbytes = cp->GetPacketBytes(); + uint8_t* packetbytes = cp->GetPacketBytes(); delete cp; SendCommand(packetbytes, 12); Response_Packet* rp = GetResponse(); bool retval = false; - int pval = rp->ParameterBytes[0]; +/* int pval = rp->ParameterBytes[0]; pval += rp->ParameterBytes[1]; pval += rp->ParameterBytes[2]; pval += rp->ParameterBytes[3]; - if (pval == 0) retval = true; + if (pval == 0) retval = true; */ + if (!rp->ParameterBytes[0] && !rp->ParameterBytes[1] && !rp->ParameterBytes[2] && !rp->ParameterBytes[3]) retval = true; delete rp; delete packetbytes; return retval; @@ -622,13 +619,13 @@ bool FPS_GT511C3::IsPressFinger() // Parameter: 0-2999, if using GT-521F52 (id number to be deleted) // 0-199, if using GT-521F32/GT-511C3(id number to be deleted) // Returns: true if successful, false if position invalid -bool FPS_GT511C3::DeleteID(int id) +bool FPS_GT511C3::DeleteID(uint16_t id) { if (UseSerialDebug) Serial.println("FPS - DeleteID"); Command_Packet* cp = new Command_Packet(); cp->Command = Command_Packet::Commands::DeleteID; - cp->ParameterFromInt(id); - byte* packetbytes = cp->GetPacketBytes(); + cp->ParameterFrom(id); + uint8_t* packetbytes = cp->GetPacketBytes(); delete cp; SendCommand(packetbytes, 12); Response_Packet* rp = GetResponse(); @@ -645,7 +642,7 @@ bool FPS_GT511C3::DeleteAll() if (UseSerialDebug) Serial.println("FPS - DeleteAll"); Command_Packet* cp = new Command_Packet(); cp->Command = Command_Packet::Commands::DeleteAll; - byte* packetbytes = cp->GetPacketBytes(); + uint8_t* packetbytes = cp->GetPacketBytes(); SendCommand(packetbytes, 12); Response_Packet* rp = GetResponse(); bool retval = rp->ACK; @@ -663,17 +660,17 @@ bool FPS_GT511C3::DeleteAll() // 1 - Invalid Position // 2 - ID is not in use // 3 - Verified FALSE (not the correct finger) -int FPS_GT511C3::Verify1_1(int id) +uint8_t FPS_GT511C3::Verify1_1(uint16_t id) { if (UseSerialDebug) Serial.println("FPS - Verify1_1"); Command_Packet* cp = new Command_Packet(); cp->Command = Command_Packet::Commands::Verify1_1; - cp->ParameterFromInt(id); - byte* packetbytes = cp->GetPacketBytes(); + cp->ParameterFrom(id); + uint8_t* packetbytes = cp->GetPacketBytes(); delete cp; SendCommand(packetbytes, 12); Response_Packet* rp = GetResponse(); - int retval = 0; + uint8_t retval = 0; if (rp->ACK == false) { retval = 3; // grw 01/03/15 - set default value of not verified before assignment @@ -694,16 +691,16 @@ int FPS_GT511C3::Verify1_1(int id) // Failed to find the fingerprint in the database // 3000, if using GT-521F52 // 200, if using GT-521F32/GT-511C3 -int FPS_GT511C3::Identify1_N() +uint16_t FPS_GT511C3::Identify1_N() { if (UseSerialDebug) Serial.println("FPS - Identify1_N"); Command_Packet* cp = new Command_Packet(); cp->Command = Command_Packet::Commands::Identify1_N; - byte* packetbytes = cp->GetPacketBytes(); + uint8_t* packetbytes = cp->GetPacketBytes(); delete cp; SendCommand(packetbytes, 12); Response_Packet* rp = GetResponse(); - int retval = rp->IntFromParameter(); + uint32_t retval = rp->FromParameter(); //Change to "retval > 3000" and "retval = 3000", if using GT-521F52 //Leave "reval > 200" and "retval = 200", if using GT-521F32/GT-511C3 if (retval > 200) retval = 200; @@ -723,13 +720,13 @@ bool FPS_GT511C3::CaptureFinger(bool highquality) cp->Command = Command_Packet::Commands::CaptureFinger; if (highquality) { - cp->ParameterFromInt(1); + cp->ParameterFrom(1); } else { - cp->ParameterFromInt(0); + cp->ParameterFrom(0); } - byte* packetbytes = cp->GetPacketBytes(); + uint8_t* packetbytes = cp->GetPacketBytes(); delete cp; SendCommand(packetbytes, 12); Response_Packet* rp = GetResponse(); @@ -747,7 +744,7 @@ bool FPS_GT511C3::GetImage() if (UseSerialDebug) Serial.println("FPS - GetImage"); Command_Packet* cp = new Command_Packet(); cp->Command = Command_Packet::Commands::GetRawImage; - byte* packetbytes = cp->GetPacketBytes(); + uint8_t* packetbytes = cp->GetPacketBytes(); delete cp; SendCommand(packetbytes, 12); Response_Packet* rp = GetResponse(); @@ -766,7 +763,7 @@ bool FPS_GT511C3::GetRawImage() if (UseSerialDebug) Serial.println("FPS - GetRawImage"); Command_Packet* cp = new Command_Packet(); cp->Command = Command_Packet::Commands::GetRawImage; - byte* packetbytes = cp->GetPacketBytes(); + uint8_t* packetbytes = cp->GetPacketBytes(); delete cp; SendCommand(packetbytes, 12); Response_Packet* rp = GetResponse(); @@ -851,7 +848,7 @@ bool FPS_GT511C3::GetRawImage() #pragma region -= Private Methods =- #endif //__GNUC__ // Sends the command to the software serial channel -void FPS_GT511C3::SendCommand(byte cmd[], int length) +void FPS_GT511C3::SendCommand(uint8_t cmd[], uint16_t length) { _serial.write(cmd, length); if (UseSerialDebug) @@ -865,23 +862,23 @@ void FPS_GT511C3::SendCommand(byte cmd[], int length) // Gets the response to the command from the software serial channel (and waits for it) Response_Packet* FPS_GT511C3::GetResponse() { - byte firstbyte = 0; + uint8_t firstbyte = 0; bool done = false; _serial.listen(); while (done == false) { - firstbyte = (byte)_serial.read(); + firstbyte = (uint8_t)_serial.read(); if (firstbyte == Response_Packet::COMMAND_START_CODE_1) { done = true; } } - byte* resp = new byte[12]; + uint8_t* resp = new uint8_t[12]; resp[0] = firstbyte; - for (int i=1; i < 12; i++) + for (uint8_t i=1; i < 12; i++) { while (_serial.available() == false) delay(10); - resp[i]= (byte) _serial.read(); + resp[i]= (uint8_t) _serial.read(); } Response_Packet* rp = new Response_Packet(resp, UseSerialDebug); delete resp; @@ -897,18 +894,18 @@ Response_Packet* FPS_GT511C3::GetResponse() // Gets the data (length bytes) from the software serial channel (and waits for it) // and sends it over serial sommunications -void FPS_GT511C3::GetData(int length) +void FPS_GT511C3::GetData(uint16_t length) { - byte firstbyte = 0; - byte secondbyte = 0; + uint8_t firstbyte = 0; + uint8_t secondbyte = 0; bool done = false; _serial.listen(); while (done == false) { - firstbyte = (byte)_serial.read(); + firstbyte = (uint8_t)_serial.read(); if (firstbyte == Data_Packet::DATA_START_CODE_1) { - secondbyte = (byte)_serial.read(); + secondbyte = (uint8_t)_serial.read(); if (secondbyte == Data_Packet::DATA_START_CODE_2) { done = true; @@ -916,13 +913,13 @@ void FPS_GT511C3::GetData(int length) } } - byte* firstdata = new byte[4]; + uint8_t* firstdata = new uint8_t[4]; firstdata[0] = firstbyte; firstdata[1] = secondbyte; - for (int i=2; i < 4; i++) + for (uint8_t i=2; i < 4; i++) { while (_serial.available() == false) delay(10); - firstdata[i]= (byte) _serial.read(); + firstdata[i]= (uint8_t) _serial.read(); } Data_Packet* dp = new Data_Packet(firstdata, UseSerialDebug); if(UseSerialDebug) @@ -934,22 +931,22 @@ void FPS_GT511C3::GetData(int length) } delete firstdata; - int numberPacketsNeeded = (length-4) / 128; + uint16_t numberPacketsNeeded = (length-4) / 128; bool smallLastPacket = false; - int lastPacketSize = (length-4) % 128; + uint8_t lastPacketSize = (length-4) % 128; if(lastPacketSize != 0) { numberPacketsNeeded++; smallLastPacket = true; } - for (int packetCount=1; packetCount < numberPacketsNeeded; packetCount++) + uint8_t* data = new uint8_t[128]; + for (uint16_t packetCount=1; packetCount < numberPacketsNeeded; packetCount++) { - byte* data = new byte[128]; - for (int i=0; i < 128; i++) + for (uint8_t i=0; i < 128; i++) { while (_serial.available() == false) delay(10); - data[i]= (byte) _serial.read(); + data[i]= (uint8_t) _serial.read(); } dp->GetData(data, UseSerialDebug); if(UseSerialDebug) @@ -959,14 +956,14 @@ void FPS_GT511C3::GetData(int length) Serial.println(); Serial.println(); } - delete data; } + delete data; - byte* lastdata = new byte[lastPacketSize]; - for (int i=0; i < lastPacketSize; i++) + uint8_t* lastdata = new uint8_t[lastPacketSize]; + for (uint8_t i=0; i < lastPacketSize; i++) { while (_serial.available() == false) delay(10); - lastdata[i]= (byte) _serial.read(); + lastdata[i]= (uint8_t) _serial.read(); } dp->GetLastData(lastdata, lastPacketSize, UseSerialDebug); if(UseSerialDebug) @@ -981,12 +978,12 @@ void FPS_GT511C3::GetData(int length) return; }; -// sends the bye aray to the serial debugger in our hex format EX: "00 AF FF 10 00 13" -void FPS_GT511C3::SendToSerial(byte data[], int length) +// sends the byte array to the serial debugger in our hex format EX: "00 AF FF 10 00 13" +void FPS_GT511C3::SendToSerial(uint8_t data[], uint16_t length) { boolean first=true; Serial.print("\""); - for(int i=0; i Date: Sun, 8 Apr 2018 23:45:27 +0200 Subject: [PATCH 09/27] API extended with a new function: You can now call the FPS constructor with the desired baud rate you want to establish communications, as additional parameter. Furthermore, comms won't fail while initializing if the FPS baud rate was established to something else than 9600. --- src/FPS_GT511C3.cpp | 122 ++++++++++++++++++++++++++++++++++++++++++-- src/FPS_GT511C3.h | 22 +++++--- 2 files changed, 134 insertions(+), 10 deletions(-) diff --git a/src/FPS_GT511C3.cpp b/src/FPS_GT511C3.cpp index f010059..31df1fe 100644 --- a/src/FPS_GT511C3.cpp +++ b/src/FPS_GT511C3.cpp @@ -316,13 +316,15 @@ void Data_Packet::SendToSerial(uint8_t data[], uint16_t length) #pragma region -= Constructor/Destructor =- #endif //__GNUC__ // Creates a new object to interface with the fingerprint scanner +// It will establish the communication to the desired baud rate if defined FPS_GT511C3::FPS_GT511C3(uint8_t rx, uint8_t tx, uint32_t baud) : _serial(rx,tx) { pin_RX = rx; pin_TX = tx; - _serial.begin(baud); this->UseSerialDebug = false; + this->Started = false; + desiredBaud = baud; }; // destructor @@ -338,8 +340,10 @@ FPS_GT511C3::~FPS_GT511C3() #pragma region -= Device Commands =- #endif //__GNUC__ //Initialises the device and gets ready for commands -void FPS_GT511C3::Open() +//Returns true if the communication established +bool FPS_GT511C3::Open() { + if (!Started) Start(); if (UseSerialDebug) Serial.println("FPS - Open"); Command_Packet* cp = new Command_Packet(); cp->Command = Command_Packet::Commands::Open; @@ -351,8 +355,11 @@ void FPS_GT511C3::Open() delete cp; SendCommand(packetbytes, 12); Response_Packet* rp = GetResponse(); + bool retval = true; + if (rp->ACK == false) retval = false; delete rp; delete packetbytes; + return retval; } // According to the DataSheet, this does nothing... @@ -413,8 +420,7 @@ bool FPS_GT511C3::ChangeBaudRate(uint32_t baud) { if ((baud == 9600) || (baud == 19200) || (baud == 38400) || (baud == 57600) || (baud == 115200)) { - - if (UseSerialDebug) Serial.println("FPS - ChangeBaudRate"); + if (UseSerialDebug) Serial.println("FPS - ChangeBaudRate"); Command_Packet* cp = new Command_Packet(); cp->Command = Command_Packet::Commands::ChangeBaudRate; cp->ParameterFrom(baud); @@ -847,6 +853,114 @@ bool FPS_GT511C3::GetRawImage() #ifndef __GNUC__ #pragma region -= Private Methods =- #endif //__GNUC__ +// Configures the device correctly for communications at the desired baud rate +void FPS_GT511C3::Start() +{ + 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; + uint8_t* packetbytes = cp->GetPacketBytes(); + delete cp; + + uint32_t baud = desiredBaud; + if (!(baud == 9600) && !(baud == 19200) && !(baud == 38400) && !(baud == 57600) && !(baud == 115200)) baud=9600; + uint32_t actualBaud = 0; + uint32_t BaudRates[5] = {9600, 19200, 38400, 57600, 115200}; + for(uint8_t i = 0; i<5; i++) // Trying to find FPS baud rate + { + if(UseSerialDebug) + { + Serial.print("Establishing connection with FPS at baud rate: "); + Serial.print(BaudRates[i]); + Serial.println(); + } + _serial.begin(BaudRates[i]); + _serial.listen(); + SendCommand(packetbytes, 12); + delay(100); + + uint8_t firstbyte = 0; + uint8_t secondbyte = 0; + bool done = false; + uint8_t byteCount = 0; + while (done == false && byteCount<100) + { + byteCount++; + if(_serial.peek() == -1) break; + firstbyte = (uint8_t)_serial.read(); + if (firstbyte == Response_Packet::COMMAND_START_CODE_1) + { + if(_serial.peek() == -1) break; + secondbyte = (uint8_t)_serial.read(); + if (secondbyte == Response_Packet::COMMAND_START_CODE_2) + { + done = true; + } + } + } + if (!done) + { + while (_serial.available()) _serial.read(); // Clear Serial buffer + } else + { + uint8_t* resp = new uint8_t[12]; + resp[0] = firstbyte; + resp[1] = secondbyte; + for (uint8_t i=2; i < 12; i++) + { + while (_serial.available() == false) delay(10); + resp[i]= (uint8_t) _serial.read(); + } + if (UseSerialDebug) + { + Response_Packet* rp = new Response_Packet(resp, UseSerialDebug); + Serial.print("FPS - RECV: "); + SendToSerial(rp->RawBytes, 12); + Serial.println(); + Serial.println(); + delete rp; + } + delete resp; + actualBaud = BaudRates[i]; + break; + } + } + + if(UseSerialDebug) + { + Serial.print("Connection established succesfully. FPS baud rate was: "); + Serial.print(actualBaud); + Serial.println(); + Serial.println(); + } + + if (actualBaud == 0) while(true) + { + if(UseSerialDebug) + { + Serial.print("EXCEPTION: FPS didn't answer to communications. Code execution stopped."); + Serial.println(); + } + delay(1000); // Something went terribly wrong with the FPS, and you aren't allowed to leave + } + + if (actualBaud != baud) + { + if(UseSerialDebug) + { + Serial.print("Undesired baud rate. Changing baud rate to: "); + Serial.print(baud); + Serial.println(); + Serial.println(); + } + ChangeBaudRate(baud); + } + Started = true; +} + // Sends the command to the software serial channel void FPS_GT511C3::SendCommand(uint8_t cmd[], uint16_t length) { diff --git a/src/FPS_GT511C3.h b/src/FPS_GT511C3.h index f45d145..012cb39 100644 --- a/src/FPS_GT511C3.h +++ b/src/FPS_GT511C3.h @@ -181,11 +181,13 @@ class FPS_GT511C3 public: // Enables verbose debug output using hardware Serial bool UseSerialDebug; + uint32_t desiredBaud; #ifndef __GNUC__ #pragma region -= Constructor/Destructor =- #endif //__GNUC__ // Creates a new object to interface with the fingerprint scanner + // It will establish the communication to the desired baud rate if defined FPS_GT511C3(uint8_t rx, uint8_t tx, uint32_t baud = 9600); // destructor @@ -199,7 +201,8 @@ class FPS_GT511C3 #pragma region -= Device Commands =- #endif //__GNUC__ //Initialises the device and gets ready for commands - void Open(); + //Returns true if the communication established + bool Open(); // Does not actually do anything (according to the datasheet) // I implemented open, so had to do closed too... lol @@ -361,11 +364,18 @@ class FPS_GT511C3 void SendToSerial(uint8_t data[], uint16_t length); private: - void SendCommand(uint8_t cmd[], uint16_t length); - Response_Packet* GetResponse(); - void GetData(uint16_t length); - uint8_t pin_RX,pin_TX; - SoftwareSerial _serial; + + // Indicates if the communication was configured for the first time + bool Started; + + //Configures the device correctly for communications at the desired baud rate + void Start(); + + void SendCommand(uint8_t cmd[], uint16_t length); + Response_Packet* GetResponse(); + void GetData(uint16_t length); + uint8_t pin_RX,pin_TX; + SoftwareSerial _serial; }; From e200f8a8929ca79288029f14f851a4133aebeaf7 Mon Sep 17 00:00:00 2001 From: Fasgort Date: Mon, 9 Apr 2018 03:02:31 +0200 Subject: [PATCH 10/27] Further fixes to data download: - Detect serial overflow, stopping data download and clearing the buffer before resuming activity. - Disabled most debug messages during data download (It will fail pretty much always). - Disabled checksum handling. Arguably useless and slow down the data download, resulting in buffer overflows. Testing some use cases with data download from the FPS (GT-511C3): - 9600 and 19200 baud rates are too slow and will shutdown the FPS. - 38400 works pretty fast and stable. - 57600 also works, but you can't use debug messages and you MUST allocate all CPU time to the task. - 115200 is way too fast and will overflow the buffer immediately. Short summary, the moment you send the command packet to start downloading, you are in a race against the FPS to receive, process and send the data before your serial buffer overflow. A slower baud rate will allow you to allocate less CPU time to the task, but go too slow and the FPS will shutdown (some kind of timeout?). --- src/FPS_GT511C3.cpp | 94 ++++++++++++++++----------------------------- src/FPS_GT511C3.h | 6 +-- 2 files changed, 35 insertions(+), 65 deletions(-) diff --git a/src/FPS_GT511C3.cpp b/src/FPS_GT511C3.cpp index 31df1fe..6f3d3f4 100644 --- a/src/FPS_GT511C3.cpp +++ b/src/FPS_GT511C3.cpp @@ -217,30 +217,32 @@ uint8_t Response_Packet::GetLowByte(uint16_t w) #endif //__GNUC__ Data_Packet::Data_Packet(uint8_t* buffer, bool UseSerialDebug) { - CheckParsing(buffer[0], DATA_START_CODE_1, DATA_START_CODE_1, "DATA_START_CODE_1", UseSerialDebug); + // The checksum here is arguably useless and may make the serial buffer overflow + /*CheckParsing(buffer[0], DATA_START_CODE_1, DATA_START_CODE_1, "DATA_START_CODE_1", UseSerialDebug); CheckParsing(buffer[1], DATA_START_CODE_2, DATA_START_CODE_2, "DATA_START_CODE_2", UseSerialDebug); CheckParsing(buffer[2], DATA_DEVICE_ID_1, DATA_DEVICE_ID_1, "DATA_DEVICE_ID_1", UseSerialDebug); CheckParsing(buffer[3], DATA_DEVICE_ID_2, DATA_DEVICE_ID_2, "DATA_DEVICE_ID_2", UseSerialDebug); - this->checksum = CalculateChecksum(buffer, 4); + this->checksum = CalculateChecksum(buffer, 4);*/ } // Get a data packet (128 bytes), calculate checksum and send it to serial -void Data_Packet::GetData(uint8_t* buffer, bool UseSerialDebug) +void Data_Packet::GetData(uint8_t buffer[], uint16_t length) { - SendToSerial(buffer, 128); - this->checksum = CalculateChecksum(buffer, 128); + for(uint16_t i = 0; ichecksum = CalculateChecksum(buffer, 128); // Checksum slowdown } // Get the last data packet (<=128 bytes), calculate checksum, validate checksum received and send it to serial void Data_Packet::GetLastData(uint8_t* buffer, uint16_t length, bool UseSerialDebug) { - SendToSerial(buffer, length-2); - this->checksum = CalculateChecksum(buffer, length); + for(uint16_t i = 0; ichecksum = CalculateChecksum(buffer, length); uint8_t checksum_low = GetLowByte(this->checksum); uint8_t checksum_high = GetHighByte(this->checksum); CheckParsing(buffer[length-2], checksum_low, checksum_low, "Checksum_LOW", UseSerialDebug); - CheckParsing(buffer[length-1], checksum_high, checksum_high, "Checksum_HIGH", UseSerialDebug); + CheckParsing(buffer[length-1], checksum_high, checksum_high, "Checksum_HIGH", UseSerialDebug);*/ } // checks to see if the byte is the proper value, and logs it to the serial channel if not @@ -284,26 +286,6 @@ uint8_t Data_Packet::GetLowByte(uint16_t w) return (uint8_t)w&0x00FF; } -// sends a byte to the serial debugger in the hex format we want EX "0F" -void Data_Packet::serialPrintHex(uint8_t data) -{ - char tmp[16]; - sprintf(tmp, "%.2X",data); - Serial.print(tmp); -} - -// sends the byte array to the serial debugger in our hex format EX: "00 AF FF 10 00 13" -void Data_Packet::SendToSerial(uint8_t data[], uint16_t length) -{ - boolean first=true; - Serial.print("\""); - for(uint16_t i=0; iGetData(data, UseSerialDebug); - if(UseSerialDebug) - { - Serial.print("FPS - RECV: "); - SendToSerial(data, 128); - Serial.println(); - Serial.println(); - } + dp.GetData(data, 128); } - delete data; - uint8_t* lastdata = new uint8_t[lastPacketSize]; + uint8_t lastdata[lastPacketSize]; for (uint8_t i=0; i < lastPacketSize; i++) { while (_serial.available() == false) delay(10); lastdata[i]= (uint8_t) _serial.read(); } - dp->GetLastData(lastdata, lastPacketSize, UseSerialDebug); - if(UseSerialDebug) - { - Serial.print("FPS - RECV: "); - SendToSerial(lastdata, lastPacketSize); - Serial.println(); - Serial.println(); - } - delete lastdata; - - return; + dp.GetLastData(lastdata, lastPacketSize, UseSerialDebug); }; // sends the byte array to the serial debugger in our hex format EX: "00 AF FF 10 00 13" diff --git a/src/FPS_GT511C3.h b/src/FPS_GT511C3.h index 012cb39..acf7aee 100644 --- a/src/FPS_GT511C3.h +++ b/src/FPS_GT511C3.h @@ -157,15 +157,13 @@ class Data_Packet static const uint8_t DATA_DEVICE_ID_1 = 0x01; // Device ID Byte 1 (lesser byte) - theoretically never changes static const uint8_t DATA_DEVICE_ID_2 = 0x00; // Device ID Byte 2 (greater byte) - void GetData(uint8_t* buffer, bool UseSerialDebug); - void GetLastData(uint8_t* buffer, uint16_t length, bool UseSerialDebug); + void GetData(uint8_t buffer[], uint16_t length); + void GetLastData(uint8_t buffer[], uint16_t length, bool UseSerialDebug); private: bool CheckParsing(uint8_t b, uint8_t propervalue, uint8_t alternatevalue, const char* varname, bool UseSerialDebug); uint16_t CalculateChecksum(uint8_t* buffer, uint16_t length); uint8_t GetHighByte(uint16_t w); uint8_t GetLowByte(uint16_t w); - void serialPrintHex(uint8_t data); - void SendToSerial(uint8_t data[], uint16_t length); }; #ifndef __GNUC__ #pragma endregion From ae59956870f701606d17dd5efedef9b65ca9e738 Mon Sep 17 00:00:00 2001 From: Fasgort Date: Mon, 9 Apr 2018 03:14:05 +0200 Subject: [PATCH 11/27] A few little fixes. Tested GetImage(), and it works as correct as GetRawImage(). --- src/FPS_GT511C3.cpp | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/FPS_GT511C3.cpp b/src/FPS_GT511C3.cpp index 6f3d3f4..83dc2b8 100644 --- a/src/FPS_GT511C3.cpp +++ b/src/FPS_GT511C3.cpp @@ -234,9 +234,9 @@ void Data_Packet::GetData(uint8_t buffer[], uint16_t length) } // Get the last data packet (<=128 bytes), calculate checksum, validate checksum received and send it to serial -void Data_Packet::GetLastData(uint8_t* buffer, uint16_t length, bool UseSerialDebug) +void Data_Packet::GetLastData(uint8_t buffer[], uint16_t length, bool UseSerialDebug) { - for(uint16_t i = 0; ichecksum = CalculateChecksum(buffer, length); uint8_t checksum_low = GetLowByte(this->checksum); @@ -727,11 +727,15 @@ bool FPS_GT511C3::CaptureFinger(bool highquality) // Gets an image that is 258x202 (52116 bytes) and sends it over serial // Returns: True (device confirming download) + // It only worked with baud rate at 38400-57600 in GT-511C3. + // Slower speeds and the FPS will shutdown. Higher speeds and the serial buffer will overflow. + // Make sure you are allocating enough CPU time for this task or you will overflow nonetheless. + // Also, avoid using UseSerialDebug for this task, since it's easier to overflow. bool FPS_GT511C3::GetImage() { if (UseSerialDebug) Serial.println("FPS - GetImage"); Command_Packet* cp = new Command_Packet(); - cp->Command = Command_Packet::Commands::GetRawImage; + cp->Command = Command_Packet::Commands::GetImage; uint8_t* packetbytes = cp->GetPacketBytes(); delete cp; SendCommand(packetbytes, 12); From daa128880d672ce244275e3de0616073d14a42fa Mon Sep 17 00:00:00 2001 From: Fasgort Date: Mon, 9 Apr 2018 20:23:01 +0200 Subject: [PATCH 12/27] Little fix to align data packets. --- src/FPS_GT511C3.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/FPS_GT511C3.cpp b/src/FPS_GT511C3.cpp index 83dc2b8..3a63c5a 100644 --- a/src/FPS_GT511C3.cpp +++ b/src/FPS_GT511C3.cpp @@ -743,7 +743,7 @@ bool FPS_GT511C3::GetImage() bool retval = rp->ACK; delete rp; delete packetbytes; - GetData(52116); + GetData(52116+6); return retval; } @@ -766,7 +766,7 @@ bool FPS_GT511C3::GetRawImage() bool retval = rp->ACK; delete rp; delete packetbytes; - GetData(19200); + GetData(19200+6); return retval; } From 55863f895bf7f7be6451c70b2ea9369c1e578589 Mon Sep 17 00:00:00 2001 From: Fasgort Date: Wed, 11 Apr 2018 13:53:56 +0200 Subject: [PATCH 13/27] - Implemented GetTemplate() and SetTemplate() methods. - Data overflow warning will only appear when UseDebugSerial is set. - Little memory optimizations. - Renamed a few variables to make the code easier to read. --- src/FPS_GT511C3.cpp | 221 ++++++++++++++++++++++++++------------------ src/FPS_GT511C3.h | 44 ++++----- 2 files changed, 149 insertions(+), 116 deletions(-) diff --git a/src/FPS_GT511C3.cpp b/src/FPS_GT511C3.cpp index 3a63c5a..4cdd803 100644 --- a/src/FPS_GT511C3.cpp +++ b/src/FPS_GT511C3.cpp @@ -92,10 +92,10 @@ Command_Packet::Command_Packet() // creates and parses a response packet from the finger print scanner Response_Packet::Response_Packet(uint8_t* buffer, bool UseSerialDebug) { - CheckParsing(buffer[0], COMMAND_START_CODE_1, COMMAND_START_CODE_1, "COMMAND_START_CODE_1", UseSerialDebug); - CheckParsing(buffer[1], COMMAND_START_CODE_2, COMMAND_START_CODE_2, "COMMAND_START_CODE_2", UseSerialDebug); - CheckParsing(buffer[2], COMMAND_DEVICE_ID_1, COMMAND_DEVICE_ID_1, "COMMAND_DEVICE_ID_1", UseSerialDebug); - CheckParsing(buffer[3], COMMAND_DEVICE_ID_2, COMMAND_DEVICE_ID_2, "COMMAND_DEVICE_ID_2", UseSerialDebug); + CheckParsing(buffer[0], RESPONSE_START_CODE_1, RESPONSE_START_CODE_1, "RESPONSE_START_CODE_1", UseSerialDebug); + CheckParsing(buffer[1], RESPONSE_START_CODE_2, RESPONSE_START_CODE_2, "RESPONSE_START_CODE_2", UseSerialDebug); + CheckParsing(buffer[2], RESPONSE_DEVICE_ID_1, RESPONSE_DEVICE_ID_1, "RESPONSE_DEVICE_ID_1", UseSerialDebug); + CheckParsing(buffer[3], RESPONSE_DEVICE_ID_2, RESPONSE_DEVICE_ID_2, "RESPONSE_DEVICE_ID_2", UseSerialDebug); CheckParsing(buffer[8], 0x30, 0x31, "AckNak_LOW", UseSerialDebug); if (buffer[8] == 0x30) ACK = true; else ACK = false; CheckParsing(buffer[9], 0x00, 0x00, "AckNak_HIGH", UseSerialDebug); @@ -336,11 +336,11 @@ bool FPS_GT511C3::Open() uint8_t* packetbytes = cp->GetPacketBytes(); delete cp; SendCommand(packetbytes, 12); + delete packetbytes; Response_Packet* rp = GetResponse(); bool retval = true; if (rp->ACK == false) retval = false; delete rp; - delete packetbytes; return retval; } @@ -358,9 +358,9 @@ void FPS_GT511C3::Close() uint8_t* packetbytes = cp->GetPacketBytes(); delete cp; SendCommand(packetbytes, 12); + delete packetbytes; Response_Packet* rp = GetResponse(); delete rp; - delete packetbytes; }; // Turns on or off the LED backlight @@ -386,11 +386,11 @@ bool FPS_GT511C3::SetLED(bool on) uint8_t* packetbytes = cp->GetPacketBytes(); delete cp; SendCommand(packetbytes, 12); + delete packetbytes; Response_Packet* rp = GetResponse(); bool retval = true; if (rp->ACK == false) retval = false; delete rp; - delete packetbytes; return retval; }; @@ -409,11 +409,11 @@ bool FPS_GT511C3::ChangeBaudRate(uint32_t baud) uint8_t* packetbytes = cp->GetPacketBytes(); delete cp; SendCommand(packetbytes, 12); + delete packetbytes; Response_Packet* rp = GetResponse(); bool retval = rp->ACK; if (retval) _serial.begin(baud); delete rp; - delete packetbytes; return retval; } return false; @@ -433,11 +433,10 @@ uint16_t FPS_GT511C3::GetEnrollCount() uint8_t* packetbytes = cp->GetPacketBytes(); delete cp; SendCommand(packetbytes, 12); + delete packetbytes; Response_Packet* rp = GetResponse(); - uint32_t retval = rp->FromParameter(); delete rp; - delete packetbytes; return retval; } @@ -509,8 +508,8 @@ uint8_t FPS_GT511C3::Enroll1() delete packetbytes; Response_Packet* rp = GetResponse(); uint32_t retval = rp->FromParameter(); -//Change to "retval < 3000", if using GT-521F52 -//Leave "reval < 200", if using GT-521F32/GT-511C3 + //Change to "retval < 3000", if using GT-521F52 + //Leave "reval < 200", if using GT-521F32/GT-511C3 if (retval < 200) retval = 3; else retval = 0; if (rp->ACK == false) { @@ -538,8 +537,8 @@ uint8_t FPS_GT511C3::Enroll2() delete packetbytes; Response_Packet* rp = GetResponse(); uint32_t retval = rp->FromParameter(); -//Change to "retval < 3000", if using GT-521F52 -//Leave "reval < 200", if using GT-521F32/GT-511C3 + //Change to "retval < 3000", if using GT-521F52 + //Leave "reval < 200", if using GT-521F32/GT-511C3 if (retval < 200) retval = 3; else retval = 0; if (rp->ACK == false) { @@ -568,9 +567,9 @@ uint8_t FPS_GT511C3::Enroll3() delete packetbytes; Response_Packet* rp = GetResponse(); uint32_t retval = rp->FromParameter(); -//Change to "retval < 3000", if using GT-521F52 -//Leave "reval < 200", if using GT-521F32/GT-511C3 - if (retval < 200) retval = 3; else retval = 0; + //Change to "retval < 3000", if using GT-521F52 + //Leave "reval < 200", if using GT-521F32/GT-511C3 + if (retval < 200) retval = 3; else retval = 0; if (rp->ACK == false) { if (rp->Error == Response_Packet::ErrorCodes::NACK_ENROLL_FAILED) retval = 1; @@ -590,16 +589,11 @@ bool FPS_GT511C3::IsPressFinger() uint8_t* packetbytes = cp->GetPacketBytes(); delete cp; SendCommand(packetbytes, 12); + delete packetbytes; 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; */ if (!rp->ParameterBytes[0] && !rp->ParameterBytes[1] && !rp->ParameterBytes[2] && !rp->ParameterBytes[3]) retval = true; delete rp; - delete packetbytes; return retval; } @@ -616,10 +610,10 @@ bool FPS_GT511C3::DeleteID(uint16_t id) uint8_t* packetbytes = cp->GetPacketBytes(); delete cp; SendCommand(packetbytes, 12); + delete packetbytes; Response_Packet* rp = GetResponse(); bool retval = rp->ACK; delete rp; - delete packetbytes; return retval; } @@ -632,10 +626,10 @@ bool FPS_GT511C3::DeleteAll() cp->Command = Command_Packet::Commands::DeleteAll; uint8_t* packetbytes = cp->GetPacketBytes(); SendCommand(packetbytes, 12); + delete packetbytes; Response_Packet* rp = GetResponse(); bool retval = rp->ACK; delete rp; - delete packetbytes; delete cp; return retval; } @@ -657,6 +651,7 @@ uint8_t FPS_GT511C3::Verify1_1(uint16_t id) uint8_t* packetbytes = cp->GetPacketBytes(); delete cp; SendCommand(packetbytes, 12); + delete packetbytes; Response_Packet* rp = GetResponse(); uint8_t retval = 0; if (rp->ACK == false) @@ -667,7 +662,6 @@ uint8_t FPS_GT511C3::Verify1_1(uint16_t id) if (rp->Error == Response_Packet::ErrorCodes::NACK_VERIFY_FAILED) retval = 3; } delete rp; - delete packetbytes; return retval; } @@ -687,13 +681,13 @@ uint16_t FPS_GT511C3::Identify1_N() uint8_t* packetbytes = cp->GetPacketBytes(); delete cp; SendCommand(packetbytes, 12); + delete packetbytes; Response_Packet* rp = GetResponse(); uint32_t retval = rp->FromParameter(); //Change to "retval > 3000" and "retval = 3000", if using GT-521F52 //Leave "reval > 200" and "retval = 200", if using GT-521F32/GT-511C3 if (retval > 200) retval = 200; delete rp; - delete packetbytes; return retval; } @@ -717,12 +711,11 @@ bool FPS_GT511C3::CaptureFinger(bool highquality) uint8_t* packetbytes = cp->GetPacketBytes(); delete cp; SendCommand(packetbytes, 12); + delete packetbytes; Response_Packet* rp = GetResponse(); bool retval = rp->ACK; delete rp; - delete packetbytes; return retval; - } // Gets an image that is 258x202 (52116 bytes) and sends it over serial @@ -739,13 +732,12 @@ bool FPS_GT511C3::GetImage() uint8_t* packetbytes = cp->GetPacketBytes(); delete cp; SendCommand(packetbytes, 12); + delete packetbytes; Response_Packet* rp = GetResponse(); bool retval = rp->ACK; delete rp; - delete packetbytes; GetData(52116+6); return retval; - } // Gets an image that is qvga 160x120 (19200 bytes) and sends it over serial @@ -762,68 +754,102 @@ bool FPS_GT511C3::GetRawImage() uint8_t* packetbytes = cp->GetPacketBytes(); delete cp; SendCommand(packetbytes, 12); + delete packetbytes; Response_Packet* rp = GetResponse(); bool retval = rp->ACK; delete rp; - delete packetbytes; GetData(19200+6); return retval; - } -#ifndef __GNUC__ -#pragma endregion -#endif //__GNUC__ -#ifndef __GNUC__ -#pragma region -= Not imlemented commands =- -#endif //__GNUC__ -// Gets an image that is 258x202 (52116 bytes) and returns it in 407 Data_Packets -// Use StartDataDownload, and then GetNextDataPacket until done -// Returns: True (device confirming download starting) - // Not implemented due to memory restrictions on the arduino - // may revisit this if I find a need for it -//bool FPS_GT511C3::GetImage() -//{ - // Not implemented due to memory restrictions on the arduino - // may revisit this if I find a need for it - //return false; -//} - -// Gets a template from the fps (498 bytes) in 4 Data_Packets -// Use StartDataDownload, and then GetNextDataPacket until done +// Gets a template from the fps (498 bytes) // Parameter: 0-199 ID number // Returns: // 0 - ACK Download starting // 1 - Invalid position // 2 - ID not used (no template to download - // Not implemented due to memory restrictions on the arduino - // may revisit this if I find a need for it -//int FPS_GT511C3::GetTemplate(int id) -//{ - // Not implemented due to memory restrictions on the arduino - // may revisit this if I find a need for it - //return false; -//} +uint8_t FPS_GT511C3::GetTemplate(uint16_t id) +{ + if (UseSerialDebug) Serial.println("FPS - GetTemplate"); + Command_Packet* cp = new Command_Packet(); + cp->Command = Command_Packet::Commands::GetTemplate; + cp->ParameterFrom(id); + uint8_t* packetbytes = cp->GetPacketBytes(); + delete cp; + SendCommand(packetbytes, 12); + delete packetbytes; + Response_Packet* rp = GetResponse(); + if(rp->ACK) + { + delete rp; + GetData(498+6); + return 0; + } else + { + uint32_t retval = rp->FromParameter(); + delete rp; + return retval; + } +} // Uploads a template to the fps // Parameter: the template (498 bytes) // Parameter: the ID number to upload // Parameter: Check for duplicate fingerprints already on fps // Returns: -// 0-199 - ID duplicated -// 200 - Uploaded ok (no duplicate if enabled) -// 201 - Invalid position -// 202 - Communications error -// 203 - Device error - // Not implemented due to memory restrictions on the arduino - // may revisit this if I find a need for it -//int FPS_GT511C3::SetTemplate(byte* tmplt, int id, bool duplicateCheck) -//{ - // Not implemented due to memory restrictions on the arduino - // may revisit this if I find a need for it - //return -1; -//} +// -1 - Undefined error (shouldn't ever happen) +// 0 - Uploaded ok (no duplicate if enabled) +// 1 - ID duplicated +// 2 - Invalid position +// 3 - Communications error +// 4 - Device error +uint16_t FPS_GT511C3::SetTemplate(byte* tmplt, uint16_t id, bool duplicateCheck) +{ + if (UseSerialDebug) Serial.println("FPS - SetTemplate"); + Command_Packet* cp = new Command_Packet(); + cp->Command = Command_Packet::Commands::SetTemplate; + cp->ParameterFrom(0xFFFF0000 * !duplicateCheck + id); // Will set the HIWORD if duplicateCheck = false + uint8_t* packetbytes = cp->GetPacketBytes(); + delete cp; + SendCommand(packetbytes, 12); + delete packetbytes; + Response_Packet* rp = GetResponse(); + if(!rp->ACK) + { + delete rp; + return 2; + } else + { + SendCommand(tmplt, 498); // Not actually a command ;) + rp = GetResponse(); + if (rp->ACK) + { + delete rp; + return 0; + } else + { + //Change to "retval < 3000", if using GT-521F52 + //Leave "reval < 200", if using GT-521F32/GT-511C3 + if (rp->FromParameter() < 200) + { + delete rp; + return 1; + } + uint16_t error = rp->Error; + delete rp; + if (error == Response_Packet::ErrorCodes::NACK_COMM_ERR) return 3; + if (error == Response_Packet::ErrorCodes::NACK_DEV_ERR) return 4; + return -1; // Undefined error + } + } +} +#ifndef __GNUC__ +#pragma endregion +#endif //__GNUC__ +#ifndef __GNUC__ +#pragma region -= Not imlemented commands =- +#endif //__GNUC__ // Commands that are not implemented (and why) // VerifyTemplate1_1 - Couldn't find a good reason to implement this on an arduino // IdentifyTemplate1_N - Couldn't find a good reason to implement this on an arduino @@ -870,22 +896,22 @@ void FPS_GT511C3::Start() _serial.begin(BaudRates[i]); _serial.listen(); SendCommand(packetbytes, 12); - delay(100); - uint8_t firstbyte = 0; - uint8_t secondbyte = 0; + uint8_t firstbyte, secondbyte = 0; bool done = false; uint8_t byteCount = 0; while (done == false && byteCount<100) { byteCount++; + delay(25); if(_serial.peek() == -1) break; firstbyte = (uint8_t)_serial.read(); - if (firstbyte == Response_Packet::COMMAND_START_CODE_1) + if (firstbyte == Response_Packet::RESPONSE_START_CODE_1) { + delay(25); if(_serial.peek() == -1) break; secondbyte = (uint8_t)_serial.read(); - if (secondbyte == Response_Packet::COMMAND_START_CODE_2) + if (secondbyte == Response_Packet::RESPONSE_START_CODE_2) { done = true; } @@ -896,7 +922,7 @@ void FPS_GT511C3::Start() while (_serial.available()) _serial.read(); // Clear Serial buffer } else { - uint8_t* resp = new uint8_t[12]; + uint8_t resp[12]; resp[0] = firstbyte; resp[1] = secondbyte; for (uint8_t i=2; i < 12; i++) @@ -913,7 +939,6 @@ void FPS_GT511C3::Start() Serial.println(); delete rp; } - delete resp; actualBaud = BaudRates[i]; break; } @@ -966,26 +991,34 @@ void FPS_GT511C3::SendCommand(uint8_t cmd[], uint16_t length) // Gets the response to the command from the software serial channel (and waits for it) Response_Packet* FPS_GT511C3::GetResponse() { - uint8_t firstbyte = 0; + uint8_t firstbyte, secondbyte = 0; bool done = false; _serial.listen(); while (done == false) { + while (_serial.available() == false) delay(10); firstbyte = (uint8_t)_serial.read(); - if (firstbyte == Response_Packet::COMMAND_START_CODE_1) + if (firstbyte == Response_Packet::RESPONSE_START_CODE_1) { - done = true; + while (_serial.available() == false) delay(10); + secondbyte = (uint8_t)_serial.read(); + if (secondbyte == Response_Packet::RESPONSE_START_CODE_2) + { + done = true; + } } } - uint8_t* resp = new uint8_t[12]; + + uint8_t resp[12]; resp[0] = firstbyte; - for (uint8_t i=1; i < 12; i++) + resp[1] = secondbyte; + for (uint8_t i=2; i < 12; i++) { while (_serial.available() == false) delay(10); resp[i]= (uint8_t) _serial.read(); } + Response_Packet* rp = new Response_Packet(resp, UseSerialDebug); - delete resp; if (UseSerialDebug) { Serial.print("FPS - RECV: "); @@ -1000,15 +1033,16 @@ Response_Packet* FPS_GT511C3::GetResponse() // and sends it over serial sommunications void FPS_GT511C3::GetData(uint16_t length) { - uint8_t firstbyte = 0; - uint8_t secondbyte = 0; + uint8_t firstbyte, secondbyte = 0; bool done = false; _serial.listen(); while (done == false) { + while (_serial.available() == false) delay(10); firstbyte = (uint8_t)_serial.read(); if (firstbyte == Data_Packet::DATA_START_CODE_1) { + while (_serial.available() == false) delay(10); secondbyte = (uint8_t)_serial.read(); if (secondbyte == Data_Packet::DATA_START_CODE_2) { @@ -1044,14 +1078,17 @@ void FPS_GT511C3::GetData(uint16_t length) while (_serial.available() == false) delay(1); if(_serial.overflow()) { - Serial.println("Overflow! Data download stopped"); - Serial.println("Cleaning serial buffer..."); + if(UseSerialDebug) + { + Serial.println("Overflow! Data download stopped"); + Serial.println("Cleaning serial buffer..."); + } for (uint16_t j = 0; j Date: Wed, 11 Apr 2018 15:28:10 +0200 Subject: [PATCH 14/27] Enabled checksum methods. Seems like they don't slow down the data download enough to be an issue. Fixed some bugs too in the checksum code. Download methods will send 2 more bytes (byte addition checksum) after the data buffer, so you can check if the data is correct in whatever the destination device is. --- src/FPS_GT511C3.cpp | 44 ++++++++++++++++++++++++-------------------- src/FPS_GT511C3.h | 8 ++++---- 2 files changed, 28 insertions(+), 24 deletions(-) diff --git a/src/FPS_GT511C3.cpp b/src/FPS_GT511C3.cpp index 4cdd803..36aaeb6 100644 --- a/src/FPS_GT511C3.cpp +++ b/src/FPS_GT511C3.cpp @@ -217,32 +217,36 @@ uint8_t Response_Packet::GetLowByte(uint16_t w) #endif //__GNUC__ Data_Packet::Data_Packet(uint8_t* buffer, bool UseSerialDebug) { - // The checksum here is arguably useless and may make the serial buffer overflow - /*CheckParsing(buffer[0], DATA_START_CODE_1, DATA_START_CODE_1, "DATA_START_CODE_1", UseSerialDebug); - CheckParsing(buffer[1], DATA_START_CODE_2, DATA_START_CODE_2, "DATA_START_CODE_2", UseSerialDebug); - CheckParsing(buffer[2], DATA_DEVICE_ID_1, DATA_DEVICE_ID_1, "DATA_DEVICE_ID_1", UseSerialDebug); - CheckParsing(buffer[3], DATA_DEVICE_ID_2, DATA_DEVICE_ID_2, "DATA_DEVICE_ID_2", UseSerialDebug); + if (UseSerialDebug) + { + CheckParsing(buffer[0], DATA_START_CODE_1, DATA_START_CODE_1, "DATA_START_CODE_1", UseSerialDebug); + CheckParsing(buffer[1], DATA_START_CODE_2, DATA_START_CODE_2, "DATA_START_CODE_2", UseSerialDebug); + CheckParsing(buffer[2], DATA_DEVICE_ID_1, DATA_DEVICE_ID_1, "DATA_DEVICE_ID_1", UseSerialDebug); + CheckParsing(buffer[3], DATA_DEVICE_ID_2, DATA_DEVICE_ID_2, "DATA_DEVICE_ID_2", UseSerialDebug); - this->checksum = CalculateChecksum(buffer, 4);*/ + this->checksum = CalculateChecksum(buffer, 4); + } } // Get a data packet (128 bytes), calculate checksum and send it to serial -void Data_Packet::GetData(uint8_t buffer[], uint16_t length) +void Data_Packet::GetData(uint8_t buffer[], uint16_t length, bool UseSerialDebug) { for(uint16_t i = 0; ichecksum = CalculateChecksum(buffer, 128); // Checksum slowdown + if (UseSerialDebug) this->checksum = CalculateChecksum(buffer, 128); } // Get the last data packet (<=128 bytes), calculate checksum, validate checksum received and send it to serial void Data_Packet::GetLastData(uint8_t buffer[], uint16_t length, bool UseSerialDebug) { - for(uint16_t i = 0; i<(length-2); i++) Serial.write(buffer[i]); - // The checksum here is arguably useless and may make the serial buffer overflow - /*this->checksum = CalculateChecksum(buffer, length); - uint8_t checksum_low = GetLowByte(this->checksum); - uint8_t checksum_high = GetHighByte(this->checksum); - CheckParsing(buffer[length-2], checksum_low, checksum_low, "Checksum_LOW", UseSerialDebug); - CheckParsing(buffer[length-1], checksum_high, checksum_high, "Checksum_HIGH", UseSerialDebug);*/ + for(uint16_t i = 0; ichecksum = CalculateChecksum(buffer, length-2); + uint8_t checksum_low = GetLowByte(this->checksum); + uint8_t checksum_high = GetHighByte(this->checksum); + CheckParsing(buffer[length-2], checksum_low, checksum_low, "Checksum_LOW", UseSerialDebug); + CheckParsing(buffer[length-1], checksum_high, checksum_high, "Checksum_HIGH", UseSerialDebug); + } } // checks to see if the byte is the proper value, and logs it to the serial channel if not @@ -251,7 +255,7 @@ bool Data_Packet::CheckParsing(uint8_t b, uint8_t propervalue, uint8_t alternate bool retval = (b != propervalue) && (b != alternatevalue); if ((UseSerialDebug) && (retval)) { - Serial.print("Data_Packet parsing error "); + Serial.print("\nData_Packet parsing error "); Serial.print(varname); Serial.print(" "); Serial.print(propervalue, HEX); @@ -718,7 +722,7 @@ bool FPS_GT511C3::CaptureFinger(bool highquality) return retval; } -// Gets an image that is 258x202 (52116 bytes) and sends it over serial +// Gets an image that is 258x202 (52116 bytes + 2 bytes checksum) and sends it over serial // Returns: True (device confirming download) // It only worked with baud rate at 38400-57600 in GT-511C3. // Slower speeds and the FPS will shutdown. Higher speeds and the serial buffer will overflow. @@ -740,7 +744,7 @@ bool FPS_GT511C3::GetImage() return retval; } -// Gets an image that is qvga 160x120 (19200 bytes) and sends it over serial +// Gets an image that is qvga 160x120 (19200 bytes + 2 bytes checksum) and sends it over serial // Returns: True (device confirming download) // It only worked with baud rate at 38400-57600 in GT-511C3. // Slower speeds and the FPS will shutdown. Higher speeds and the serial buffer will overflow. @@ -762,7 +766,7 @@ bool FPS_GT511C3::GetRawImage() return retval; } -// Gets a template from the fps (498 bytes) +// Gets a template from the fps (498 bytes + 2 bvtes checksum) // Parameter: 0-199 ID number // Returns: // 0 - ACK Download starting @@ -1093,7 +1097,7 @@ void FPS_GT511C3::GetData(uint16_t length) } data[i]= (uint8_t) _serial.read(); } - dp.GetData(data, 128); + dp.GetData(data, 128, UseSerialDebug); } uint8_t lastdata[lastPacketSize]; diff --git a/src/FPS_GT511C3.h b/src/FPS_GT511C3.h index 5f3a53a..249cd3a 100644 --- a/src/FPS_GT511C3.h +++ b/src/FPS_GT511C3.h @@ -157,7 +157,7 @@ class Data_Packet static const uint8_t DATA_DEVICE_ID_1 = 0x01; // Device ID Byte 1 (lesser byte) - theoretically never changes static const uint8_t DATA_DEVICE_ID_2 = 0x00; // Device ID Byte 2 (greater byte) - void GetData(uint8_t buffer[], uint16_t length); + void GetData(uint8_t buffer[], uint16_t length, bool UseSerialDebug); void GetLastData(uint8_t buffer[], uint16_t length, bool UseSerialDebug); private: bool CheckParsing(uint8_t b, uint8_t propervalue, uint8_t alternatevalue, const char* varname, bool UseSerialDebug); @@ -300,15 +300,15 @@ class FPS_GT511C3 // Returns: True if ok, false if no finger pressed bool CaptureFinger(bool highquality); - // Gets an image that is 258x202 (52116 bytes) and sends it over serial + // Gets an image that is 258x202 (52116 bytes + 2 bytes checksum) and sends it over serial // Returns: True (device confirming download) bool GetImage(); - // Gets an image that is qvga 160x120 (19200 bytes) and sends it over serial + // Gets an image that is qvga 160x120 (19200 bytes + 2 bytes checksum) and sends it over serial // Returns: True (device confirming download) bool GetRawImage(); - // Gets a template from the fps (498 bytes) + // Gets a template from the fps (498 bytes + 2 bytes checksum) // Parameter: 0-199 ID number // Returns: // 0 - ACK Download starting From 4181d4d54a59812d5ce6127bdb316630d450dd70 Mon Sep 17 00:00:00 2001 From: Fasgort Date: Wed, 11 Apr 2018 19:44:41 +0200 Subject: [PATCH 15/27] Some patches over GetImage() method. This is completely broken. Check the comments in the code. --- src/FPS_GT511C3.cpp | 43 +++++++++++++++++++++++++++++++++---------- src/FPS_GT511C3.h | 4 +++- 2 files changed, 36 insertions(+), 11 deletions(-) diff --git a/src/FPS_GT511C3.cpp b/src/FPS_GT511C3.cpp index 36aaeb6..ae5b9f0 100644 --- a/src/FPS_GT511C3.cpp +++ b/src/FPS_GT511C3.cpp @@ -728,19 +728,42 @@ bool FPS_GT511C3::CaptureFinger(bool highquality) // Slower speeds and the FPS will shutdown. Higher speeds and the serial buffer will overflow. // Make sure you are allocating enough CPU time for this task or you will overflow nonetheless. // Also, avoid using UseSerialDebug for this task, since it's easier to overflow. -bool FPS_GT511C3::GetImage() + // WARNING: This method is completely broken, but you can give it a try. + // Patched method will return a 232x139 bitmap 8-bit image, 32248 bytes. +// Parameter: true to ignore the documentation and get valid image data. +bool FPS_GT511C3::GetImage(bool patched) { if (UseSerialDebug) Serial.println("FPS - GetImage"); - Command_Packet* cp = new Command_Packet(); - cp->Command = Command_Packet::Commands::GetImage; - uint8_t* packetbytes = cp->GetPacketBytes(); - delete cp; - SendCommand(packetbytes, 12); + Command_Packet* cp = new Command_Packet(); + cp->Command = Command_Packet::Commands::GetImage; + uint8_t* packetbytes = cp->GetPacketBytes(); + delete cp; + SendCommand(packetbytes, 12); delete packetbytes; - Response_Packet* rp = GetResponse(); - bool retval = rp->ACK; - delete rp; - GetData(52116+6); + Response_Packet* rp = GetResponse(); + bool retval = rp->ACK; + delete rp; + + if (!patched) GetData(52116+6); + else + { + // Alright, for some reason, in my GT-511C3, there are around 15000 trash bytes being sent + // before the actual image is sent. The actual number is random, but the image will come + // after a long block of empty bytes. Not only that, the resolution of the image is actually + // 232x139 (maybe taller) and not whatever the documentation says. This wasn't fun to debug. + for (uint16_t i = 0; i<10000; i++) // This goes past the initial non-zero trash block + { + while(!_serial.available()) delay(10); + _serial.read(); + } + while(_serial.peek() <= 0) _serial.read(); // This looks for the actual first byte of image data + + for(uint16_t i = 0; i<32248; i++) // Bytes for a 232x139 bitmap 8-bit image + { + while(!_serial.available()) delay(10); + Serial.write((uint8_t)_serial.read()); + } + } return retval; } diff --git a/src/FPS_GT511C3.h b/src/FPS_GT511C3.h index 249cd3a..78d4df8 100644 --- a/src/FPS_GT511C3.h +++ b/src/FPS_GT511C3.h @@ -301,8 +301,10 @@ class FPS_GT511C3 bool CaptureFinger(bool highquality); // Gets an image that is 258x202 (52116 bytes + 2 bytes checksum) and sends it over serial + // WARNING: The documentation is totally wrong (at least in GT-511C3). Check implementation comments. // Returns: True (device confirming download) - bool GetImage(); + // Parameter: true to ignore the documentation and get valid image data. + bool GetImage(bool patched = false); // Gets an image that is qvga 160x120 (19200 bytes + 2 bytes checksum) and sends it over serial // Returns: True (device confirming download) From a02d6486374e0a81da0eebcd9b763860c04a10b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20L=C3=B3pez=20Chica?= Date: Mon, 29 Oct 2018 20:08:37 +0100 Subject: [PATCH 16/27] A few memory optimizations, specially if you decided not to use the Debug methods. --- src/FPS_GT511C3.cpp | 271 +++++++++++++++++++++++++------------------- src/FPS_GT511C3.h | 20 ++-- 2 files changed, 168 insertions(+), 123 deletions(-) diff --git a/src/FPS_GT511C3.cpp b/src/FPS_GT511C3.cpp index ae5b9f0..c9ee9e1 100644 --- a/src/FPS_GT511C3.cpp +++ b/src/FPS_GT511C3.cpp @@ -90,21 +90,21 @@ Command_Packet::Command_Packet() #pragma region -= Response_Packet Definitions =- #endif //__GNUC__ // creates and parses a response packet from the finger print scanner -Response_Packet::Response_Packet(uint8_t* buffer, bool UseSerialDebug) +Response_Packet::Response_Packet(uint8_t* buffer) { - CheckParsing(buffer[0], RESPONSE_START_CODE_1, RESPONSE_START_CODE_1, "RESPONSE_START_CODE_1", UseSerialDebug); - CheckParsing(buffer[1], RESPONSE_START_CODE_2, RESPONSE_START_CODE_2, "RESPONSE_START_CODE_2", UseSerialDebug); - CheckParsing(buffer[2], RESPONSE_DEVICE_ID_1, RESPONSE_DEVICE_ID_1, "RESPONSE_DEVICE_ID_1", UseSerialDebug); - CheckParsing(buffer[3], RESPONSE_DEVICE_ID_2, RESPONSE_DEVICE_ID_2, "RESPONSE_DEVICE_ID_2", UseSerialDebug); - CheckParsing(buffer[8], 0x30, 0x31, "AckNak_LOW", UseSerialDebug); + CheckParsing(buffer[0], RESPONSE_START_CODE_1, RESPONSE_START_CODE_1, "RESPONSE_START_CODE_1"); + CheckParsing(buffer[1], RESPONSE_START_CODE_2, RESPONSE_START_CODE_2, "RESPONSE_START_CODE_2"); + CheckParsing(buffer[2], RESPONSE_DEVICE_ID_1, RESPONSE_DEVICE_ID_1, "RESPONSE_DEVICE_ID_1"); + CheckParsing(buffer[3], RESPONSE_DEVICE_ID_2, RESPONSE_DEVICE_ID_2, "RESPONSE_DEVICE_ID_2"); + CheckParsing(buffer[8], 0x30, 0x31, "AckNak_LOW"); if (buffer[8] == 0x30) ACK = true; else ACK = false; - CheckParsing(buffer[9], 0x00, 0x00, "AckNak_HIGH", UseSerialDebug); + CheckParsing(buffer[9], 0x00, 0x00, "AckNak_HIGH"); uint16_t checksum = CalculateChecksum(buffer, 10); uint8_t checksum_low = GetLowByte(checksum); uint8_t checksum_high = GetHighByte(checksum); - CheckParsing(buffer[10], checksum_low, checksum_low, "Checksum_LOW", UseSerialDebug); - CheckParsing(buffer[11], checksum_high, checksum_high, "Checksum_HIGH", UseSerialDebug); + CheckParsing(buffer[10], checksum_low, checksum_low, "Checksum_LOW"); + CheckParsing(buffer[11], checksum_high, checksum_high, "Checksum_HIGH"); Error = ErrorCodes::ParseFromBytes(buffer[5], buffer[4]); @@ -169,10 +169,11 @@ uint32_t Response_Packet::FromParameter() } // checks to see if the byte is the proper value, and logs it to the serial channel if not -bool Response_Packet::CheckParsing(uint8_t b, uint8_t propervalue, uint8_t alternatevalue, const char* varname, bool UseSerialDebug) +bool Response_Packet::CheckParsing(uint8_t b, uint8_t propervalue, uint8_t alternatevalue, const char* varname) { bool retval = (b != propervalue) && (b != alternatevalue); - if ((UseSerialDebug) && (retval)) +#if FPS_DEBUG + if (retval) { Serial.print("Response_Packet parsing error "); Serial.print(varname); @@ -183,6 +184,7 @@ bool Response_Packet::CheckParsing(uint8_t b, uint8_t propervalue, uint8_t alter Serial.print(" != "); Serial.println(b, HEX); } +#endif return retval; } @@ -215,45 +217,47 @@ uint8_t Response_Packet::GetLowByte(uint16_t w) #ifndef __GNUC__ #pragma region -= Data_Packet =- #endif //__GNUC__ -Data_Packet::Data_Packet(uint8_t* buffer, bool UseSerialDebug) +Data_Packet::Data_Packet(uint8_t* buffer) { - if (UseSerialDebug) - { - CheckParsing(buffer[0], DATA_START_CODE_1, DATA_START_CODE_1, "DATA_START_CODE_1", UseSerialDebug); - CheckParsing(buffer[1], DATA_START_CODE_2, DATA_START_CODE_2, "DATA_START_CODE_2", UseSerialDebug); - CheckParsing(buffer[2], DATA_DEVICE_ID_1, DATA_DEVICE_ID_1, "DATA_DEVICE_ID_1", UseSerialDebug); - CheckParsing(buffer[3], DATA_DEVICE_ID_2, DATA_DEVICE_ID_2, "DATA_DEVICE_ID_2", UseSerialDebug); - - this->checksum = CalculateChecksum(buffer, 4); - } +#if FPS_DEBUG + CheckParsing(buffer[0], DATA_START_CODE_1, DATA_START_CODE_1, "DATA_START_CODE_1"); + CheckParsing(buffer[1], DATA_START_CODE_2, DATA_START_CODE_2, "DATA_START_CODE_2"); + CheckParsing(buffer[2], DATA_DEVICE_ID_1, DATA_DEVICE_ID_1, "DATA_DEVICE_ID_1"); + CheckParsing(buffer[3], DATA_DEVICE_ID_2, DATA_DEVICE_ID_2, "DATA_DEVICE_ID_2"); + + this->checksum = CalculateChecksum(buffer, 4); +#endif } // Get a data packet (128 bytes), calculate checksum and send it to serial -void Data_Packet::GetData(uint8_t buffer[], uint16_t length, bool UseSerialDebug) +void Data_Packet::GetData(uint8_t buffer[]) { - for(uint16_t i = 0; ichecksum = CalculateChecksum(buffer, 128); + for(uint16_t i = 0; i<128; i++) Serial.write(buffer[i]); +#if FPS_DEBUG + this->checksum = CalculateChecksum(buffer, 128); +#endif } // Get the last data packet (<=128 bytes), calculate checksum, validate checksum received and send it to serial -void Data_Packet::GetLastData(uint8_t buffer[], uint16_t length, bool UseSerialDebug) +void Data_Packet::GetLastData(uint8_t buffer[], uint16_t length) { for(uint16_t i = 0; ichecksum = CalculateChecksum(buffer, length-2); - uint8_t checksum_low = GetLowByte(this->checksum); - uint8_t checksum_high = GetHighByte(this->checksum); - CheckParsing(buffer[length-2], checksum_low, checksum_low, "Checksum_LOW", UseSerialDebug); - CheckParsing(buffer[length-1], checksum_high, checksum_high, "Checksum_HIGH", UseSerialDebug); - } + +#if FPS_DEBUG + this->checksum = CalculateChecksum(buffer, length-2); + uint8_t checksum_low = GetLowByte(this->checksum); + uint8_t checksum_high = GetHighByte(this->checksum); + CheckParsing(buffer[length-2], checksum_low, checksum_low, "Checksum_LOW"); + CheckParsing(buffer[length-1], checksum_high, checksum_high, "Checksum_HIGH"); +#endif } // checks to see if the byte is the proper value, and logs it to the serial channel if not -bool Data_Packet::CheckParsing(uint8_t b, uint8_t propervalue, uint8_t alternatevalue, const char* varname, bool UseSerialDebug) +bool Data_Packet::CheckParsing(uint8_t b, uint8_t propervalue, uint8_t alternatevalue, const char* varname) { bool retval = (b != propervalue) && (b != alternatevalue); - if ((UseSerialDebug) && (retval)) +#if FPS_DEBUG + if(retval) { Serial.print("\nData_Packet parsing error "); Serial.print(varname); @@ -264,6 +268,7 @@ bool Data_Packet::CheckParsing(uint8_t b, uint8_t propervalue, uint8_t alternate Serial.print(" != "); Serial.println(b, HEX); } +#endif return retval; } @@ -308,7 +313,6 @@ FPS_GT511C3::FPS_GT511C3(uint8_t rx, uint8_t tx, uint32_t baud) { pin_RX = rx; pin_TX = tx; - this->UseSerialDebug = false; this->Started = false; desiredBaud = baud; }; @@ -330,7 +334,9 @@ FPS_GT511C3::~FPS_GT511C3() bool FPS_GT511C3::Open() { if (!Started) Start(); - if (UseSerialDebug) Serial.println("FPS - Open"); +#if FPS_DEBUG + Serial.println("FPS - Open"); +#endif Command_Packet* cp = new Command_Packet(); cp->Command = Command_Packet::Commands::Open; cp->Parameter[0] = 0x00; @@ -352,7 +358,9 @@ bool FPS_GT511C3::Open() // Implemented it for completeness. void FPS_GT511C3::Close() { - if (UseSerialDebug) Serial.println("FPS - Close"); +#if FPS_DEBUG + Serial.println("FPS - Close"); +#endif Command_Packet* cp = new Command_Packet(); cp->Command = Command_Packet::Commands::Close; cp->Parameter[0] = 0x00; @@ -376,12 +384,16 @@ bool FPS_GT511C3::SetLED(bool on) cp->Command = Command_Packet::Commands::CmosLed; if (on) { - if (UseSerialDebug) Serial.println("FPS - LED on"); +#if FPS_DEBUG + Serial.println("FPS - LED on"); +#endif cp->Parameter[0] = 0x01; } else { - if (UseSerialDebug) Serial.println("FPS - LED off"); +#if FPS_DEBUG + Serial.println("FPS - LED off"); +#endif cp->Parameter[0] = 0x00; } cp->Parameter[1] = 0x00; @@ -406,7 +418,9 @@ bool FPS_GT511C3::ChangeBaudRate(uint32_t baud) { if ((baud == 9600) || (baud == 19200) || (baud == 38400) || (baud == 57600) || (baud == 115200)) { - if (UseSerialDebug) Serial.println("FPS - ChangeBaudRate"); +#if FPS_DEBUG + Serial.println("FPS - ChangeBaudRate"); +#endif Command_Packet* cp = new Command_Packet(); cp->Command = Command_Packet::Commands::ChangeBaudRate; cp->ParameterFrom(baud); @@ -427,7 +441,9 @@ bool FPS_GT511C3::ChangeBaudRate(uint32_t baud) // Return: The total number of enrolled fingerprints uint16_t FPS_GT511C3::GetEnrollCount() { - if (UseSerialDebug) Serial.println("FPS - GetEnrolledCount"); +#if FPS_DEBUG + Serial.println("FPS - GetEnrolledCount"); +#endif Command_Packet* cp = new Command_Packet(); cp->Command = Command_Packet::Commands::GetEnrollCount; cp->Parameter[0] = 0x00; @@ -450,7 +466,9 @@ uint16_t FPS_GT511C3::GetEnrollCount() // Return: True if the ID number is enrolled, false if not bool FPS_GT511C3::CheckEnrolled(uint16_t id) { - if (UseSerialDebug) Serial.println("FPS - CheckEnrolled"); +#if FPS_DEBUG + Serial.println("FPS - CheckEnrolled"); +#endif Command_Packet* cp = new Command_Packet(); cp->Command = Command_Packet::Commands::CheckEnrolled; cp->ParameterFrom(id); @@ -475,7 +493,9 @@ bool FPS_GT511C3::CheckEnrolled(uint16_t id) // 3 - Position(ID) is already used uint8_t FPS_GT511C3::EnrollStart(uint16_t id) { - if (UseSerialDebug) Serial.println("FPS - EnrollStart"); +#if FPS_DEBUG + Serial.println("FPS - EnrollStart"); +#endif Command_Packet* cp = new Command_Packet(); cp->Command = Command_Packet::Commands::EnrollStart; cp->ParameterFrom(id); @@ -503,7 +523,9 @@ uint8_t FPS_GT511C3::EnrollStart(uint16_t id) // 3 - ID in use uint8_t FPS_GT511C3::Enroll1() { - if (UseSerialDebug) Serial.println("FPS - Enroll1"); +#if FPS_DEBUG + Serial.println("FPS - Enroll1"); +#endif Command_Packet* cp = new Command_Packet(); cp->Command = Command_Packet::Commands::Enroll1; uint8_t* packetbytes = cp->GetPacketBytes(); @@ -532,7 +554,9 @@ uint8_t FPS_GT511C3::Enroll1() // 3 - ID in use uint8_t FPS_GT511C3::Enroll2() { - if (UseSerialDebug) Serial.println("FPS - Enroll2"); +#if FPS_DEBUG + Serial.println("FPS - Enroll2"); +#endif Command_Packet* cp = new Command_Packet(); cp->Command = Command_Packet::Commands::Enroll2; byte* packetbytes = cp->GetPacketBytes(); @@ -562,7 +586,9 @@ uint8_t FPS_GT511C3::Enroll2() // 3 - ID in use uint8_t FPS_GT511C3::Enroll3() { - if (UseSerialDebug) Serial.println("FPS - Enroll3"); +#if FPS_DEBUG + Serial.println("FPS - Enroll3"); +#endif Command_Packet* cp = new Command_Packet(); cp->Command = Command_Packet::Commands::Enroll3; byte* packetbytes = cp->GetPacketBytes(); @@ -587,7 +613,9 @@ uint8_t FPS_GT511C3::Enroll3() // Return: true if finger pressed, false if not bool FPS_GT511C3::IsPressFinger() { - if (UseSerialDebug) Serial.println("FPS - IsPressFinger"); +#if FPS_DEBUG + Serial.println("FPS - IsPressFinger"); +#endif Command_Packet* cp = new Command_Packet(); cp->Command = Command_Packet::Commands::IsPressFinger; uint8_t* packetbytes = cp->GetPacketBytes(); @@ -607,7 +635,9 @@ bool FPS_GT511C3::IsPressFinger() // Returns: true if successful, false if position invalid bool FPS_GT511C3::DeleteID(uint16_t id) { - if (UseSerialDebug) Serial.println("FPS - DeleteID"); +#if FPS_DEBUG + Serial.println("FPS - DeleteID"); +#endif Command_Packet* cp = new Command_Packet(); cp->Command = Command_Packet::Commands::DeleteID; cp->ParameterFrom(id); @@ -625,7 +655,9 @@ bool FPS_GT511C3::DeleteID(uint16_t id) // Returns: true if successful, false if db is empty bool FPS_GT511C3::DeleteAll() { - if (UseSerialDebug) Serial.println("FPS - DeleteAll"); +#if FPS_DEBUG + Serial.println("FPS - DeleteAll"); +#endif Command_Packet* cp = new Command_Packet(); cp->Command = Command_Packet::Commands::DeleteAll; uint8_t* packetbytes = cp->GetPacketBytes(); @@ -648,7 +680,9 @@ bool FPS_GT511C3::DeleteAll() // 3 - Verified FALSE (not the correct finger) uint8_t FPS_GT511C3::Verify1_1(uint16_t id) { - if (UseSerialDebug) Serial.println("FPS - Verify1_1"); +#if FPS_DEBUG + Serial.println("FPS - Verify1_1"); +#endif Command_Packet* cp = new Command_Packet(); cp->Command = Command_Packet::Commands::Verify1_1; cp->ParameterFrom(id); @@ -679,7 +713,9 @@ uint8_t FPS_GT511C3::Verify1_1(uint16_t id) // 200, if using GT-521F32/GT-511C3 uint16_t FPS_GT511C3::Identify1_N() { - if (UseSerialDebug) Serial.println("FPS - Identify1_N"); +#if FPS_DEBUG + Serial.println("FPS - Identify1_N"); +#endif Command_Packet* cp = new Command_Packet(); cp->Command = Command_Packet::Commands::Identify1_N; uint8_t* packetbytes = cp->GetPacketBytes(); @@ -701,7 +737,9 @@ uint16_t FPS_GT511C3::Identify1_N() // Returns: True if ok, false if no finger pressed bool FPS_GT511C3::CaptureFinger(bool highquality) { - if (UseSerialDebug) Serial.println("FPS - CaptureFinger"); +#if FPS_DEBUG + Serial.println("FPS - CaptureFinger"); +#endif Command_Packet* cp = new Command_Packet(); cp->Command = Command_Packet::Commands::CaptureFinger; if (highquality) @@ -733,7 +771,9 @@ bool FPS_GT511C3::CaptureFinger(bool highquality) // Parameter: true to ignore the documentation and get valid image data. bool FPS_GT511C3::GetImage(bool patched) { - if (UseSerialDebug) Serial.println("FPS - GetImage"); +#if FPS_DEBUG + Serial.println("FPS - GetImage"); +#endif Command_Packet* cp = new Command_Packet(); cp->Command = Command_Packet::Commands::GetImage; uint8_t* packetbytes = cp->GetPacketBytes(); @@ -775,7 +815,9 @@ bool FPS_GT511C3::GetImage(bool patched) // Also, avoid using UseSerialDebug for this task, since it's easier to overflow. bool FPS_GT511C3::GetRawImage() { - if (UseSerialDebug) Serial.println("FPS - GetRawImage"); +#if FPS_DEBUG + Serial.println("FPS - GetRawImage"); +#endif Command_Packet* cp = new Command_Packet(); cp->Command = Command_Packet::Commands::GetRawImage; uint8_t* packetbytes = cp->GetPacketBytes(); @@ -797,7 +839,9 @@ bool FPS_GT511C3::GetRawImage() // 2 - ID not used (no template to download uint8_t FPS_GT511C3::GetTemplate(uint16_t id) { - if (UseSerialDebug) Serial.println("FPS - GetTemplate"); +#if FPS_DEBUG + Serial.println("FPS - GetTemplate"); +#endif Command_Packet* cp = new Command_Packet(); cp->Command = Command_Packet::Commands::GetTemplate; cp->ParameterFrom(id); @@ -832,7 +876,9 @@ uint8_t FPS_GT511C3::GetTemplate(uint16_t id) // 4 - Device error uint16_t FPS_GT511C3::SetTemplate(byte* tmplt, uint16_t id, bool duplicateCheck) { - if (UseSerialDebug) Serial.println("FPS - SetTemplate"); +#if FPS_DEBUG + Serial.println("FPS - SetTemplate"); +#endif Command_Packet* cp = new Command_Packet(); cp->Command = Command_Packet::Commands::SetTemplate; cp->ParameterFrom(0xFFFF0000 * !duplicateCheck + id); // Will set the HIWORD if duplicateCheck = false @@ -914,12 +960,12 @@ void FPS_GT511C3::Start() uint32_t BaudRates[5] = {9600, 19200, 38400, 57600, 115200}; for(uint8_t i = 0; i<5; i++) // Trying to find FPS baud rate { - if(UseSerialDebug) - { - Serial.print("Establishing connection with FPS at baud rate: "); - Serial.print(BaudRates[i]); - Serial.println(); - } +#if FPS_DEBUG + Serial.print("Establishing connection with FPS at baud rate: "); + Serial.print(BaudRates[i]); + Serial.println(); +#endif + _serial.begin(BaudRates[i]); _serial.listen(); SendCommand(packetbytes, 12); @@ -957,47 +1003,43 @@ void FPS_GT511C3::Start() while (_serial.available() == false) delay(10); resp[i]= (uint8_t) _serial.read(); } - if (UseSerialDebug) - { - Response_Packet* rp = new Response_Packet(resp, UseSerialDebug); - Serial.print("FPS - RECV: "); - SendToSerial(rp->RawBytes, 12); - Serial.println(); - Serial.println(); - delete rp; - } +#if FPS_DEBUG + Response_Packet* rp = new Response_Packet(resp); + Serial.print("FPS - RECV: "); + SendToSerial(rp->RawBytes, 12); + Serial.println(); + Serial.println(); + delete rp; +#endif actualBaud = BaudRates[i]; break; } } - if(UseSerialDebug) - { - Serial.print("Connection established succesfully. FPS baud rate was: "); - Serial.print(actualBaud); - Serial.println(); - Serial.println(); - } +#if FPS_DEBUG + Serial.print("Connection established succesfully. FPS baud rate was: "); + Serial.print(actualBaud); + Serial.println(); + Serial.println(); +#endif if (actualBaud == 0) while(true) { - if(UseSerialDebug) - { - Serial.print("EXCEPTION: FPS didn't answer to communications. Code execution stopped."); - Serial.println(); - } +#if FPS_DEBUG + Serial.print("EXCEPTION: FPS didn't answer to communications. Code execution stopped."); + Serial.println(); +#endif delay(1000); // Something went terribly wrong with the FPS, and you aren't allowed to leave } if (actualBaud != baud) { - if(UseSerialDebug) - { - Serial.print("Undesired baud rate. Changing baud rate to: "); - Serial.print(baud); - Serial.println(); - Serial.println(); - } +#if FPS_DEBUG + Serial.print("Undesired baud rate. Changing baud rate to: "); + Serial.print(baud); + Serial.println(); + Serial.println(); +#endif ChangeBaudRate(baud); } Started = true; @@ -1007,12 +1049,11 @@ void FPS_GT511C3::Start() void FPS_GT511C3::SendCommand(uint8_t cmd[], uint16_t length) { _serial.write(cmd, length); - if (UseSerialDebug) - { - Serial.print("FPS - SEND: "); - SendToSerial(cmd, length); - Serial.println(); - } +#if FPS_DEBUG + Serial.print("FPS - SEND: "); + SendToSerial(cmd, length); + Serial.println(); +#endif }; // Gets the response to the command from the software serial channel (and waits for it) @@ -1045,14 +1086,13 @@ Response_Packet* FPS_GT511C3::GetResponse() resp[i]= (uint8_t) _serial.read(); } - Response_Packet* rp = new Response_Packet(resp, UseSerialDebug); - if (UseSerialDebug) - { - Serial.print("FPS - RECV: "); - SendToSerial(rp->RawBytes, 12); - Serial.println(); - Serial.println(); - } + Response_Packet* rp = new Response_Packet(resp); +#if FPS_DEBUG + Serial.print("FPS - RECV: "); + SendToSerial(rp->RawBytes, 12); + Serial.println(); + Serial.println(); +#endif return rp; }; @@ -1086,7 +1126,7 @@ void FPS_GT511C3::GetData(uint16_t length) while (_serial.available() == false) delay(10); firstdata[i]= (uint8_t) _serial.read(); } - Data_Packet dp(firstdata, UseSerialDebug); + Data_Packet dp(firstdata); uint16_t numberPacketsNeeded = (length-4) / 128; bool smallLastPacket = false; @@ -1105,22 +1145,23 @@ void FPS_GT511C3::GetData(uint16_t length) while (_serial.available() == false) delay(1); if(_serial.overflow()) { - if(UseSerialDebug) - { - Serial.println("Overflow! Data download stopped"); - Serial.println("Cleaning serial buffer..."); - } +#if FPS_DEBUG + Serial.println("Overflow! Data download stopped"); + Serial.println("Cleaning serial buffer..."); +#endif for (uint16_t j = 0; j Date: Wed, 28 Nov 2018 18:18:54 +0100 Subject: [PATCH 17/27] Switch to 64 bytes packets, since that's the default serial buffer size. --- src/FPS_GT511C3.cpp | 24 ++++++++++++------------ src/FPS_GT511C3.h | 2 +- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/FPS_GT511C3.cpp b/src/FPS_GT511C3.cpp index c9ee9e1..cf30e8a 100644 --- a/src/FPS_GT511C3.cpp +++ b/src/FPS_GT511C3.cpp @@ -229,16 +229,16 @@ Data_Packet::Data_Packet(uint8_t* buffer) #endif } -// Get a data packet (128 bytes), calculate checksum and send it to serial -void Data_Packet::GetData(uint8_t buffer[]) +// Get a data packet, calculate checksum and send it to serial +void Data_Packet::GetData(uint8_t buffer[], uint16_t length) { - for(uint16_t i = 0; i<128; i++) Serial.write(buffer[i]); + for(uint16_t i = 0; ichecksum = CalculateChecksum(buffer, 128); + this->checksum = CalculateChecksum(buffer, length); #endif } -// Get the last data packet (<=128 bytes), calculate checksum, validate checksum received and send it to serial +// Get the last data packet, calculate checksum, validate checksum received and send it to serial void Data_Packet::GetLastData(uint8_t buffer[], uint16_t length) { for(uint16_t i = 0; i Date: Wed, 28 Nov 2018 20:15:45 +0100 Subject: [PATCH 18/27] Since the template doesn't require much memory storage (500 bytes will do), I implemented a function that allows you to return the template, instead of just simply sending it over Serial. Have fun. --- src/FPS_GT511C3.cpp | 99 +++++++++++++++++++++++++++++++++++++++++++++ src/FPS_GT511C3.h | 9 +++++ 2 files changed, 108 insertions(+) diff --git a/src/FPS_GT511C3.cpp b/src/FPS_GT511C3.cpp index cf30e8a..0a68062 100644 --- a/src/FPS_GT511C3.cpp +++ b/src/FPS_GT511C3.cpp @@ -863,6 +863,39 @@ uint8_t FPS_GT511C3::GetTemplate(uint16_t id) } } +// Gets a template from the fps (498 bytes + 2 bytes checksum) and store it in an array +// Parameter: 0-199 ID number, array pointer to store the data +// Returns: +// 0 - ACK Download starting +// 1 - Invalid position +// 2 - ID not used (no template to download +// 3 - Data download failed (Serial overflow) +uint8_t FPS_GT511C3::GetTemplate(uint16_t id, uint8_t data[]) +{ +#if FPS_DEBUG + Serial.println("FPS - GetTemplate"); +#endif + Command_Packet* cp = new Command_Packet(); + cp->Command = Command_Packet::Commands::GetTemplate; + cp->ParameterFrom(id); + uint8_t* packetbytes = cp->GetPacketBytes(); + delete cp; + SendCommand(packetbytes, 12); + delete packetbytes; + Response_Packet* rp = GetResponse(); + if(rp->ACK) + { + delete rp; + if (ReturnData(498+6, data)) return 0; + else return 3; + } else + { + uint32_t retval = rp->FromParameter(); + delete rp; + return retval; + } +} + // Uploads a template to the fps // Parameter: the template (498 bytes) // Parameter: the ID number to upload @@ -1173,6 +1206,72 @@ void FPS_GT511C3::GetData(uint16_t length) dp.GetLastData(lastdata, lastPacketSize); }; +// Gets the data (length bytes) from the software serial channel (and waits for it) +// and store it in an array +// Return: True if the data was succesfully downloaded +bool FPS_GT511C3::ReturnData(uint16_t length, uint8_t data[]) +{ + uint8_t firstbyte, secondbyte = 0; + bool done = false; + _serial.listen(); + while (done == false) + { + while (_serial.available() == false) delay(10); + firstbyte = (uint8_t)_serial.read(); + if (firstbyte == Data_Packet::DATA_START_CODE_1) + { + while (_serial.available() == false) delay(10); + secondbyte = (uint8_t)_serial.read(); + if (secondbyte == Data_Packet::DATA_START_CODE_2) + { + done = true; + } + } + } + + uint8_t firstdata[4]; + firstdata[0] = firstbyte; + firstdata[1] = secondbyte; + for (uint8_t i=2; i < 4; i++) + { + while (_serial.available() == false) delay(10); + firstdata[i]= (uint8_t) _serial.read(); + } + Data_Packet dp(firstdata); + + uint16_t numberPacketsNeeded = (length-4) / 64; + bool smallLastPacket = false; + uint8_t lastPacketSize = (length-4) % 64; + if(lastPacketSize != 0) + { + numberPacketsNeeded++; + smallLastPacket = true; + } + + for (uint16_t i=0; i < length-4; i++) + { + while (_serial.available() == false) delay(1); + if(_serial.overflow()) + { +#if FPS_DEBUG + Serial.println("Overflow! Data download stopped"); + Serial.println("Cleaning serial buffer..."); +#endif + for (uint16_t j = 0; j Date: Wed, 28 Nov 2018 20:26:12 +0100 Subject: [PATCH 19/27] A few optimizations and some deleted obsolete code. --- src/FPS_GT511C3.cpp | 21 ++++++--------------- 1 file changed, 6 insertions(+), 15 deletions(-) diff --git a/src/FPS_GT511C3.cpp b/src/FPS_GT511C3.cpp index 0a68062..0bb4699 100644 --- a/src/FPS_GT511C3.cpp +++ b/src/FPS_GT511C3.cpp @@ -1162,12 +1162,12 @@ void FPS_GT511C3::GetData(uint16_t length) Data_Packet dp(firstdata); uint16_t numberPacketsNeeded = (length-4) / 64; - bool smallLastPacket = false; uint8_t lastPacketSize = (length-4) % 64; - if(lastPacketSize != 0) - { - numberPacketsNeeded++; - smallLastPacket = true; + if(lastPacketSize != 0) numberPacketsNeeded++; + else { + // Last packet requires special treatment, so you don't want it to pass over the main loop + numberPacketsNeeded--; + lastPacketSize = 64; } uint8_t data[64]; @@ -1237,16 +1237,7 @@ bool FPS_GT511C3::ReturnData(uint16_t length, uint8_t data[]) while (_serial.available() == false) delay(10); firstdata[i]= (uint8_t) _serial.read(); } - Data_Packet dp(firstdata); - - uint16_t numberPacketsNeeded = (length-4) / 64; - bool smallLastPacket = false; - uint8_t lastPacketSize = (length-4) % 64; - if(lastPacketSize != 0) - { - numberPacketsNeeded++; - smallLastPacket = true; - } + Data_Packet dp(firstdata); // Not needed for (uint16_t i=0; i < length-4; i++) { From 1a16661a4b90ac52ffd77c567d420b8cc862c064 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20L=C3=B3pez=20Chica?= Date: Wed, 28 Nov 2018 21:19:28 +0100 Subject: [PATCH 20/27] Debug methods won't use that much memory anymore (they were spending over 800 bytes in the SRAM). Instead, they are now saved in flash memory. --- src/FPS_GT511C3.cpp | 114 ++++++++++++++++++++++---------------------- src/FPS_GT511C3.h | 4 +- 2 files changed, 59 insertions(+), 59 deletions(-) diff --git a/src/FPS_GT511C3.cpp b/src/FPS_GT511C3.cpp index 0bb4699..4dc2aec 100644 --- a/src/FPS_GT511C3.cpp +++ b/src/FPS_GT511C3.cpp @@ -92,19 +92,19 @@ Command_Packet::Command_Packet() // creates and parses a response packet from the finger print scanner Response_Packet::Response_Packet(uint8_t* buffer) { - CheckParsing(buffer[0], RESPONSE_START_CODE_1, RESPONSE_START_CODE_1, "RESPONSE_START_CODE_1"); - CheckParsing(buffer[1], RESPONSE_START_CODE_2, RESPONSE_START_CODE_2, "RESPONSE_START_CODE_2"); - CheckParsing(buffer[2], RESPONSE_DEVICE_ID_1, RESPONSE_DEVICE_ID_1, "RESPONSE_DEVICE_ID_1"); - CheckParsing(buffer[3], RESPONSE_DEVICE_ID_2, RESPONSE_DEVICE_ID_2, "RESPONSE_DEVICE_ID_2"); - CheckParsing(buffer[8], 0x30, 0x31, "AckNak_LOW"); + CheckParsing(buffer[0], RESPONSE_START_CODE_1, RESPONSE_START_CODE_1, F("RESPONSE_START_CODE_1")); + CheckParsing(buffer[1], RESPONSE_START_CODE_2, RESPONSE_START_CODE_2, F("RESPONSE_START_CODE_2")); + CheckParsing(buffer[2], RESPONSE_DEVICE_ID_1, RESPONSE_DEVICE_ID_1, F("RESPONSE_DEVICE_ID_1")); + CheckParsing(buffer[3], RESPONSE_DEVICE_ID_2, RESPONSE_DEVICE_ID_2, F("RESPONSE_DEVICE_ID_2")); + CheckParsing(buffer[8], 0x30, 0x31, F("AckNak_LOW")); if (buffer[8] == 0x30) ACK = true; else ACK = false; - CheckParsing(buffer[9], 0x00, 0x00, "AckNak_HIGH"); + CheckParsing(buffer[9], 0x00, 0x00, F("AckNak_HIGH")); uint16_t checksum = CalculateChecksum(buffer, 10); uint8_t checksum_low = GetLowByte(checksum); uint8_t checksum_high = GetHighByte(checksum); - CheckParsing(buffer[10], checksum_low, checksum_low, "Checksum_LOW"); - CheckParsing(buffer[11], checksum_high, checksum_high, "Checksum_HIGH"); + CheckParsing(buffer[10], checksum_low, checksum_low, F("Checksum_LOW")); + CheckParsing(buffer[11], checksum_high, checksum_high, F("Checksum_HIGH")); Error = ErrorCodes::ParseFromBytes(buffer[5], buffer[4]); @@ -169,19 +169,19 @@ uint32_t Response_Packet::FromParameter() } // checks to see if the byte is the proper value, and logs it to the serial channel if not -bool Response_Packet::CheckParsing(uint8_t b, uint8_t propervalue, uint8_t alternatevalue, const char* varname) +bool Response_Packet::CheckParsing(uint8_t b, uint8_t propervalue, uint8_t alternatevalue, const String varname) { bool retval = (b != propervalue) && (b != alternatevalue); #if FPS_DEBUG if (retval) { - Serial.print("Response_Packet parsing error "); + Serial.print(F("Response_Packet parsing error ")); Serial.print(varname); - Serial.print(" "); + Serial.print(F(" ")); Serial.print(propervalue, HEX); - Serial.print(" || "); + Serial.print(F(" || ")); Serial.print(alternatevalue, HEX); - Serial.print(" != "); + Serial.print(F(" != ")); Serial.println(b, HEX); } #endif @@ -220,10 +220,10 @@ uint8_t Response_Packet::GetLowByte(uint16_t w) Data_Packet::Data_Packet(uint8_t* buffer) { #if FPS_DEBUG - CheckParsing(buffer[0], DATA_START_CODE_1, DATA_START_CODE_1, "DATA_START_CODE_1"); - CheckParsing(buffer[1], DATA_START_CODE_2, DATA_START_CODE_2, "DATA_START_CODE_2"); - CheckParsing(buffer[2], DATA_DEVICE_ID_1, DATA_DEVICE_ID_1, "DATA_DEVICE_ID_1"); - CheckParsing(buffer[3], DATA_DEVICE_ID_2, DATA_DEVICE_ID_2, "DATA_DEVICE_ID_2"); + CheckParsing(buffer[0], DATA_START_CODE_1, DATA_START_CODE_1, F("DATA_START_CODE_1")); + CheckParsing(buffer[1], DATA_START_CODE_2, DATA_START_CODE_2, F("DATA_START_CODE_2")); + CheckParsing(buffer[2], DATA_DEVICE_ID_1, DATA_DEVICE_ID_1, F("DATA_DEVICE_ID_1")); + CheckParsing(buffer[3], DATA_DEVICE_ID_2, DATA_DEVICE_ID_2, F("DATA_DEVICE_ID_2")); this->checksum = CalculateChecksum(buffer, 4); #endif @@ -247,25 +247,25 @@ void Data_Packet::GetLastData(uint8_t buffer[], uint16_t length) this->checksum = CalculateChecksum(buffer, length-2); uint8_t checksum_low = GetLowByte(this->checksum); uint8_t checksum_high = GetHighByte(this->checksum); - CheckParsing(buffer[length-2], checksum_low, checksum_low, "Checksum_LOW"); - CheckParsing(buffer[length-1], checksum_high, checksum_high, "Checksum_HIGH"); + CheckParsing(buffer[length-2], checksum_low, checksum_low, F("Checksum_LOW")); + CheckParsing(buffer[length-1], checksum_high, checksum_high, F("Checksum_HIGH")); #endif } // checks to see if the byte is the proper value, and logs it to the serial channel if not -bool Data_Packet::CheckParsing(uint8_t b, uint8_t propervalue, uint8_t alternatevalue, const char* varname) +bool Data_Packet::CheckParsing(uint8_t b, uint8_t propervalue, uint8_t alternatevalue, const String varname) { bool retval = (b != propervalue) && (b != alternatevalue); #if FPS_DEBUG if(retval) { - Serial.print("\nData_Packet parsing error "); + Serial.print(F("\nData_Packet parsing error ")); Serial.print(varname); - Serial.print(" "); + Serial.print(F(" ")); Serial.print(propervalue, HEX); - Serial.print(" || "); + Serial.print(F(" || ")); Serial.print(alternatevalue, HEX); - Serial.print(" != "); + Serial.print(F(" != ")); Serial.println(b, HEX); } #endif @@ -335,7 +335,7 @@ bool FPS_GT511C3::Open() { if (!Started) Start(); #if FPS_DEBUG - Serial.println("FPS - Open"); + Serial.println(F("FPS - Open")); #endif Command_Packet* cp = new Command_Packet(); cp->Command = Command_Packet::Commands::Open; @@ -359,7 +359,7 @@ bool FPS_GT511C3::Open() void FPS_GT511C3::Close() { #if FPS_DEBUG - Serial.println("FPS - Close"); + Serial.println(F("FPS - Close")); #endif Command_Packet* cp = new Command_Packet(); cp->Command = Command_Packet::Commands::Close; @@ -385,14 +385,14 @@ bool FPS_GT511C3::SetLED(bool on) if (on) { #if FPS_DEBUG - Serial.println("FPS - LED on"); + Serial.println(F("FPS - LED on")); #endif cp->Parameter[0] = 0x01; } else { #if FPS_DEBUG - Serial.println("FPS - LED off"); + Serial.println(F("FPS - LED off")); #endif cp->Parameter[0] = 0x00; } @@ -419,7 +419,7 @@ bool FPS_GT511C3::ChangeBaudRate(uint32_t baud) if ((baud == 9600) || (baud == 19200) || (baud == 38400) || (baud == 57600) || (baud == 115200)) { #if FPS_DEBUG - Serial.println("FPS - ChangeBaudRate"); + Serial.println(F("FPS - ChangeBaudRate")); #endif Command_Packet* cp = new Command_Packet(); cp->Command = Command_Packet::Commands::ChangeBaudRate; @@ -442,7 +442,7 @@ bool FPS_GT511C3::ChangeBaudRate(uint32_t baud) uint16_t FPS_GT511C3::GetEnrollCount() { #if FPS_DEBUG - Serial.println("FPS - GetEnrolledCount"); + Serial.println(F("FPS - GetEnrolledCount")); #endif Command_Packet* cp = new Command_Packet(); cp->Command = Command_Packet::Commands::GetEnrollCount; @@ -467,7 +467,7 @@ uint16_t FPS_GT511C3::GetEnrollCount() bool FPS_GT511C3::CheckEnrolled(uint16_t id) { #if FPS_DEBUG - Serial.println("FPS - CheckEnrolled"); + Serial.println(F("FPS - CheckEnrolled")); #endif Command_Packet* cp = new Command_Packet(); cp->Command = Command_Packet::Commands::CheckEnrolled; @@ -494,7 +494,7 @@ bool FPS_GT511C3::CheckEnrolled(uint16_t id) uint8_t FPS_GT511C3::EnrollStart(uint16_t id) { #if FPS_DEBUG - Serial.println("FPS - EnrollStart"); + Serial.println(F("FPS - EnrollStart")); #endif Command_Packet* cp = new Command_Packet(); cp->Command = Command_Packet::Commands::EnrollStart; @@ -524,7 +524,7 @@ uint8_t FPS_GT511C3::EnrollStart(uint16_t id) uint8_t FPS_GT511C3::Enroll1() { #if FPS_DEBUG - Serial.println("FPS - Enroll1"); + Serial.println(F("FPS - Enroll1")); #endif Command_Packet* cp = new Command_Packet(); cp->Command = Command_Packet::Commands::Enroll1; @@ -555,7 +555,7 @@ uint8_t FPS_GT511C3::Enroll1() uint8_t FPS_GT511C3::Enroll2() { #if FPS_DEBUG - Serial.println("FPS - Enroll2"); + Serial.println(F("FPS - Enroll2")); #endif Command_Packet* cp = new Command_Packet(); cp->Command = Command_Packet::Commands::Enroll2; @@ -587,7 +587,7 @@ uint8_t FPS_GT511C3::Enroll2() uint8_t FPS_GT511C3::Enroll3() { #if FPS_DEBUG - Serial.println("FPS - Enroll3"); + Serial.println(F("FPS - Enroll3")); #endif Command_Packet* cp = new Command_Packet(); cp->Command = Command_Packet::Commands::Enroll3; @@ -614,7 +614,7 @@ uint8_t FPS_GT511C3::Enroll3() bool FPS_GT511C3::IsPressFinger() { #if FPS_DEBUG - Serial.println("FPS - IsPressFinger"); + Serial.println(F("FPS - IsPressFinger")); #endif Command_Packet* cp = new Command_Packet(); cp->Command = Command_Packet::Commands::IsPressFinger; @@ -636,7 +636,7 @@ bool FPS_GT511C3::IsPressFinger() bool FPS_GT511C3::DeleteID(uint16_t id) { #if FPS_DEBUG - Serial.println("FPS - DeleteID"); + Serial.println(F("FPS - DeleteID")); #endif Command_Packet* cp = new Command_Packet(); cp->Command = Command_Packet::Commands::DeleteID; @@ -656,7 +656,7 @@ bool FPS_GT511C3::DeleteID(uint16_t id) bool FPS_GT511C3::DeleteAll() { #if FPS_DEBUG - Serial.println("FPS - DeleteAll"); + Serial.println(F("FPS - DeleteAll")); #endif Command_Packet* cp = new Command_Packet(); cp->Command = Command_Packet::Commands::DeleteAll; @@ -681,7 +681,7 @@ bool FPS_GT511C3::DeleteAll() uint8_t FPS_GT511C3::Verify1_1(uint16_t id) { #if FPS_DEBUG - Serial.println("FPS - Verify1_1"); + Serial.println(F("FPS - Verify1_1")); #endif Command_Packet* cp = new Command_Packet(); cp->Command = Command_Packet::Commands::Verify1_1; @@ -714,7 +714,7 @@ uint8_t FPS_GT511C3::Verify1_1(uint16_t id) uint16_t FPS_GT511C3::Identify1_N() { #if FPS_DEBUG - Serial.println("FPS - Identify1_N"); + Serial.println(F("FPS - Identify1_N")); #endif Command_Packet* cp = new Command_Packet(); cp->Command = Command_Packet::Commands::Identify1_N; @@ -738,7 +738,7 @@ uint16_t FPS_GT511C3::Identify1_N() bool FPS_GT511C3::CaptureFinger(bool highquality) { #if FPS_DEBUG - Serial.println("FPS - CaptureFinger"); + Serial.println(F("FPS - CaptureFinger")); #endif Command_Packet* cp = new Command_Packet(); cp->Command = Command_Packet::Commands::CaptureFinger; @@ -772,7 +772,7 @@ bool FPS_GT511C3::CaptureFinger(bool highquality) bool FPS_GT511C3::GetImage(bool patched) { #if FPS_DEBUG - Serial.println("FPS - GetImage"); + Serial.println(F("FPS - GetImage")); #endif Command_Packet* cp = new Command_Packet(); cp->Command = Command_Packet::Commands::GetImage; @@ -816,7 +816,7 @@ bool FPS_GT511C3::GetImage(bool patched) bool FPS_GT511C3::GetRawImage() { #if FPS_DEBUG - Serial.println("FPS - GetRawImage"); + Serial.println(F("FPS - GetRawImage")); #endif Command_Packet* cp = new Command_Packet(); cp->Command = Command_Packet::Commands::GetRawImage; @@ -840,7 +840,7 @@ bool FPS_GT511C3::GetRawImage() uint8_t FPS_GT511C3::GetTemplate(uint16_t id) { #if FPS_DEBUG - Serial.println("FPS - GetTemplate"); + Serial.println(F("FPS - GetTemplate")); #endif Command_Packet* cp = new Command_Packet(); cp->Command = Command_Packet::Commands::GetTemplate; @@ -873,7 +873,7 @@ uint8_t FPS_GT511C3::GetTemplate(uint16_t id) uint8_t FPS_GT511C3::GetTemplate(uint16_t id, uint8_t data[]) { #if FPS_DEBUG - Serial.println("FPS - GetTemplate"); + Serial.println(F("FPS - GetTemplate")); #endif Command_Packet* cp = new Command_Packet(); cp->Command = Command_Packet::Commands::GetTemplate; @@ -910,7 +910,7 @@ uint8_t FPS_GT511C3::GetTemplate(uint16_t id, uint8_t data[]) uint16_t FPS_GT511C3::SetTemplate(byte* tmplt, uint16_t id, bool duplicateCheck) { #if FPS_DEBUG - Serial.println("FPS - SetTemplate"); + Serial.println(F("FPS - SetTemplate")); #endif Command_Packet* cp = new Command_Packet(); cp->Command = Command_Packet::Commands::SetTemplate; @@ -994,7 +994,7 @@ void FPS_GT511C3::Start() for(uint8_t i = 0; i<5; i++) // Trying to find FPS baud rate { #if FPS_DEBUG - Serial.print("Establishing connection with FPS at baud rate: "); + Serial.print(F("Establishing connection with FPS at baud rate: ")); Serial.print(BaudRates[i]); Serial.println(); #endif @@ -1050,7 +1050,7 @@ void FPS_GT511C3::Start() } #if FPS_DEBUG - Serial.print("Connection established succesfully. FPS baud rate was: "); + Serial.print(F("Connection established succesfully. FPS baud rate was: ")); Serial.print(actualBaud); Serial.println(); Serial.println(); @@ -1059,7 +1059,7 @@ void FPS_GT511C3::Start() if (actualBaud == 0) while(true) { #if FPS_DEBUG - Serial.print("EXCEPTION: FPS didn't answer to communications. Code execution stopped."); + Serial.print(F("EXCEPTION: FPS didn't answer to communications. Code execution stopped.")); Serial.println(); #endif delay(1000); // Something went terribly wrong with the FPS, and you aren't allowed to leave @@ -1068,7 +1068,7 @@ void FPS_GT511C3::Start() if (actualBaud != baud) { #if FPS_DEBUG - Serial.print("Undesired baud rate. Changing baud rate to: "); + Serial.print(F("Undesired baud rate. Changing baud rate to: ")); Serial.print(baud); Serial.println(); Serial.println(); @@ -1083,7 +1083,7 @@ void FPS_GT511C3::SendCommand(uint8_t cmd[], uint16_t length) { _serial.write(cmd, length); #if FPS_DEBUG - Serial.print("FPS - SEND: "); + Serial.print(F("FPS - SEND: ")); SendToSerial(cmd, length); Serial.println(); #endif @@ -1179,8 +1179,8 @@ void FPS_GT511C3::GetData(uint16_t length) if(_serial.overflow()) { #if FPS_DEBUG - Serial.println("Overflow! Data download stopped"); - Serial.println("Cleaning serial buffer..."); + Serial.println(F("Overflow! Data download stopped")); + Serial.println(F("Cleaning serial buffer...")); #endif for (uint16_t j = 0; j Date: Wed, 28 Nov 2018 21:27:08 +0100 Subject: [PATCH 21/27] V1.2.2 Release: Implemented GetTemplate() additional method that allows you to download and return the template without sending it over serial. Other changes: - Further optimizations. - Fixed a few errors with the count of packets needed. - Debug methods won't use too much memory anymore. - A new way to enable or disable debug code. - ReturnData() method that works almost exactly as GetData(), but returning the data instead, allowing you for further data processing. --- library.json | 2 +- library.properties | 2 +- src/FPS_GT511C3.cpp | 397 +++++++++++++++++++++++++++++--------------- src/FPS_GT511C3.h | 29 +++- 4 files changed, 287 insertions(+), 143 deletions(-) diff --git a/library.json b/library.json index 118256f..4f8b609 100644 --- a/library.json +++ b/library.json @@ -7,7 +7,7 @@ "type": "git", "url": "https://github.com/Fasgort/Fingerprint_Scanner-TTL.git" }, - "version": "1.2.0", + "version": "1.2.2", "frameworks": "arduino", "platforms": "atmelavr" } diff --git a/library.properties b/library.properties index bf8f6b6..fa95a4d 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=Fingerprint Scanner TTL -version=1.2.0 +version=1.2.2 author=Josh Hawley, modified by David López Chica maintainer=David López Chica sentence=Arduino examples for ADH-Tech's Fingerprint Scanners. diff --git a/src/FPS_GT511C3.cpp b/src/FPS_GT511C3.cpp index ae5b9f0..4dc2aec 100644 --- a/src/FPS_GT511C3.cpp +++ b/src/FPS_GT511C3.cpp @@ -90,21 +90,21 @@ Command_Packet::Command_Packet() #pragma region -= Response_Packet Definitions =- #endif //__GNUC__ // creates and parses a response packet from the finger print scanner -Response_Packet::Response_Packet(uint8_t* buffer, bool UseSerialDebug) +Response_Packet::Response_Packet(uint8_t* buffer) { - CheckParsing(buffer[0], RESPONSE_START_CODE_1, RESPONSE_START_CODE_1, "RESPONSE_START_CODE_1", UseSerialDebug); - CheckParsing(buffer[1], RESPONSE_START_CODE_2, RESPONSE_START_CODE_2, "RESPONSE_START_CODE_2", UseSerialDebug); - CheckParsing(buffer[2], RESPONSE_DEVICE_ID_1, RESPONSE_DEVICE_ID_1, "RESPONSE_DEVICE_ID_1", UseSerialDebug); - CheckParsing(buffer[3], RESPONSE_DEVICE_ID_2, RESPONSE_DEVICE_ID_2, "RESPONSE_DEVICE_ID_2", UseSerialDebug); - CheckParsing(buffer[8], 0x30, 0x31, "AckNak_LOW", UseSerialDebug); + CheckParsing(buffer[0], RESPONSE_START_CODE_1, RESPONSE_START_CODE_1, F("RESPONSE_START_CODE_1")); + CheckParsing(buffer[1], RESPONSE_START_CODE_2, RESPONSE_START_CODE_2, F("RESPONSE_START_CODE_2")); + CheckParsing(buffer[2], RESPONSE_DEVICE_ID_1, RESPONSE_DEVICE_ID_1, F("RESPONSE_DEVICE_ID_1")); + CheckParsing(buffer[3], RESPONSE_DEVICE_ID_2, RESPONSE_DEVICE_ID_2, F("RESPONSE_DEVICE_ID_2")); + CheckParsing(buffer[8], 0x30, 0x31, F("AckNak_LOW")); if (buffer[8] == 0x30) ACK = true; else ACK = false; - CheckParsing(buffer[9], 0x00, 0x00, "AckNak_HIGH", UseSerialDebug); + CheckParsing(buffer[9], 0x00, 0x00, F("AckNak_HIGH")); uint16_t checksum = CalculateChecksum(buffer, 10); uint8_t checksum_low = GetLowByte(checksum); uint8_t checksum_high = GetHighByte(checksum); - CheckParsing(buffer[10], checksum_low, checksum_low, "Checksum_LOW", UseSerialDebug); - CheckParsing(buffer[11], checksum_high, checksum_high, "Checksum_HIGH", UseSerialDebug); + CheckParsing(buffer[10], checksum_low, checksum_low, F("Checksum_LOW")); + CheckParsing(buffer[11], checksum_high, checksum_high, F("Checksum_HIGH")); Error = ErrorCodes::ParseFromBytes(buffer[5], buffer[4]); @@ -169,20 +169,22 @@ uint32_t Response_Packet::FromParameter() } // checks to see if the byte is the proper value, and logs it to the serial channel if not -bool Response_Packet::CheckParsing(uint8_t b, uint8_t propervalue, uint8_t alternatevalue, const char* varname, bool UseSerialDebug) +bool Response_Packet::CheckParsing(uint8_t b, uint8_t propervalue, uint8_t alternatevalue, const String varname) { bool retval = (b != propervalue) && (b != alternatevalue); - if ((UseSerialDebug) && (retval)) +#if FPS_DEBUG + if (retval) { - Serial.print("Response_Packet parsing error "); + Serial.print(F("Response_Packet parsing error ")); Serial.print(varname); - Serial.print(" "); + Serial.print(F(" ")); Serial.print(propervalue, HEX); - Serial.print(" || "); + Serial.print(F(" || ")); Serial.print(alternatevalue, HEX); - Serial.print(" != "); + Serial.print(F(" != ")); Serial.println(b, HEX); } +#endif return retval; } @@ -215,55 +217,58 @@ uint8_t Response_Packet::GetLowByte(uint16_t w) #ifndef __GNUC__ #pragma region -= Data_Packet =- #endif //__GNUC__ -Data_Packet::Data_Packet(uint8_t* buffer, bool UseSerialDebug) +Data_Packet::Data_Packet(uint8_t* buffer) { - if (UseSerialDebug) - { - CheckParsing(buffer[0], DATA_START_CODE_1, DATA_START_CODE_1, "DATA_START_CODE_1", UseSerialDebug); - CheckParsing(buffer[1], DATA_START_CODE_2, DATA_START_CODE_2, "DATA_START_CODE_2", UseSerialDebug); - CheckParsing(buffer[2], DATA_DEVICE_ID_1, DATA_DEVICE_ID_1, "DATA_DEVICE_ID_1", UseSerialDebug); - CheckParsing(buffer[3], DATA_DEVICE_ID_2, DATA_DEVICE_ID_2, "DATA_DEVICE_ID_2", UseSerialDebug); - - this->checksum = CalculateChecksum(buffer, 4); - } +#if FPS_DEBUG + CheckParsing(buffer[0], DATA_START_CODE_1, DATA_START_CODE_1, F("DATA_START_CODE_1")); + CheckParsing(buffer[1], DATA_START_CODE_2, DATA_START_CODE_2, F("DATA_START_CODE_2")); + CheckParsing(buffer[2], DATA_DEVICE_ID_1, DATA_DEVICE_ID_1, F("DATA_DEVICE_ID_1")); + CheckParsing(buffer[3], DATA_DEVICE_ID_2, DATA_DEVICE_ID_2, F("DATA_DEVICE_ID_2")); + + this->checksum = CalculateChecksum(buffer, 4); +#endif } -// Get a data packet (128 bytes), calculate checksum and send it to serial -void Data_Packet::GetData(uint8_t buffer[], uint16_t length, bool UseSerialDebug) +// Get a data packet, calculate checksum and send it to serial +void Data_Packet::GetData(uint8_t buffer[], uint16_t length) { for(uint16_t i = 0; ichecksum = CalculateChecksum(buffer, 128); +#if FPS_DEBUG + this->checksum = CalculateChecksum(buffer, length); +#endif } -// Get the last data packet (<=128 bytes), calculate checksum, validate checksum received and send it to serial -void Data_Packet::GetLastData(uint8_t buffer[], uint16_t length, bool UseSerialDebug) +// Get the last data packet, calculate checksum, validate checksum received and send it to serial +void Data_Packet::GetLastData(uint8_t buffer[], uint16_t length) { for(uint16_t i = 0; ichecksum = CalculateChecksum(buffer, length-2); - uint8_t checksum_low = GetLowByte(this->checksum); - uint8_t checksum_high = GetHighByte(this->checksum); - CheckParsing(buffer[length-2], checksum_low, checksum_low, "Checksum_LOW", UseSerialDebug); - CheckParsing(buffer[length-1], checksum_high, checksum_high, "Checksum_HIGH", UseSerialDebug); - } + +#if FPS_DEBUG + this->checksum = CalculateChecksum(buffer, length-2); + uint8_t checksum_low = GetLowByte(this->checksum); + uint8_t checksum_high = GetHighByte(this->checksum); + CheckParsing(buffer[length-2], checksum_low, checksum_low, F("Checksum_LOW")); + CheckParsing(buffer[length-1], checksum_high, checksum_high, F("Checksum_HIGH")); +#endif } // checks to see if the byte is the proper value, and logs it to the serial channel if not -bool Data_Packet::CheckParsing(uint8_t b, uint8_t propervalue, uint8_t alternatevalue, const char* varname, bool UseSerialDebug) +bool Data_Packet::CheckParsing(uint8_t b, uint8_t propervalue, uint8_t alternatevalue, const String varname) { bool retval = (b != propervalue) && (b != alternatevalue); - if ((UseSerialDebug) && (retval)) +#if FPS_DEBUG + if(retval) { - Serial.print("\nData_Packet parsing error "); + Serial.print(F("\nData_Packet parsing error ")); Serial.print(varname); - Serial.print(" "); + Serial.print(F(" ")); Serial.print(propervalue, HEX); - Serial.print(" || "); + Serial.print(F(" || ")); Serial.print(alternatevalue, HEX); - Serial.print(" != "); + Serial.print(F(" != ")); Serial.println(b, HEX); } +#endif return retval; } @@ -308,7 +313,6 @@ FPS_GT511C3::FPS_GT511C3(uint8_t rx, uint8_t tx, uint32_t baud) { pin_RX = rx; pin_TX = tx; - this->UseSerialDebug = false; this->Started = false; desiredBaud = baud; }; @@ -330,7 +334,9 @@ FPS_GT511C3::~FPS_GT511C3() bool FPS_GT511C3::Open() { if (!Started) Start(); - if (UseSerialDebug) Serial.println("FPS - Open"); +#if FPS_DEBUG + Serial.println(F("FPS - Open")); +#endif Command_Packet* cp = new Command_Packet(); cp->Command = Command_Packet::Commands::Open; cp->Parameter[0] = 0x00; @@ -352,7 +358,9 @@ bool FPS_GT511C3::Open() // Implemented it for completeness. void FPS_GT511C3::Close() { - if (UseSerialDebug) Serial.println("FPS - Close"); +#if FPS_DEBUG + Serial.println(F("FPS - Close")); +#endif Command_Packet* cp = new Command_Packet(); cp->Command = Command_Packet::Commands::Close; cp->Parameter[0] = 0x00; @@ -376,12 +384,16 @@ bool FPS_GT511C3::SetLED(bool on) cp->Command = Command_Packet::Commands::CmosLed; if (on) { - if (UseSerialDebug) Serial.println("FPS - LED on"); +#if FPS_DEBUG + Serial.println(F("FPS - LED on")); +#endif cp->Parameter[0] = 0x01; } else { - if (UseSerialDebug) Serial.println("FPS - LED off"); +#if FPS_DEBUG + Serial.println(F("FPS - LED off")); +#endif cp->Parameter[0] = 0x00; } cp->Parameter[1] = 0x00; @@ -406,7 +418,9 @@ bool FPS_GT511C3::ChangeBaudRate(uint32_t baud) { if ((baud == 9600) || (baud == 19200) || (baud == 38400) || (baud == 57600) || (baud == 115200)) { - if (UseSerialDebug) Serial.println("FPS - ChangeBaudRate"); +#if FPS_DEBUG + Serial.println(F("FPS - ChangeBaudRate")); +#endif Command_Packet* cp = new Command_Packet(); cp->Command = Command_Packet::Commands::ChangeBaudRate; cp->ParameterFrom(baud); @@ -427,7 +441,9 @@ bool FPS_GT511C3::ChangeBaudRate(uint32_t baud) // Return: The total number of enrolled fingerprints uint16_t FPS_GT511C3::GetEnrollCount() { - if (UseSerialDebug) Serial.println("FPS - GetEnrolledCount"); +#if FPS_DEBUG + Serial.println(F("FPS - GetEnrolledCount")); +#endif Command_Packet* cp = new Command_Packet(); cp->Command = Command_Packet::Commands::GetEnrollCount; cp->Parameter[0] = 0x00; @@ -450,7 +466,9 @@ uint16_t FPS_GT511C3::GetEnrollCount() // Return: True if the ID number is enrolled, false if not bool FPS_GT511C3::CheckEnrolled(uint16_t id) { - if (UseSerialDebug) Serial.println("FPS - CheckEnrolled"); +#if FPS_DEBUG + Serial.println(F("FPS - CheckEnrolled")); +#endif Command_Packet* cp = new Command_Packet(); cp->Command = Command_Packet::Commands::CheckEnrolled; cp->ParameterFrom(id); @@ -475,7 +493,9 @@ bool FPS_GT511C3::CheckEnrolled(uint16_t id) // 3 - Position(ID) is already used uint8_t FPS_GT511C3::EnrollStart(uint16_t id) { - if (UseSerialDebug) Serial.println("FPS - EnrollStart"); +#if FPS_DEBUG + Serial.println(F("FPS - EnrollStart")); +#endif Command_Packet* cp = new Command_Packet(); cp->Command = Command_Packet::Commands::EnrollStart; cp->ParameterFrom(id); @@ -503,7 +523,9 @@ uint8_t FPS_GT511C3::EnrollStart(uint16_t id) // 3 - ID in use uint8_t FPS_GT511C3::Enroll1() { - if (UseSerialDebug) Serial.println("FPS - Enroll1"); +#if FPS_DEBUG + Serial.println(F("FPS - Enroll1")); +#endif Command_Packet* cp = new Command_Packet(); cp->Command = Command_Packet::Commands::Enroll1; uint8_t* packetbytes = cp->GetPacketBytes(); @@ -532,7 +554,9 @@ uint8_t FPS_GT511C3::Enroll1() // 3 - ID in use uint8_t FPS_GT511C3::Enroll2() { - if (UseSerialDebug) Serial.println("FPS - Enroll2"); +#if FPS_DEBUG + Serial.println(F("FPS - Enroll2")); +#endif Command_Packet* cp = new Command_Packet(); cp->Command = Command_Packet::Commands::Enroll2; byte* packetbytes = cp->GetPacketBytes(); @@ -562,7 +586,9 @@ uint8_t FPS_GT511C3::Enroll2() // 3 - ID in use uint8_t FPS_GT511C3::Enroll3() { - if (UseSerialDebug) Serial.println("FPS - Enroll3"); +#if FPS_DEBUG + Serial.println(F("FPS - Enroll3")); +#endif Command_Packet* cp = new Command_Packet(); cp->Command = Command_Packet::Commands::Enroll3; byte* packetbytes = cp->GetPacketBytes(); @@ -587,7 +613,9 @@ uint8_t FPS_GT511C3::Enroll3() // Return: true if finger pressed, false if not bool FPS_GT511C3::IsPressFinger() { - if (UseSerialDebug) Serial.println("FPS - IsPressFinger"); +#if FPS_DEBUG + Serial.println(F("FPS - IsPressFinger")); +#endif Command_Packet* cp = new Command_Packet(); cp->Command = Command_Packet::Commands::IsPressFinger; uint8_t* packetbytes = cp->GetPacketBytes(); @@ -607,7 +635,9 @@ bool FPS_GT511C3::IsPressFinger() // Returns: true if successful, false if position invalid bool FPS_GT511C3::DeleteID(uint16_t id) { - if (UseSerialDebug) Serial.println("FPS - DeleteID"); +#if FPS_DEBUG + Serial.println(F("FPS - DeleteID")); +#endif Command_Packet* cp = new Command_Packet(); cp->Command = Command_Packet::Commands::DeleteID; cp->ParameterFrom(id); @@ -625,7 +655,9 @@ bool FPS_GT511C3::DeleteID(uint16_t id) // Returns: true if successful, false if db is empty bool FPS_GT511C3::DeleteAll() { - if (UseSerialDebug) Serial.println("FPS - DeleteAll"); +#if FPS_DEBUG + Serial.println(F("FPS - DeleteAll")); +#endif Command_Packet* cp = new Command_Packet(); cp->Command = Command_Packet::Commands::DeleteAll; uint8_t* packetbytes = cp->GetPacketBytes(); @@ -648,7 +680,9 @@ bool FPS_GT511C3::DeleteAll() // 3 - Verified FALSE (not the correct finger) uint8_t FPS_GT511C3::Verify1_1(uint16_t id) { - if (UseSerialDebug) Serial.println("FPS - Verify1_1"); +#if FPS_DEBUG + Serial.println(F("FPS - Verify1_1")); +#endif Command_Packet* cp = new Command_Packet(); cp->Command = Command_Packet::Commands::Verify1_1; cp->ParameterFrom(id); @@ -679,7 +713,9 @@ uint8_t FPS_GT511C3::Verify1_1(uint16_t id) // 200, if using GT-521F32/GT-511C3 uint16_t FPS_GT511C3::Identify1_N() { - if (UseSerialDebug) Serial.println("FPS - Identify1_N"); +#if FPS_DEBUG + Serial.println(F("FPS - Identify1_N")); +#endif Command_Packet* cp = new Command_Packet(); cp->Command = Command_Packet::Commands::Identify1_N; uint8_t* packetbytes = cp->GetPacketBytes(); @@ -701,7 +737,9 @@ uint16_t FPS_GT511C3::Identify1_N() // Returns: True if ok, false if no finger pressed bool FPS_GT511C3::CaptureFinger(bool highquality) { - if (UseSerialDebug) Serial.println("FPS - CaptureFinger"); +#if FPS_DEBUG + Serial.println(F("FPS - CaptureFinger")); +#endif Command_Packet* cp = new Command_Packet(); cp->Command = Command_Packet::Commands::CaptureFinger; if (highquality) @@ -733,7 +771,9 @@ bool FPS_GT511C3::CaptureFinger(bool highquality) // Parameter: true to ignore the documentation and get valid image data. bool FPS_GT511C3::GetImage(bool patched) { - if (UseSerialDebug) Serial.println("FPS - GetImage"); +#if FPS_DEBUG + Serial.println(F("FPS - GetImage")); +#endif Command_Packet* cp = new Command_Packet(); cp->Command = Command_Packet::Commands::GetImage; uint8_t* packetbytes = cp->GetPacketBytes(); @@ -775,7 +815,9 @@ bool FPS_GT511C3::GetImage(bool patched) // Also, avoid using UseSerialDebug for this task, since it's easier to overflow. bool FPS_GT511C3::GetRawImage() { - if (UseSerialDebug) Serial.println("FPS - GetRawImage"); +#if FPS_DEBUG + Serial.println(F("FPS - GetRawImage")); +#endif Command_Packet* cp = new Command_Packet(); cp->Command = Command_Packet::Commands::GetRawImage; uint8_t* packetbytes = cp->GetPacketBytes(); @@ -797,7 +839,9 @@ bool FPS_GT511C3::GetRawImage() // 2 - ID not used (no template to download uint8_t FPS_GT511C3::GetTemplate(uint16_t id) { - if (UseSerialDebug) Serial.println("FPS - GetTemplate"); +#if FPS_DEBUG + Serial.println(F("FPS - GetTemplate")); +#endif Command_Packet* cp = new Command_Packet(); cp->Command = Command_Packet::Commands::GetTemplate; cp->ParameterFrom(id); @@ -819,6 +863,39 @@ uint8_t FPS_GT511C3::GetTemplate(uint16_t id) } } +// Gets a template from the fps (498 bytes + 2 bytes checksum) and store it in an array +// Parameter: 0-199 ID number, array pointer to store the data +// Returns: +// 0 - ACK Download starting +// 1 - Invalid position +// 2 - ID not used (no template to download +// 3 - Data download failed (Serial overflow) +uint8_t FPS_GT511C3::GetTemplate(uint16_t id, uint8_t data[]) +{ +#if FPS_DEBUG + Serial.println(F("FPS - GetTemplate")); +#endif + Command_Packet* cp = new Command_Packet(); + cp->Command = Command_Packet::Commands::GetTemplate; + cp->ParameterFrom(id); + uint8_t* packetbytes = cp->GetPacketBytes(); + delete cp; + SendCommand(packetbytes, 12); + delete packetbytes; + Response_Packet* rp = GetResponse(); + if(rp->ACK) + { + delete rp; + if (ReturnData(498+6, data)) return 0; + else return 3; + } else + { + uint32_t retval = rp->FromParameter(); + delete rp; + return retval; + } +} + // Uploads a template to the fps // Parameter: the template (498 bytes) // Parameter: the ID number to upload @@ -832,7 +909,9 @@ uint8_t FPS_GT511C3::GetTemplate(uint16_t id) // 4 - Device error uint16_t FPS_GT511C3::SetTemplate(byte* tmplt, uint16_t id, bool duplicateCheck) { - if (UseSerialDebug) Serial.println("FPS - SetTemplate"); +#if FPS_DEBUG + Serial.println(F("FPS - SetTemplate")); +#endif Command_Packet* cp = new Command_Packet(); cp->Command = Command_Packet::Commands::SetTemplate; cp->ParameterFrom(0xFFFF0000 * !duplicateCheck + id); // Will set the HIWORD if duplicateCheck = false @@ -914,12 +993,12 @@ void FPS_GT511C3::Start() uint32_t BaudRates[5] = {9600, 19200, 38400, 57600, 115200}; for(uint8_t i = 0; i<5; i++) // Trying to find FPS baud rate { - if(UseSerialDebug) - { - Serial.print("Establishing connection with FPS at baud rate: "); - Serial.print(BaudRates[i]); - Serial.println(); - } +#if FPS_DEBUG + Serial.print(F("Establishing connection with FPS at baud rate: ")); + Serial.print(BaudRates[i]); + Serial.println(); +#endif + _serial.begin(BaudRates[i]); _serial.listen(); SendCommand(packetbytes, 12); @@ -957,47 +1036,43 @@ void FPS_GT511C3::Start() while (_serial.available() == false) delay(10); resp[i]= (uint8_t) _serial.read(); } - if (UseSerialDebug) - { - Response_Packet* rp = new Response_Packet(resp, UseSerialDebug); - Serial.print("FPS - RECV: "); - SendToSerial(rp->RawBytes, 12); - Serial.println(); - Serial.println(); - delete rp; - } +#if FPS_DEBUG + Response_Packet* rp = new Response_Packet(resp); + Serial.print("FPS - RECV: "); + SendToSerial(rp->RawBytes, 12); + Serial.println(); + Serial.println(); + delete rp; +#endif actualBaud = BaudRates[i]; break; } } - if(UseSerialDebug) - { - Serial.print("Connection established succesfully. FPS baud rate was: "); - Serial.print(actualBaud); - Serial.println(); - Serial.println(); - } +#if FPS_DEBUG + Serial.print(F("Connection established succesfully. FPS baud rate was: ")); + Serial.print(actualBaud); + Serial.println(); + Serial.println(); +#endif if (actualBaud == 0) while(true) { - if(UseSerialDebug) - { - Serial.print("EXCEPTION: FPS didn't answer to communications. Code execution stopped."); - Serial.println(); - } +#if FPS_DEBUG + Serial.print(F("EXCEPTION: FPS didn't answer to communications. Code execution stopped.")); + Serial.println(); +#endif delay(1000); // Something went terribly wrong with the FPS, and you aren't allowed to leave } if (actualBaud != baud) { - if(UseSerialDebug) - { - Serial.print("Undesired baud rate. Changing baud rate to: "); - Serial.print(baud); - Serial.println(); - Serial.println(); - } +#if FPS_DEBUG + Serial.print(F("Undesired baud rate. Changing baud rate to: ")); + Serial.print(baud); + Serial.println(); + Serial.println(); +#endif ChangeBaudRate(baud); } Started = true; @@ -1007,12 +1082,11 @@ void FPS_GT511C3::Start() void FPS_GT511C3::SendCommand(uint8_t cmd[], uint16_t length) { _serial.write(cmd, length); - if (UseSerialDebug) - { - Serial.print("FPS - SEND: "); - SendToSerial(cmd, length); - Serial.println(); - } +#if FPS_DEBUG + Serial.print(F("FPS - SEND: ")); + SendToSerial(cmd, length); + Serial.println(); +#endif }; // Gets the response to the command from the software serial channel (and waits for it) @@ -1045,14 +1119,13 @@ Response_Packet* FPS_GT511C3::GetResponse() resp[i]= (uint8_t) _serial.read(); } - Response_Packet* rp = new Response_Packet(resp, UseSerialDebug); - if (UseSerialDebug) - { - Serial.print("FPS - RECV: "); - SendToSerial(rp->RawBytes, 12); - Serial.println(); - Serial.println(); - } + Response_Packet* rp = new Response_Packet(resp); +#if FPS_DEBUG + Serial.print("FPS - RECV: "); + SendToSerial(rp->RawBytes, 12); + Serial.println(); + Serial.println(); +#endif return rp; }; @@ -1086,41 +1159,42 @@ void FPS_GT511C3::GetData(uint16_t length) while (_serial.available() == false) delay(10); firstdata[i]= (uint8_t) _serial.read(); } - Data_Packet dp(firstdata, UseSerialDebug); + Data_Packet dp(firstdata); - uint16_t numberPacketsNeeded = (length-4) / 128; - bool smallLastPacket = false; - uint8_t lastPacketSize = (length-4) % 128; - if(lastPacketSize != 0) - { - numberPacketsNeeded++; - smallLastPacket = true; + uint16_t numberPacketsNeeded = (length-4) / 64; + uint8_t lastPacketSize = (length-4) % 64; + if(lastPacketSize != 0) numberPacketsNeeded++; + else { + // Last packet requires special treatment, so you don't want it to pass over the main loop + numberPacketsNeeded--; + lastPacketSize = 64; } - uint8_t data[128]; + uint8_t data[64]; for (uint16_t packetCount=1; packetCount < numberPacketsNeeded; packetCount++) { - for (uint8_t i=0; i < 128; i++) + for (uint8_t i=0; i < 64; i++) { while (_serial.available() == false) delay(1); if(_serial.overflow()) { - if(UseSerialDebug) - { - Serial.println("Overflow! Data download stopped"); - Serial.println("Cleaning serial buffer..."); - } +#if FPS_DEBUG + Serial.println(F("Overflow! Data download stopped")); + Serial.println(F("Cleaning serial buffer...")); +#endif for (uint16_t j = 0; j Date: Wed, 11 Apr 2018 22:59:45 +0200 Subject: [PATCH 22/27] Updated library properties for pull request. --- README.md | 10 ---------- library.json | 2 +- library.properties | 4 ++-- 3 files changed, 3 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index 95a23e8..760874d 100644 --- a/README.md +++ b/README.md @@ -16,16 +16,6 @@ Fingerprint Scanner-TTL This is a great fingerprint module from ADH-Tech that communicates over 3.3V TTL Serial so you can easily embed it into your next project. This repository contains Arduino example code to work with it. This code has been tested with GT-521F32, GT-521F52, GT-511C3, and GT-511C1R. -Fork purpose -==================================== -This fork implements a few of the remaining commands needed to extract the fingerprint DB contained in the original device, allowing to implement a server-based IoT service. - -Commands to implement: -* bool GetImage() -* bool GetRawImage() -* int GetTemplate(int) -* int SetTemplate(byte*, int, bool) - Repository Contents ------------------- * **/examples** - Example code to interface with the sensor. diff --git a/library.json b/library.json index 4f8b609..68af6fa 100644 --- a/library.json +++ b/library.json @@ -5,7 +5,7 @@ "repository": { "type": "git", - "url": "https://github.com/Fasgort/Fingerprint_Scanner-TTL.git" + "url": "https://github.com/sparkfun/Fingerprint_Scanner-TTL.git" }, "version": "1.2.2", "frameworks": "arduino", diff --git a/library.properties b/library.properties index fa95a4d..62bc7dd 100644 --- a/library.properties +++ b/library.properties @@ -1,9 +1,9 @@ name=Fingerprint Scanner TTL version=1.2.2 author=Josh Hawley, modified by David López Chica -maintainer=David López Chica +maintainer=SparkFun Electronics sentence=Arduino examples for ADH-Tech's Fingerprint Scanners. paragraph=This is a great fingerprint module from ADH-Tech that communicates over 3.3V TTL Serial so you can easily embed it into your next project. This repository contains Arduino example code to work with it. This code has been tested with GT-521F32, GT-521F52, GT-511C3, and GT-511C1R. category=Sensors -url=https://github.com/Fasgort/Fingerprint_Scanner-TTL +url=https://github.com/sparkfun/Fingerprint_Scanner-TTL architectures=* From 7897efbc1a31b128a6f01724708ce5893f921a6b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20L=C3=B3pez=20Chica?= Date: Sun, 9 Dec 2018 21:12:53 +0100 Subject: [PATCH 23/27] Fixed SetTemplate method and cleaned up a bit the code. --- src/FPS_GT511C3.cpp | 77 ++++++++++++++++++++++++++++++++++++++++----- src/FPS_GT511C3.h | 13 ++++---- 2 files changed, 76 insertions(+), 14 deletions(-) diff --git a/src/FPS_GT511C3.cpp b/src/FPS_GT511C3.cpp index 4dc2aec..3e60348 100644 --- a/src/FPS_GT511C3.cpp +++ b/src/FPS_GT511C3.cpp @@ -90,7 +90,7 @@ Command_Packet::Command_Packet() #pragma region -= Response_Packet Definitions =- #endif //__GNUC__ // creates and parses a response packet from the finger print scanner -Response_Packet::Response_Packet(uint8_t* buffer) +Response_Packet::Response_Packet(uint8_t buffer[]) { CheckParsing(buffer[0], RESPONSE_START_CODE_1, RESPONSE_START_CODE_1, F("RESPONSE_START_CODE_1")); CheckParsing(buffer[1], RESPONSE_START_CODE_2, RESPONSE_START_CODE_2, F("RESPONSE_START_CODE_2")); @@ -189,7 +189,7 @@ bool Response_Packet::CheckParsing(uint8_t b, uint8_t propervalue, uint8_t alter } // calculates the checksum from the bytes in the packet -uint16_t Response_Packet::CalculateChecksum(uint8_t* buffer, uint16_t length) +uint16_t Response_Packet::CalculateChecksum(uint8_t buffer[], uint16_t length) { uint16_t checksum = 0; for (uint16_t i=0; ichecksum)); + Serial.print(tmp); + } + { + if (first) first=false; else Serial.print(" "); + char tmp[16]; + sprintf(tmp, "%.2X", GetHighByte(this->checksum)); + Serial.print(tmp); + } + Serial.print("\""); + Serial.println(); +#endif + + // Calculate checksum + this->checksum = CalculateChecksum(data_code, 4); + this->checksum = CalculateChecksum(buffer, length); + + // Send everything to the finger print scanner + _serial.write(data_code, 4); + _serial.write(buffer, length); + _serial.write(GetLowByte(this->checksum)); + _serial.write(GetHighByte(this->checksum)); + + // clean up + delete data_code; + +} +// creates and parses a data packet from the finger print scanner +Data_Packet::Data_Packet(uint8_t buffer[]) { #if FPS_DEBUG CheckParsing(buffer[0], DATA_START_CODE_1, DATA_START_CODE_1, F("DATA_START_CODE_1")); @@ -273,7 +334,7 @@ bool Data_Packet::CheckParsing(uint8_t b, uint8_t propervalue, uint8_t alternate } // calculates the checksum from the bytes in the packet -uint16_t Data_Packet::CalculateChecksum(uint8_t* buffer, uint16_t length) +uint16_t Data_Packet::CalculateChecksum(uint8_t buffer[], uint16_t length) { uint16_t checksum = this->checksum; for (uint16_t i=0; iACK) { @@ -954,7 +1015,7 @@ uint16_t FPS_GT511C3::SetTemplate(byte* tmplt, uint16_t id, bool duplicateCheck) #endif //__GNUC__ #ifndef __GNUC__ -#pragma region -= Not imlemented commands =- +#pragma region -= Not implemented commands =- #endif //__GNUC__ // Commands that are not implemented (and why) // VerifyTemplate1_1 - Couldn't find a good reason to implement this on an arduino @@ -1266,7 +1327,7 @@ bool FPS_GT511C3::ReturnData(uint16_t length, uint8_t data[]) // sends the byte array to the serial debugger in our hex format EX: "00 AF FF 10 00 13" void FPS_GT511C3::SendToSerial(uint8_t data[], uint16_t length) { - boolean first=true; + bool first=true; Serial.print("\""); for(uint16_t i=0; i Date: Sun, 9 Dec 2018 23:35:30 +0100 Subject: [PATCH 24/27] Fixed an impossible value for an undefined error in SetTemplate() method (thanks @JoshHawley for finding this one). (cherry picked from commit aa069257cc8ab6ab59815aecda32bee709d42c47) --- src/FPS_GT511C3.cpp | 4 ++-- src/FPS_GT511C3.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/FPS_GT511C3.cpp b/src/FPS_GT511C3.cpp index 3e60348..3528e57 100644 --- a/src/FPS_GT511C3.cpp +++ b/src/FPS_GT511C3.cpp @@ -962,12 +962,12 @@ uint8_t FPS_GT511C3::GetTemplate(uint16_t id, uint8_t data[]) // Parameter: the ID number to upload // Parameter: Check for duplicate fingerprints already on fps // Returns: -// -1 - Undefined error (shouldn't ever happen) // 0 - Uploaded ok (no duplicate if enabled) // 1 - ID duplicated // 2 - Invalid position // 3 - Communications error // 4 - Device error +// 5 - Undefined error (shouldn't ever happen) uint16_t FPS_GT511C3::SetTemplate(uint8_t tmplt[], uint16_t id, bool duplicateCheck) { #if FPS_DEBUG @@ -1006,7 +1006,7 @@ uint16_t FPS_GT511C3::SetTemplate(uint8_t tmplt[], uint16_t id, bool duplicateCh delete rp; if (error == Response_Packet::ErrorCodes::NACK_COMM_ERR) return 3; if (error == Response_Packet::ErrorCodes::NACK_DEV_ERR) return 4; - return -1; // Undefined error + return 5; // Undefined error } } } diff --git a/src/FPS_GT511C3.h b/src/FPS_GT511C3.h index 1d1fc45..c94989f 100644 --- a/src/FPS_GT511C3.h +++ b/src/FPS_GT511C3.h @@ -336,12 +336,12 @@ class FPS_GT511C3 // Parameter: the ID number to upload // Parameter: Check for duplicate fingerprints already on fps // Returns: - // -1 - Undefined error (shouldn't ever happen) // 0 - Uploaded ok (no duplicate if enabled) // 1 - ID duplicated // 2 - Invalid position // 3 - Communications error // 4 - Device error + // 5 - Undefined error (shouldn't ever happen) uint16_t SetTemplate(uint8_t tmplt[], uint16_t id, bool duplicateCheck); #ifndef __GNUC__ #pragma endregion From 032ed6d38a50271110d93fa08cf4ae98ada9e245 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20L=C3=B3pez=20Chica?= Date: Fri, 21 Dec 2018 04:32:39 +0100 Subject: [PATCH 25/27] HOTFIX: Fixed memory leak in SetTemplate() method. (cherry picked from commit 2303b5388287a7cef68a629b7ca069b266027435) --- src/FPS_GT511C3.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/FPS_GT511C3.cpp b/src/FPS_GT511C3.cpp index 3528e57..d3cdf70 100644 --- a/src/FPS_GT511C3.cpp +++ b/src/FPS_GT511C3.cpp @@ -988,6 +988,7 @@ uint16_t FPS_GT511C3::SetTemplate(uint8_t tmplt[], uint16_t id, bool duplicateCh } else { Data_Packet dp(tmplt, 498, _serial); // This makes the data packet and sends it immediately + delete rp; rp = GetResponse(); if (rp->ACK) { From d9ac1bbb0c48bbf63e7db9a13675f44b31344a76 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20L=C3=B3pez=20Chica?= Date: Fri, 22 Feb 2019 21:29:51 +0100 Subject: [PATCH 26/27] HOTFIX: Fixed bug in the enroll process, where any error in the EnrollX() method would be ignored in Arduino code. --- examples/FPS_Enroll/FPS_Enroll.ino | 18 ++++++++++++++---- src/FPS_GT511C3.cpp | 12 ++++++------ 2 files changed, 20 insertions(+), 10 deletions(-) diff --git a/examples/FPS_Enroll/FPS_Enroll.ino b/examples/FPS_Enroll/FPS_Enroll.ino index 5e34960..d39586d 100644 --- a/examples/FPS_Enroll/FPS_Enroll.ino +++ b/examples/FPS_Enroll/FPS_Enroll.ino @@ -101,20 +101,20 @@ void Enroll() if (bret != false) { Serial.println("Remove finger"); - fps.Enroll1(); + iret = fps.Enroll1(); while(fps.IsPressFinger() == true) delay(100); Serial.println("Press same finger again"); while(fps.IsPressFinger() == false) delay(100); bret = fps.CaptureFinger(true); - if (bret != false) + if (bret != false && !iret) { Serial.println("Remove finger"); - fps.Enroll2(); + iret = fps.Enroll2(); while(fps.IsPressFinger() == true) delay(100); Serial.println("Press same finger yet again"); while(fps.IsPressFinger() == false) delay(100); bret = fps.CaptureFinger(true); - if (bret != false) + if (bret != false && !iret) { Serial.println("Remove finger"); iret = fps.Enroll3(); @@ -128,8 +128,18 @@ void Enroll() Serial.println(iret); } } + else if (iret) + { + Serial.print("Enrolling Failed with error code:"); + Serial.println(iret); + } else Serial.println("Failed to capture third finger"); } + else if (iret) + { + Serial.print("Enrolling Failed with error code:"); + Serial.println(iret); + } else Serial.println("Failed to capture second finger"); } else Serial.println("Failed to capture first finger"); diff --git a/src/FPS_GT511C3.cpp b/src/FPS_GT511C3.cpp index d3cdf70..08e21b9 100644 --- a/src/FPS_GT511C3.cpp +++ b/src/FPS_GT511C3.cpp @@ -602,9 +602,9 @@ uint8_t FPS_GT511C3::Enroll1() { if (rp->Error == Response_Packet::ErrorCodes::NACK_ENROLL_FAILED) retval = 1; if (rp->Error == Response_Packet::ErrorCodes::NACK_BAD_FINGER) retval = 2; - } + } else retval = 0; delete rp; - if (rp->ACK) return 0; else return retval; + return retval; } // Gets the Second scan of an enrollment @@ -633,9 +633,9 @@ uint8_t FPS_GT511C3::Enroll2() { if (rp->Error == Response_Packet::ErrorCodes::NACK_ENROLL_FAILED) retval = 1; if (rp->Error == Response_Packet::ErrorCodes::NACK_BAD_FINGER) retval = 2; - } + } else retval = 0; delete rp; - if (rp->ACK) return 0; else return retval; + return retval; } // Gets the Third scan of an enrollment @@ -665,9 +665,9 @@ uint8_t FPS_GT511C3::Enroll3() { if (rp->Error == Response_Packet::ErrorCodes::NACK_ENROLL_FAILED) retval = 1; if (rp->Error == Response_Packet::ErrorCodes::NACK_BAD_FINGER) retval = 2; - } + } else retval = 0; delete rp; - if (rp->ACK) return 0; else return retval; + return retval; } // Checks to see if a finger is pressed on the FPS From 9dfcc0895103a97cef672df3d96a272579a3ec32 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20L=C3=B3pez=20Chica?= Date: Wed, 10 Jul 2019 01:15:08 +0200 Subject: [PATCH 27/27] Fixed memory issues. --- src/FPS_GT511C3.cpp | 3 ++- src/FPS_GT511C3.h | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/FPS_GT511C3.cpp b/src/FPS_GT511C3.cpp index 08e21b9..b637480 100644 --- a/src/FPS_GT511C3.cpp +++ b/src/FPS_GT511C3.cpp @@ -218,7 +218,7 @@ uint8_t Response_Packet::GetLowByte(uint16_t w) #pragma region -= Data_Packet =- #endif //__GNUC__ // creates a data packet and send it to the finger print scanner -Data_Packet::Data_Packet(uint8_t buffer[], uint16_t length, SoftwareSerial _serial) +Data_Packet::Data_Packet(uint8_t buffer[], uint16_t length, SoftwareSerial& _serial) { uint8_t* data_code= new uint8_t[4]; @@ -1110,6 +1110,7 @@ void FPS_GT511C3::Start() break; } } + delete packetbytes; #if FPS_DEBUG Serial.print(F("Connection established succesfully. FPS baud rate was: ")); diff --git a/src/FPS_GT511C3.h b/src/FPS_GT511C3.h index c94989f..f0d3f4f 100644 --- a/src/FPS_GT511C3.h +++ b/src/FPS_GT511C3.h @@ -156,7 +156,7 @@ class Response_Packet class Data_Packet { public: - Data_Packet(uint8_t buffer[], uint16_t length, SoftwareSerial _serial); + Data_Packet(uint8_t buffer[], uint16_t length, SoftwareSerial& _serial); Data_Packet(uint8_t buffer[]); uint16_t checksum = 0; static const uint8_t DATA_START_CODE_1 = 0x5A; // Static byte to mark the beginning of a data packet - never changes