0% found this document useful (0 votes)
36 views8 pages

Arduino Fingerprint Sensor Code

This document is an Arduino sketch for interfacing with a fingerprint sensor using an ESP32 microcontroller. It includes functions for enrolling fingerprints, identifying users, and managing stored fingerprints, along with LED control for user feedback. The sketch utilizes UART communication to send and receive packets to and from the fingerprint sensor.

Uploaded by

Avdhut Punekar
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
36 views8 pages

Arduino Fingerprint Sensor Code

This document is an Arduino sketch for interfacing with a fingerprint sensor using an ESP32 microcontroller. It includes functions for enrolling fingerprints, identifying users, and managing stored fingerprints, along with LED control for user feedback. The sketch utilizes UART communication to send and receive packets to and from the fingerprint sensor.

Uploaded by

Avdhut Punekar
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd

#include <Arduino.

h> // Include Arduino core functions

HardwareSerial fingerSerial(2); // Use UART2 of ESP32 for fingerprint


sensor

// ---------------- Pin / Baud Config ----------------


#define FP_BAUD 57600 // Baud rate for fingerprint sensor
#define RX_PIN 16 // ESP32 pin connected to sensor TX
#define TX_PIN 17 // ESP32 pin connected to sensor RX
#define EXT_LED_PIN 4 // External LED pin on ESP32

int nextUserID = 1; // Start user IDs from 1 (mapped to module slots


0..199)

//PACKET HANDLING FUNCTIONS

// Send a packet to the fingerprint sensor


void sendPacket(uint8_t *content, uint16_t length) {
uint8_t packet[512]; uint16_t sum=0;

// Header: Start code = 0xEF01


packet[0]=0xEF; packet[1]=0x01;

// Module address = default 0xFFFFFFFF


packet[2]=0xFF; packet[3]=0xFF; packet[4]=0xFF; packet[5]=0xFF;

// Packet identifier = 0x01 (command packet)


packet[6]=0x01;

// Packet length = command length + 2 bytes (checksum)


uint16_t lenField=length+2;
packet[7]=lenField>>8; packet[8]=lenField&0xFF;

// Copy the actual command payload


memcpy(&packet[9],content,length);

// Calculate checksum (sum from packet[6] to end of content)


for(int i=6;i<9+length;i++) sum+=packet[i];

// Append checksum high and low bytes


packet[9+length]=sum>>8; packet[10+length]=sum&0xFF;
// Send packet to fingerprint sensor
[Link](packet,11+length);
}

// Read a packet from the fingerprint sensor with timeout


