Hi,
I'm creating a Fingerprint Attendence project in ASP.NET Core Web App (MVC).
I have a R307/AS608 fingerprint sensor, an Arduino Uno.
I was thinking to extract somehow the fingerprint data, sent to PC through serial, where C# would be waiting for it, store in database.
That was for enroll process, for verifying process, I was thinking the same where C# would hold compare and match logic, but it didn't seem to go as planned.
I got it to extract templates and send to PC, but compare and match function didn't seem to work because every template came with a high confidence score which came a match.
I'm open for any idea.
Here is the sketch code:
#include <Adafruit_Fingerprint.h>
#if (defined(__AVR__) || defined(ESP8266)) && !defined(__AVR_ATmega2560__)
#include <SoftwareSerial.h>
SoftwareSerial mySerial(2, 3);
#else
#define mySerial Serial1
#endif
Adafruit_Fingerprint finger = Adafruit_Fingerprint(&mySerial);
void setup() {
Serial.begin(9600);
while (!Serial);
finger.begin(57600);
if (finger.verifyPassword()) {
Serial.println("ArduinoFingerPrintSensorReady");
} else {
Serial.println("Sensor not found");
while (1);
}
}
void loop() {
if (Serial.available()) {
char command[16];
int len = Serial.readBytesUntil('\n', command, sizeof(command)-1);
command[len] = 0;
if (strcasecmp(command, "ENROLL") == 0) enrollFingerprint();
else if (strcasecmp(command, "VERIFY") == 0) verifyFingerprint();
else Serial.println("Unknown command");
}
}
void enrollFingerprint() {
Serial.println("Starting enrollment for ID #1");
if (!captureAndConvert(1)) return;
Serial.println("Remove finger...");
delay(2000);
while (finger.getImage() != FINGERPRINT_NOFINGER);
delay(500);
Serial.println("Place same finger again...");
if (!captureAndConvert(2)) return;
if (finger.createModel() != FINGERPRINT_OK) {
Serial.println("Model creation failed");
return;
}
if (finger.storeModel(1) != FINGERPRINT_OK) {
Serial.println("Storage failed");
return;
}
sendFingerprintTemplate(1);
if (finger.deleteModel(1) != FINGERPRINT_OK) return;
}
void verifyFingerprint() {
Serial.println("Starting verification...");
// First capture (slot 1)
if (!captureAndConvert(1)) return;
// Second capture (same finger, slot 2)
Serial.print("Keep finger on sensor...");
delay(500); // Short delay to stabilize
if (!captureAndConvert(2)) return;
// Create model from both slots
if (finger.createModel() != FINGERPRINT_OK) {
Serial.println("Model creation failed");
return;
}
// Store temporarily at ID 1
if (finger.storeModel(1) != FINGERPRINT_OK) {
Serial.println("Storage failed");
return;
}
// Send the combined template
sendFingerprintTemplate(1);
// Cleanup
finger.deleteModel(1);
}
bool captureAndConvert(uint8_t slot) {
if (getFingerprintImage() != FINGERPRINT_OK) {
Serial.println("Capture failed");
return false;
}
if (finger.image2Tz(slot) != FINGERPRINT_OK) {
Serial.println("Conversion failed");
return false;
}
Serial.print(slot == 1 ? "First" : "Second");
Serial.println(" image converted");
return true;
}
uint8_t getFingerprintImage() {
uint8_t p;
while ((p = finger.getImage()) != FINGERPRINT_OK) {
switch (p) {
case FINGERPRINT_NOFINGER: Serial.print("."); break;
case FINGERPRINT_PACKETRECIEVEERR: Serial.println("Comms error"); break;
case FINGERPRINT_IMAGEFAIL: Serial.println("Imaging error"); break;
default: Serial.print("Error: "); Serial.println(p); break;
}
delay(50);
}
Serial.println();
Serial.println("Image captured");
return p;
}
void sendFingerprintTemplate(uint16_t id) {
static uint8_t buffer[534];
if (finger.loadModel(id) != FINGERPRINT_OK) {
Serial.println("Load failed");
return;
}
if (finger.getModel() != FINGERPRINT_OK) {
Serial.println("Retrieve failed");
return;
}
Serial.print("Transferring template ");
Serial.println(id);
uint32_t start = millis();
int idx = 0;
while (idx < 534 && (millis() - start) < 20000) {
if (mySerial.available()) buffer[idx++] = mySerial.read();
}
Serial.print(idx);
Serial.println(" bytes read");
Serial.print("Template: ");
printBufferSection(buffer + 9, 256);
printBufferSection(buffer + 276, 256);
Serial.println();
}
void printBufferSection(uint8_t* data, uint16_t length) {
for (uint16_t i = 0; i < length; i++) printHex(data[i], 2);
}
void printHex(uint8_t num, uint8_t precision) {
char hex[] = "0123456789ABCDEF";
if (precision > 1) {
Serial.print(hex[(num >> 4) & 0xF]);
}
Serial.print(hex[num & 0xF]);
}