I am currently working on your GT521F52 Optical Fingerprint sensor,
I have reached out to the forum regarding the coding part, my task is to extract the saved fingerprint data in the form of a template and store it in the sql database and again set the extracted template in a different GT521F52 optical fingerprint sensor .
I am not able to find a suitable library for my above tasks.
Currently I am directly using the commands in the code.
code:
#include <AltSoftSerial.h>
#include <SoftwareSerial.h>
#include <SPI.h>
// Fingerprint Sensor on AltSoftSerial
AltSoftSerial mySerial; // RX = 8, TX = 9
// ESP on SoftwareSerial
SoftwareSerial espSerial(10, 11); // RX = 10, TX = 11
// GT-521F52 Command Constants
const byte CMD_HEADER[2] = {0x55, 0xAA};
const byte CMD_DEVICE_ID[2] = {0x01, 0x00};
const uint8_t CMD_OPEN = 0x01;
const uint8_t CMD_LED_ON = 0x12;
const uint8_t CMD_ENROLL_START = 0x22;
const uint8_t CMD_ENROLL_1 = 0x23;
const uint8_t CMD_ENROLL_2 = 0x24;
const uint8_t CMD_ENROLL_3 = 0x25;
const uint8_t CMD_CAPTURE = 0x60;
const uint8_t CMD_IDENTIFY = 0x51;
const uint8_t CMD_DELETE_ID = 0x40;
const uint8_t CMD_GET_TEMPLATE = 0x70;
void sendCommand(uint8_t cmd, uint16_t pL = 0, uint16_t pH = 0) {
byte pkt[12];
pkt[0] = CMD_HEADER[0]; pkt[1] = CMD_HEADER[1];
pkt[2] = CMD_DEVICE_ID[0]; pkt[3] = CMD_DEVICE_ID[1];
pkt[4] = lowByte(pL); pkt[5] = highByte(pL);
pkt[6] = lowByte(pH); pkt[7] = highByte(pH);
pkt[8] = cmd; pkt[9] = 0x00;
uint16_t csum = 0; for (int i = 0; i < 10; i++) csum += pkt[i];
pkt[10] = lowByte(csum); pkt[11] = highByte(csum);
mySerial.write(pkt, 12);
}
bool readAck(byte *r) {
unsigned long t = millis();
while (mySerial.available() < 12) {
if (millis() - t > 3000) return false;
}
mySerial.readBytes(r, 12);
return (r[8] == 0x30);
}
String getInput(String prompt, unsigned long to = 20000) {
Serial.println(prompt);
unsigned long start = millis();
while (millis() - start < to) {
if (Serial.available()) {
String s = Serial.readStringUntil(‘\n’);
s.trim();
while (Serial.available()) Serial.read(); // flush extra chars
Serial.print(" You entered: "); Serial.println(s);
delay(100); // give time before next serial use
return s;
}
}
Serial.println(“ Input timeout.”);
return “”;
}
void verifyFingerprint() {
byte resp[12];
Serial.println(“ Place finger to verify using sensor…”);
// Step 1: Capture fingerprint
while (true) {
// Flush old data to avoid stale bytes
while (mySerial.available()) mySerial.read();
sendCommand(CMD_CAPTURE, 1); // high quality
if (readAck(resp)) break;
delay(300); // Give time for user to place finger
}
// Step 2: Identify fingerprint
sendCommand(CMD_IDENTIFY);
if (!readAck(resp)) {
Serial.println(“ IDENTIFY failed.”);
return;
}
// Extract matched ID
uint16_t matchedID = resp[5] << 8 | resp[4];
Serial.print(" Matched ID: ");
Serial.println(matchedID);
// Step 3: Get template of matched ID
const int SZ = 498;
const int CH = 64;
uint8_t tmpl[SZ];
sendCommand(CMD_GET_TEMPLATE, matchedID);
if (!readAck(resp)) {
Serial.println(“ CMD_GET_TEMPLATE failed”);
return;
}
// Read template data
int received = 0;
unsigned long t0 = millis();
while (received < SZ && millis() - t0 < 5000) {
if (mySerial.available()) {
tmpl[received++] = mySerial.read();
}
}
if (received != SZ) {
Serial.print(“ Only received “);
Serial.print(received);
Serial.println(” bytes before timeout.”);
return;
}
// Step 4: Send to ESP to request employee info
espSerial.print(“TEMPLATE:”);
espSerial.print(matchedID);
espSerial.println(“,FetchInfo,START”);
delay(100);
// Send in chunks
int totalChunks = (SZ + CH - 1) / CH;
char hexBuf[CH * 2 + 2];
for (int i = 0; i < totalChunks; i++) {
int offset = i * CH;
int len = min(CH, SZ - offset);
for (int j = 0; j < len; j++) {
sprintf(&hexBuf[j * 2], "%02X", tmpl[offset + j]);
}
hexBuf[len * 2] = '\0';
espSerial.print("CHUNK:");
espSerial.println(hexBuf);
espSerial.flush();
delay(50);
}
// Signal end of transfer
espSerial.println(“FETCHINFO:END”);
// Step 5: Wait for employee info
unsigned long start = millis();
while (millis() - start < 5000) {
if (espSerial.available()) {
String result = espSerial.readStringUntil(‘\n’);
result.trim();
if (result.startsWith("EMPINFO:")) {
result.remove(0, 8); // Remove "EMPINFO:"
int p1 = result.indexOf(',');
int p2 = result.indexOf(',', p1 + 1);
int p3 = result.indexOf(',', p2 + 1);
int p4 = result.indexOf(',', p3 + 1);
String id = result.substring(0, p1);
String name = result.substring(p1 + 1, p2);
String team = result.substring(p2 + 1, p3);
String desig = result.substring(p3 + 1, p4);
String fingerName = result.substring(p4 + 1);
Serial.println("🔍 Employee Match Found:");
Serial.print("Emp_ID: "); Serial.println(id);
Serial.print("Emp_Name: "); Serial.println(name);
Serial.print("Team: "); Serial.println(team);
Serial.print("Designation: "); Serial.println(desig);
Serial.print("Finger Name: "); Serial.println(fingerName);
} else {
Serial.print("⚠️ Unexpected ESP response: ");
Serial.println(result);
}
return;
}
}
Serial.println(“ No response from ESP.”);
}
void enrollFingerprint() {
String nm, tm, ds, fg;
uint16_t enrollID;
byte resp[12];
// Ask for ID
Serial.println(“Enter ID (0–199):”);
while (Serial.available() == 0);
enrollID = Serial.readStringUntil(‘\n’).toInt();
Serial.print(" You entered ID: ");
Serial.println(enrollID);
// Employee metadata
Serial.println(“Enter Name:”);
while (nm.length() == 0) nm = Serial.readStringUntil(‘\n’);
nm.trim();
Serial.println(“Enter Team:”);
while (tm.length() == 0) tm = Serial.readStringUntil(‘\n’);
tm.trim();
Serial.println(“Enter Designation:”);
while (ds.length() == 0) ds = Serial.readStringUntil(‘\n’);
ds.trim();
Serial.println(“Enter Finger Name:”);
while (fg.length() == 0) fg = Serial.readStringUntil(‘\n’);
fg.trim();
// Begin enrollment
sendCommand(CMD_ENROLL_START, enrollID);
if (!readAck(resp)) {
Serial.println(“ ENROLL_START failed”);
return;
}
for (int i = 1; i <= 3; i++) {
Serial.print(" Place finger for scan ");
Serial.println(i);
while (true) {
sendCommand(CMD_CAPTURE, 1); // best image
if (readAck(resp)) break;
delay(500);
}
sendCommand(CMD_ENROLL_1 + (i - 1));
if (!readAck(resp)) {
Serial.print("❌ ENROLL_"); Serial.print(i); Serial.println(" failed");
return;
}
Serial.println("✋ Remove finger");
delay(2000);
}
Serial.println(“ Enroll success.”);
// ================= Template Transfer ==================
espSerial.print(“TEMPLATE:”);
espSerial.print(enrollID);
espSerial.print(“,”);
espSerial.print(fg);
espSerial.println(“,START”);
Serial.println(“ TEMPLATE:START sent”);
// Request template
const int SZ = 498;
const int CH = 64;
uint8_t tmpl[SZ];
sendCommand(CMD_GET_TEMPLATE, enrollID);
if (!readAck(resp)) {
Serial.println(“ CMD_GET_TEMPLATE failed”);
return;
}
// Read template chunk-by-chunk (64 bytes)
int received = 0;
unsigned long t0 = millis();
while (received < SZ && millis() - t0 < 5000) {
if (mySerial.available()) {
tmpl[received++] = mySerial.read();
}
}
if (received != SZ) {
Serial.print(“ Only received “);
Serial.print(received);
Serial.println(” bytes before timeout.”);
return;
}
// Send 64-byte template in 8 chunks (64 x 7 + 50 bytes last)
int totalChunks = (SZ + CH - 1) / CH;
char hexBuf[CH * 2 + 2]; // +2 to safely hold optional padding + null
for (int i = 0; i < totalChunks; i++) {
int offset = i * CH;
int len = min(CH, SZ - offset);
for (int j = 0; j < len; j++) {
sprintf(&hexBuf[j * 2], "%02X", tmpl[offset + j]); // always 2-digit hex
}
int hexLen = len * 2;
hexBuf[hexLen] = '\0';
// ✅ Ensure even-length hex string (safety for unhexlify)
if (hexLen % 2 != 0) {
hexBuf[hexLen] = '0';
hexBuf[hexLen + 1] = '\0';
hexLen += 1;
}
espSerial.print("SENDTEMPLATE:");
espSerial.print(i + 1);
espSerial.print("/");
espSerial.print(totalChunks);
espSerial.print(":");
espSerial.println(hexBuf);
Serial.print("✅ Hex length: ");
Serial.println(strlen(hexBuf));
Serial.print("Hex Char: ");
Serial.println(hexBuf);
espSerial.flush(); // Wait until all data is sent
delay(100); // Give ESP time to process & forward
Serial.print("📤 Chunk ");
Serial.print(i + 1);
Serial.print("/");
Serial.println(totalChunks);
delay(50); // allow server to process
}
// Send EMPINFO
espSerial.print(“EMPINFO:”);
espSerial.print(enrollID); espSerial.print(“,”);
espSerial.print(nm); espSerial.print(“,”);
espSerial.print™; espSerial.print(“,”);
espSerial.print(ds); espSerial.print(“,”);
espSerial.println(fg);
// Confirm on Serial
Serial.println(“====== Enrolled Fingerprint ======”);
Serial.print("Emp_ID: "); Serial.println(enrollID);
Serial.print("Emp_Name: "); Serial.println(nm);
Serial.print("Team: "); Serial.println™;
Serial.print("Designation: "); Serial.println(ds);
Serial.print("Finger Name: "); Serial.println(fg);
delay(200);
// End marker
espSerial.println(“TEMPLATE:END”);
Serial.println(“ TEMPLATE:END sent”);
espSerial.flush();
delay(100);
}
void deleteFingerprint() {
byte response[12];
Serial.println();
Serial.print("Enter ID to delete: ");
while (!Serial.available()) { /* wait */ }
String s = Serial.readStringUntil(‘\n’);
s.trim();
uint16_t delID = s.toInt();
Serial.print(" Deleting ID: ");
Serial.println(delID);
sendCommand(CMD_DELETE_ID, delID);
if (readAck(response)) {
Serial.print(" Successfully deleted ID ");
Serial.println(delID);
} else {
Serial.print(“ Delete failed. ACK code: 0x”);
Serial.println(response[8], HEX);
}
}
void setup() {
Serial.begin(9600);
mySerial.begin(9600);
espSerial.begin(9600);
delay(500);
byte r[12];
sendCommand(CMD_OPEN);
if (!readAck(r)) { Serial.println(“ Sensor init failed”); while (1); }
Serial.println(“ Sensor ready”);
sendCommand(CMD_LED_ON, 1);
readAck(r);
}
void loop() {
Serial.println(“\n📋 MENU:\n1. Verify Fingerprint\n2. Enroll Fingerprint\n3. Delete Fingerprint”);
String opt = getInput(“Enter option (1/2/3):”);
opt.trim(); // Ensure it’s clean
Serial.print(“ Option received: [”);
Serial.print(opt);
Serial.println(“]”);
if (opt == “1”) verifyFingerprint();
else if (opt == “2”) enrollFingerprint();
else if (opt == “3”) deleteFingerprint();
else Serial.println(“ Option not relevant”);
delay(1000);
}