int readPacket(uint8_t*buf,int maxlen,unsigned long timeout=1000){
unsigned long t0=millis();
while(millis()-t0<timeout){
if(![Link]()){ delay(1); continue; }

// Check for header 0xEF01


if([Link]()!=0xEF) continue;
while(![Link]());
if([Link]()!=0x01) continue;

buf[0]=0xEF; buf[1]=0x01;
int idx=2;

// Read module address (4 bytes)


for(int i=0;i<4;i++){ while(![Link]());
buf[idx++]=[Link]();}

// Packet identifier
while(![Link]()); buf[idx++]=[Link]();

// Length high + low


while(![Link]()); buf[idx++]=[Link]();
while(![Link]()); buf[idx++]=[Link]();

// Read remaining payload bytes


uint16_t lenVal=((uint16_t)buf[7]<<8)|buf[8];
if(idx+lenVal>maxlen) return 0;
for(uint16_t k=0;k<lenVal;k++){ while(![Link]());
buf[idx++]=[Link]();}

return idx; // Total length of received packet


}
return 0; // Timeout
}
// Send a command and wait for ACK response
int sendCmdAndGetAck(uint8_t*cmd,uint16_t cmdLen,uint8_t*ack,int
ackMax,unsigned long timeout=1000){
while([Link]()) [Link](); // Clear buffer
sendPacket(cmd,cmdLen); // Send command
packet
return readPacket(ack,ackMax,timeout); // Wait for ACK
packet
}
// COMMAND FUNCTIONS
// Generate image from finger
void cmd_GenImg(uint8_t*out,int*len){uint8_t
c[1]={0x01};*len=sendCmdAndGetAck(c,1,out,200,800);}
// Convert image to template buffer (1 or 2)
void cmd_Img2Tz(uint8_t b,uint8_t*out,int*len){uint8_t
c[2]={0x02,b};*len=sendCmdAndGetAck(c,2,out,200,800);}
// Create model by combining buffer1 & buffer2
void cmd_RegModel(uint8_t*out,int*len){uint8_t
c[1]={0x05};*len=sendCmdAndGetAck(c,1,out,200,800);}
// Store model into library (moduleID = slot number)
void cmd_Store(uint16_t moduleID,uint8_t*out,int*len){uint8_t
c[4]={0x06,0x01,(uint8_t)(moduleID>>8),(uint8_t)moduleID};*len=sendCmdA
ndGetAck(c,4,out,200,1000);}
// Search library for a matching fingerprint
void cmd_SearchAll(uint8_t*out,int*len){uint8_t
c[6]={0x04,0x01,0,0,0,0xC8};*len=sendCmdAndGetAck(c,6,out,200,1000);}
// Delete template
void cmd_Delete(uint16_t moduleID,uint16_t
num,uint8_t*out,int*len){uint8_t
c[5]={0x0C,(uint8_t)(moduleID>>8),(uint8_t)moduleID,(uint8_t)(num>>8),(
uint8_t)num};*len=sendCmdAndGetAck(c,5,out,200,1200);}
// Get number of enrolled fingerprints
void cmd_GetTemplateNum(uint8_t*out,int*len){uint8_t
c[1]={0x1D};*len=sendCmdAndGetAck(c,1,out,200,800);}
// Read index table (to know which IDs are used)
void cmd_ReadIndexTable(uint8_t page,uint8_t*out,int*len){uint8_t
c[2]={0x1F,page};*len=sendCmdAndGetAck(c,2,out,300,1200);}
// Control Aura LED (mode, speed, color, times)
void cmd_AuraLed(uint8_t ctrl,uint8_t spd,uint8_t color,uint8_t times){
uint8_t c[5]={0x35,ctrl,spd,color,times};uint8_t ack[32];int len;
sendCmdAndGetAck(c,5,ack,sizeof(ack),500);
}
//LED CONTROL MODES
void ledBlueScan(){cmd_AuraLed(0x01,0x80,0x02,0);} // breathing blue
void ledGreen(){cmd_AuraLed(0x03,0,0x04,0);} // solid green
void ledRed(){cmd_AuraLed(0x02,0x80,0x01,1);} // red flash
// ENROLLMENT FUNCTION
void enrollAtUserID(int userID){
int moduleID = userID - 1; // Convert userID (1-based) to module
slot (0-based)
uint8_t ack[128]; int ackLen;

[Link]("Enrolling ID %d\n",userID);
// Step 1: Capture first image
[Link]("Step 1: place finger");
while(1){
cmd_GenImg(ack,&ackLen);
if(ackLen>9&&ack[9]==0x00){ // success
cmd_Img2Tz(1,ack,&ackLen);
if(ackLen>9&&ack[9]==0x00) break; // stored in buffer 1
}
delay(200);
}

// Ask to remove finger


[Link]("Remove finger...");
delay(1000);

// Step 2: Capture again


[Link]("Step 2: place same finger again");
while(1){
cmd_GenImg(ack,&ackLen);
if(ackLen>9&&ack[9]==0x00){
cmd_Img2Tz(2,ack,&ackLen);
if(ackLen>9&&ack[9]==0x00) break; // stored in buffer 2
}
delay(200);
}

// Combine both images → model


cmd_RegModel(ack,&ackLen);
if(!(ackLen>9&&ack[9]==0x00)){[Link](" ❌ RegModel failed");
return;}

// Store model in flash library


cmd_Store(moduleID,ack,&ackLen);
if(ackLen>9&&ack[9]==0x00){
[Link](" ✅ Stored fingerprint ID %d\n",userID);
ledGreen(); delay(600); ledBlueScan();
}
else {
[Link](" ❌ Store failed");
ledRed(); delay(600); ledBlueScan();
}
}

