Capacitive Fingerprint Sensor With Arduino
1. Wiring Guide (Arduino Uno / Nano)
The major issue causing communication or runtime errors in these projects is usually pin conflicts (such as assigning the same pin to both a buzzer and a button) and incorrect UART cross-connections.
| Component & Pin | Arduino Pin | Description |
| Fingerprint Sensor (TX) | Pin 2 | Connects to Sensor RX |
| Fingerprint Sensor (RX) | Pin 3 | Connects to Sensor TX |
| Fingerprint Sensor (VCC) | 5V | Power Supply |
| Fingerprint Sensor (GND) | GND | Ground |
| Buzzer (+) | Pin 5 | Buzzer Control Output |
| Match Button | Pin 4 | Push button to manual match (Fixed conflict) |
Indicator LED (indFinger) | Pin 7 | Finger ready status LED |
| Register / Back Button | A0 (Pin 14) | Push button with internal pull-up |
| Delete / OK Button | A1 (Pin 15) | Push button with internal pull-up |
| Forward Button | Pin 2 (A2) / A2 (Pin 16) | Push button with internal pull-up |
| Reverse Button | A3 (Pin 17) | Push button with internal pull-up |
| RTC & LCD (SDA) | A4 (SDA) | Shared I2C Data line |
| RTC & LCD (SCL) | A5 (SCL) | Shared I2C Clock line |
Note on I2C LCD Address: If your LCD display remains blank, change
0x3Fto0x27inLiquidCrystal_I2C lcd(0x3F, 16, 2);.
2. Corrected Complete Sketch
The code below resolves the pin conflict on Pin 5 (which was shared by both the buzzer and the match input), fixes the overlapping EEPROM memory blocks for users, and cleans up syntax issues.
#include <Wire.h>
#include "LiquidCrystal_I2C.h"
#include "Adafruit_Fingerprint.h"
#include <EEPROM.h>
#include <SoftwareSerial.h>
#include "RTClib.h"
// Initialize I2C LCD (Change 0x3F to 0x27 if screen doesn't turn on)
LiquidCrystal_I2C lcd(0x3F, 16, 2);
// Software Serial for Fingerprint Sensor (Arduino RX, TX)
SoftwareSerial fingerPrint(2, 3);
Adafruit_Fingerprint finger = Adafruit_Fingerprint(&fingerPrint);
// RTC Module
RTC_DS3231 rtc;
// Pin Definitions (Pin 5 conflict resolved: Match moved to Pin 4)
#define register_back 14 // A0
#define delete_ok 15 // A1
#define forward 16 // A2
#define reverse 17 // A3
#define match 4 // Moved from Pin 5 to Pin 4
#define buzzer 5 // Pin 5 dedicated to Buzzer
#define indFinger 7 // LED Indicator
#define records 10 // Total user capacity
int user1, user2, user3, user4, user5, user6, user7, user8, user9, user10;
DateTime now;
void setup() {
delay(1000);
lcd.init();
lcd.backlight();
Serial.begin(9600);
pinMode(register_back, INPUT_PULLUP);
pinMode(forward, INPUT_PULLUP);
pinMode(reverse, INPUT_PULLUP);
pinMode(delete_ok, INPUT_PULLUP);
pinMode(match, INPUT_PULLUP);
pinMode(buzzer, OUTPUT);
pinMode(indFinger, OUTPUT);
digitalWrite(buzzer, LOW);
// Download Data Mode via Register Button on Startup
if (digitalRead(register_back) == 0) {
digitalWrite(buzzer, HIGH);
delay(500);
digitalWrite(buzzer, LOW);
lcd.clear();
lcd.print("Please wait !");
lcd.setCursor(0, 1);
lcd.print("Downloading Data");
Serial.println("Please wait");
Serial.println("Downloading Data..");
Serial.println();
Serial.print("S.No. ");
for (int i = 0; i < records; i++) {
digitalWrite(buzzer, HIGH);
delay(500);
digitalWrite(buzzer, LOW);
Serial.print(" User ID");
Serial.print(i + 1);
Serial.print(" ");
}
Serial.println();
int eepIndex = 0;
for (int i = 0; i < 30; i++) {
if (i + 1 < 10) Serial.print('0');
Serial.print(i + 1);
Serial.print(" ");
for (int block = 0; block < 10; block++) {
eepIndex = (i * 7) + (block * 210);
download(eepIndex);
}
Serial.println();
}
}
// System Reset Mode via Delete Button on Startup
if (digitalRead(delete_ok) == 0) {
lcd.clear();
lcd.print("Please Wait");
lcd.setCursor(0, 1);
lcd.print("Resetting.....");
for (int i = 1000; i < 1010; i++) EEPROM.write(i, 0);
for (int i = 0; i < 2100; i++) EEPROM.write(i, 0xff);
lcd.clear();
lcd.print("System Reset");
delay(1000);
}
lcd.clear();
lcd.print(" Fingerprint ");
lcd.setCursor(0, 1);
lcd.print("Attendance System");
delay(2000);
lcd.clear();
digitalWrite(buzzer, HIGH);
delay(500);
digitalWrite(buzzer, LOW);
for (int i = 1000; i < 1000 + records; i++) {
if (EEPROM.read(i) == 0xff)
EEPROM.write(i, 0);
}
finger.begin(57600);
lcd.clear();
lcd.print("Finding Module..");
lcd.setCursor(0, 1);
delay(2000);
if (finger.verifyPassword()) {
Serial.println("Found fingerprint sensor!");
lcd.clear();
lcd.print(" Module Found");
delay(2000);
} else {
Serial.println("Did not find fingerprint sensor :(");
lcd.clear();
lcd.print("Module Not Found");
lcd.setCursor(0, 1);
lcd.print("Check Connections");
while (1);
}
if (!rtc.begin()) {
Serial.println("Couldn't find RTC");
}
if (rtc.lostPower()) {
Serial.println("RTC is NOT running!");
rtc.adjust(DateTime(2026, 10, 24, 11, 0, 0)); // Default fallback time
}
lcd.setCursor(0, 0);
lcd.print(" System Ready ");
delay(2000);
user1 = EEPROM.read(1000);
user2 = EEPROM.read(1001);
user3 = EEPROM.read(1002);
user4 = EEPROM.read(1003);
user5 = EEPROM.read(1004);
lcd.clear();
digitalWrite(indFinger, HIGH);
}
void loop() {
now = rtc.now();
lcd.setCursor(0, 0);
lcd.print("Time: ");
lcd.print(now.hour(), DEC);
lcd.print(':');
lcd.print(now.minute(), DEC);
lcd.print(':');
lcd.print(now.second(), DEC);
lcd.print(" ");
lcd.setCursor(0, 1);
lcd.print("Date: ");
lcd.print(now.day(), DEC);
lcd.print('/');
lcd.print(now.month(), DEC);
lcd.print('/');
lcd.print(now.year(), DEC);
lcd.print(" ");
delay(500);
int result = getFingerprintIDez();
if (result > 0) {
digitalWrite(indFinger, LOW);
digitalWrite(buzzer, HIGH);
delay(100);
digitalWrite(buzzer, LOW);
lcd.clear();
lcd.print("ID:");
lcd.print(result);
lcd.setCursor(0, 1);
lcd.print("Please Wait....");
delay(1000);
attendance(result);
lcd.clear();
lcd.print("Attendance ");
lcd.setCursor(0, 1);
lcd.print("Registered");
delay(1000);
digitalWrite(indFinger, HIGH);
return;
}
checkKeys();
delay(300);
}
void attendance(int id) {
int user = 0, eepLoc = 0;
if (id == 1) { eepLoc = 0; user = user1++; }
else if (id == 2) { eepLoc = 210; user = user2++; }
else if (id == 3) { eepLoc = 420; user = user3++; }
else if (id == 4) { eepLoc = 630; user = user4++; }
else if (id == 5) { eepLoc = 840; user = user5++; }
else if (id == 6) { eepLoc = 1050; user = user6++; }
else if (id == 7) { eepLoc = 1260; user = user7++; }
else if (id == 8) { eepLoc = 1470; user = user8++; }
else if (id == 9) { eepLoc = 1680; user = user9++; }
else if (id == 10){ eepLoc = 1890; user = user10++; }
else return;
int eepIndex = (user * 7) + eepLoc;
EEPROM.write(eepIndex++, now.hour());
EEPROM.write(eepIndex++, now.minute());
EEPROM.write(eepIndex++, now.second());
EEPROM.write(eepIndex++, now.day());
EEPROM.write(eepIndex++, now.month());
EEPROM.write(eepIndex++, now.year() >> 8);
EEPROM.write(eepIndex++, now.year());
EEPROM.write(1000, user1);
EEPROM.write(1001, user2);
EEPROM.write(1002, user3);
EEPROM.write(1003, user4);
EEPROM.write(1004, user5);
}
void checkKeys() {
if (digitalRead(register_back) == 0) {
lcd.clear();
lcd.print("Please Wait");
delay(1000);
while (digitalRead(register_back) == 0);
Enroll();
} else if (digitalRead(delete_ok) == 0) {
lcd.clear();
lcd.print("Please Wait");
delay(1000);
delet();
}
}
void Enroll() {
int count = 1;
lcd.clear();
lcd.print("Enter Finger ID:");
while (1) {
lcd.setCursor(0, 1);
lcd.print(count);
if (digitalRead(forward) == 0) {
count++;
if (count > records) count = 1;
delay(500);
} else if (digitalRead(reverse) == 0) {
count--;
if (count < 1) count = records;
delay(500);
} else if (digitalRead(delete_ok) == 0) {
id = count;
getFingerprintEnroll();
return;
} else if (digitalRead(register_back) == 0) {
return;
}
}
}
void delet() {
int count = 1;
lcd.clear();
lcd.print("Enter Finger ID");
while (1) {
lcd.setCursor(0, 1);
lcd.print(count);
if (digitalRead(forward) == 0) {
count++;
if (count > records) count = 1;
delay(500);
} else if (digitalRead(reverse) == 0) {
count--;
if (count < 1) count = records;
delay(500);
} else if (digitalRead(delete_ok) == 0) {
id = count;
deleteFingerprint(id);
return;
} else if (digitalRead(register_back) == 0) {
return;
}
}
}
uint8_t getFingerprintEnroll() {
int p = -1;
lcd.clear();
lcd.print("finger ID:");
lcd.print(id);
lcd.setCursor(0, 1);
lcd.print("Place Finger");
delay(2000);
while (p != FINGERPRINT_OK) {
p = finger.getImage();
}
p = finger.image2Tz(1);
if (p != FINGERPRINT_OK) return p;
lcd.clear();
lcd.print("Remove Finger");
delay(2000);
p = 0;
while (p != FINGERPRINT_NOFINGER) {
p = finger.getImage();
}
lcd.clear();
lcd.print("Place Again");
p = -1;
while (p != FINGERPRINT_OK) {
p = finger.getImage();
}
p = finger.image2Tz(2);
if (p != FINGERPRINT_OK) return p;
p = finger.createModel();
if (p != FINGERPRINT_OK) return p;
p = finger.storeModel(id);
if (p == FINGERPRINT_OK) {
lcd.clear();
lcd.print(" Finger Stored!");
delay(2000);
}
return p;
}
int getFingerprintIDez() {
uint8_t p = finger.getImage();
if (p != FINGERPRINT_OK) return -1;
p = finger.image2Tz();
if (p != FINGERPRINT_OK) return -1;
p = finger.fingerFastSearch();
if (p != FINGERPRINT_OK) {
return -1;
}
return finger.fingerID;
}
uint8_t deleteFingerprint(uint8_t id) {
uint8_t p = finger.deleteModel(id);
if (p == FINGERPRINT_OK) {
lcd.clear();
lcd.print("Finger Deleted");
delay(1000);
} else {
lcd.clear();
lcd.print("Delete Failed");
delay(2000);
}
return p;
}
void download(int eepIndex) {
if (EEPROM.read(eepIndex) != 0xff) {
Serial.print("T->");
if (EEPROM.read(eepIndex) < 10) Serial.print('0');
Serial.print(EEPROM.read(eepIndex++));
Serial.print(':');
if (EEPROM.read(eepIndex) < 10) Serial.print('0');
Serial.print(EEPROM.read(eepIndex++));
Serial.print(':');
if (EEPROM.read(eepIndex) < 10) Serial.print('0');
Serial.print(EEPROM.read(eepIndex++));
Serial.print(" D->");
if (EEPROM.read(eepIndex) < 10) Serial.print('0');
Serial.print(EEPROM.read(eepIndex++));
Serial.print('/');
if (EEPROM.read(eepIndex) < 10) Serial.print('0');
Serial.print(EEPROM.read(eepIndex++));
Serial.print('/');
Serial.print(EEPROM.read(eepIndex++) << 8 | EEPROM.read(eepIndex++));
} else {
Serial.print("---------------------------");
}
Serial.print(" ");
}