// IDENTIFICATION FUNCTION

void identifyOnce(){
uint8_t ack[128]; int ackLen;

// Capture finger image


cmd_GenImg(ack,&ackLen);
if(!(ackLen>9) || ack[9]!=0x00) return; // no finger present

// Convert to template buffer


cmd_Img2Tz(1,ack,&ackLen);
if(!(ackLen>9&&ack[9]==0x00)) return;

// Search library for match


cmd_SearchAll(ack,&ackLen);
if(ackLen>13&&ack[9]==0x00){
// Extract matched ID and score
uint16_t moduleID=((uint16_t)ack[10]<<8)|ack[11];
uint16_t score=((uint16_t)ack[12]<<8)|ack[13];
int userID = moduleID + 1;

[Link](" ✅ Match: user ID=%d, score=%d\n",userID,score);


// Blink external LED 3 times
for(int i=0;i<3;i++){
digitalWrite(EXT_LED_PIN,HIGH);
delay(300);
digitalWrite(EXT_LED_PIN,LOW);
delay(300);
}

// Module LED: green success


ledGreen(); delay(400); ledBlueScan();
} else {
[Link](" ❌ No match");
ledRed(); delay(400); ledBlueScan();
}
}

// LIST + DELETE FUNCTIONS

void listStored(){
uint8_t ack[200]; int len;

// Get number of enrolled fingerprints


cmd_GetTemplateNum(ack,&len);
if(len>11&&ack[9]==0x00){
int count=((int)ack[10]<<8)|ack[11];
[Link]("Total enrolled = %d\n",count);
}

// Read index table (page 0 = IDs 0..255)


cmd_ReadIndexTable(0,ack,&len);

[Link]("Enrolled IDs: ");


if(len>41&&ack[9]==0x00){
for(int i=0;i<32;i++){
uint8_t b=ack[10+i];
for(int j=0;j<8;j++){
int moduleID=i*8+j;
if(moduleID<200 && (b&(1<<j))){
[Link]("%d ", moduleID+1); // Convert back to userID
}
}
}
}
[Link]();
}

void deleteWithTimeout(){
[Link]("Enter ID to delete (1..200) within 5s:");
while([Link]()) [Link](); // Clear input buffer

unsigned long t0=millis();


String s="";
// Wait for user input
while(millis()-t0<5000){
if([Link]()){
char c=[Link]();
if(isDigit(c)) s+=c;
else if(c=='\n'||c=='\r') break;
}
}

if([Link]()==0){[Link]("Timeout"); return;}
int userID=[Link]();
if(userID<1||userID>200){[Link]("Invalid ID"); return;}
int moduleID=userID-1;
uint8_t ack[128]; int len;
// Delete given ID
cmd_Delete(moduleID,1,ack,&len);
if(len>9&&ack[9]==0x00) [Link]("Deleted ID %d\n",userID);
else [Link]("Delete failed");
}
//ARDUINO SETUP + LOOP
void setup(){
pinMode(EXT_LED_PIN,OUTPUT);
digitalWrite(EXT_LED_PIN,LOW); // External LED OFF at start

[Link](115200); // Debug over USB


[Link](FP_BAUD,SERIAL_8N1,RX_PIN,TX_PIN); // UART2 for
sensor
delay(200);

[Link]("=== R503-M22 Direct Match Mode ===");


ledBlueScan(); // Module LED: scanning mode (blue breathing)
}
void loop(){
// Handle serial commands
if([Link]()){
char c=[Link]();
if(c=='E'){ // Enroll new finger
enrollAtUserID(nextUserID);
nextUserID++;
if(nextUserID>200) nextUserID=1;
}
else if(c=='S'){ listStored(); } // Show stored fingerprints
else if(c=='D'){ deleteWithTimeout(); } // Delete fingerprint
}
// Always try to identify a finger if placed
identifyOnce();
delay(150);
}

You might also like