This is a fingerprint-based authentication system with keypad backup and LCD display feedback. It combines biometric security with manual PIN entry for access control applications.
Step-by-Step Description
1. Hardware Components
- Arduino Uno - Main microcontroller
- TTP229 Capacitive Touch Keypad (4x4) - 16-key touch interface for PIN entry
- R307 Fingerprint Sensor - Biometric authentication module
- 16x2 LCD Display (I2C) - Shows system status and messages
- 2 LEDs - Red (access denied) and Green (access granted)
- Resistors - Current limiting for LEDs
- Connecting Wires - Signal and power connections
2. Circuit Connections
Fingerprint Sensor (R307)
- VCC → Arduino 5V
- GND → Arduino GND
- TX → Arduino RX (Digital Pin 0 or software serial)
- RX → Arduino TX (Digital Pin 1 or software serial)
LCD Display (I2C)
- VCC → Arduino 5V
- GND → Arduino GND
- SDA → Arduino A4
- SCL → Arduino A5
4x4 Keypad (TTP229)
- VCC → Arduino 5V
- GND → Arduino GND
- SCL → Arduino Digital Pin (e.g., Pin 3)
- SDO → Arduino Digital Pin (e.g., Pin 2)
LEDs
- Red LED Anode → Arduino Digital Pin (e.g., Pin 8) → Resistor (220Ω) → GND
- Green LED Anode → Arduino Digital Pin (e.g., Pin 9) → Resistor (220Ω) → GND
DIAGRAM .json file:
{
"version": 1,
"author": "Tapish Chahera",
"editor": "wokwi",
"parts": [
{
"type": "wokwi-arduino-uno",
"id": "uno",
"top": 152.6,
"left": -33.4,
"rotate": 180,
"attrs": {}
},
{ "type": "wokwi-membrane-keypad", "id": "keypad", "top": 55.6, "left": 245.6, "attrs": {} },
{
"type": "wokwi-led",
"id": "led-green",
"top": 44.4,
"left": 195.8,
"attrs": { "color": "green", "flip": "" }
},
{
"type": "wokwi-led",
"id": "led-red",
"top": 44.4,
"left": 138.2,
"attrs": { "color": "red", "flip": "" }
},
{
"type": "wokwi-lcd1602",
"id": "lcd1",
"top": -89.6,
"left": -23.2,
"attrs": { "pins": "i2c" }
},
{
"type": "board-ili9341-cap-touch",
"id": "lcd2",
"top": -47.24,
"left": -288.38,
"attrs": {}
},
{ "type": "wokwi-junction", "id": "j1", "top": 91.2, "left": 62.4, "attrs": {} },
{ "type": "wokwi-junction", "id": "j2", "top": 91.2, "left": 148.8, "attrs": {} },
{ "type": "wokwi-junction", "id": "j3", "top": 91.2, "left": -52.8, "attrs": {} },
{ "type": "wokwi-junction", "id": "j4", "top": 158.4, "left": -100.8, "attrs": {} },
{ "type": "wokwi-junction", "id": "j5", "top": 72, "left": -43.2, "attrs": {} },
{ "type": "wokwi-junction", "id": "j6", "top": 139.2, "left": -110.4, "attrs": {} }
],
"connections": [
[ "led-green:C", "uno:GND", "black", [ "v0" ] ],
[ "led-red:C", "uno:GND", "black", [ "v0" ] ],
[ "uno:9", "keypad:R1", "green", [ "v57.6", "h325.6" ] ],
[ "uno:8", "keypad:R2", "green", [ "v67.2", "h345.6" ] ],
[ "uno:7", "keypad:R3", "green", [ "v76.8", "h371.1" ] ],
[ "uno:6", "keypad:R4", "green", [ "v86.4", "h390.1" ] ],
[ "uno:5", "keypad:C1", "green", [ "v96", "h409.1" ] ],
[ "uno:4", "keypad:C2", "green", [ "v105.6", "h428.1" ] ],
[ "uno:3", "keypad:C3", "green", [ "v115.2", "h447.35" ] ],
[ "uno:2", "keypad:C4", "green", [ "v124.8", "h466.6" ] ],
[ "lcd2:SCK", "uno:13", "blue", [ "v134.4", "h307.6" ] ],
[ "lcd2:MISO", "uno:12", "blue", [ "v124.8", "h278.9" ] ],
[ "lcd2:MOSI", "uno:11", "blue", [ "v144", "h298.2" ] ],
[ "lcd2:CS", "uno:10", "blue", [ "v153.6", "h317.5" ] ],
[ "uno:GND.2", "j1:J", "black", [ "h-3.9", "v-38.3" ] ],
[ "j1:J", "j2:J", "black", [ "v0" ] ],
[ "j2:J", "led-green:C", "black", [ "v0", "h67.2" ] ],
[ "j2:J", "led-red:C", "black", [ "v0" ] ],
[ "j1:J", "j3:J", "black", [ "v0" ] ],
[ "j3:J", "lcd1:GND", "black", [ "v0" ] ],
[ "j3:J", "lcd2:GND", "black", [ "v230.4", "h-192" ] ],
[ "uno:A5", "j4:J", "yellow", [ "v0" ] ],
[ "j4:J", "lcd1:SCL", "yellow", [ "v0" ] ],
[ "j4:J", "lcd2:SCL", "yellow", [ "v105.6", "h-67.2" ] ],
[ "uno:5V", "j5:J", "red", [ "v-86.3", "h-119" ] ],
[ "j5:J", "lcd1:VCC", "red", [ "v0" ] ],
[ "j5:J", "lcd2:VCC", "red", [ "v259.2", "h-211.2" ] ],
[ "uno:A4", "j6:J", "green", [ "v0" ] ],
[ "j6:J", "lcd1:SDA", "green", [ "v0" ] ],
[ "j6:J", "lcd2:SDA", "green", [ "v115.2", "h-48" ] ],
[ "uno:A0", "led-green:A", "green", [ "v-28.7", "h188.2" ] ],
[ "uno:A1", "led-red:A", "green", [ "v-38.3", "h140.1" ] ],
[ "uno:A3", "lcd2:RST", "blue", [ "v-28.7", "h-71.3", "v163.2", "h-153.6" ] ],
[ "uno:A2", "lcd2:D/C", "blue", [ "v-38.3", "h-90.4", "v163.2", "h-134.4" ] ]
],
"dependencies": {}
}
3. How It Works
System Flow:
- System Startup
- LCD displays: "1. SBI 4894" and "2. PNB 7930"
- These appear to be menu options or account identifiers
- System waits for user input
- Authentication Methods Method A: Fingerprint Authentication
- User places finger on sensor
- Sensor scans and compares with stored templates
- If match found → Green LED lights up
- If no match → Red LED lights up
- LCD shows result message
Method B: PIN Entry- User enters 4-digit PIN using touch keypad
- System validates entered PIN
- Correct PIN → Green LED + Access granted message
- Wrong PIN → Red LED + Access denied message
- Access Control
- Green LED = Access Granted
- Red LED = Access Denied
- LCD provides feedback throughout
4. Programming Logic
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <Keypad.h>
#include <Adafruit_GFX.h>
#include <Adafruit_ILI9341.h>
#include <Adafruit_FT6206.h>
#define TFT_CS 10
#define TFT_DC A2
#define TFT_RST A3
#define LED_GRN A0
#define LED_RED A1
const byte ROWS = 4;
const byte COLS = 4;
char keys[ROWS][COLS] = {{'1','2','3','A'},{'4','5','6','B'},{'7','8','9','C'},{'*','0','#','D'}};
byte rowPins[ROWS] = {9, 8, 7, 6};
byte colPins[COLS] = {5, 4, 3, 2};
Keypad keypad = Keypad(makeKeymap(keys), rowPins, colPins, ROWS, COLS);
LiquidCrystal_I2C lcd(0x27, 16, 2);
Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC, TFT_RST);
Adafruit_FT6206 ctp = Adafruit_FT6206();
enum State { MERCHANT_ENTRY, ID_PHASE, ACCOUNT_SEL, PIN_PHASE };
State currentState = MERCHANT_ENTRY;
// --- MULTI-USER DATA ---
int currentUser = 0;
String userNames[] = {"Tapish Chahera", "Simran Chawla"};
String userBanks[2][5] = {
{"SBI 4894", "PNB 7930", "HDFC 4689", "ICICI 1122", "AXIS 9901"},
{"KOTAK 2210", "INDUS 5543", "YES 9090", "BOB 3321", "UCO 1199"}
};
const int totalBanks = 5;
int scrollIndex = 0;
String amount = "";
String selectedBank = "";
int pinTaps = 0;
int failMode = 0;
float totalSales = 0;
bool sosActive = false;
unsigned long lastTouch = 0;
void setup() {
pinMode(LED_GRN, OUTPUT);
pinMode(LED_RED, OUTPUT);
lcd.init(); lcd.backlight();
tft.begin(); tft.setRotation(0);
// FIX: Lower threshold from 40 to 10 for "Feather Touch" sensitivity
ctp.begin(10);
resetSystem();
}
void resetSystem() {
currentState = MERCHANT_ENTRY;
amount = ""; pinTaps = 0; failMode = 0; selectedBank = ""; scrollIndex = 0;
sosActive = false;
digitalWrite(LED_GRN, LOW); digitalWrite(LED_RED, LOW);
lcd.clear();
lcd.print("Enter Amount:");
lcd.setCursor(0, 1); lcd.print("Rs. ");
// IDLE STATE: Dark Grey Outline
tft.fillScreen(ILI9341_BLACK);
tft.drawEllipse(120, 160, 50, 80, 0x5AEB); // Static Outline
tft.drawEllipse(120, 160, 49, 79, 0x5AEB); // Thicker line
}
// --- OPTIMIZED ANIMATION FUNCTION ---
void scanFingerEffect(uint16_t color) {
// Loop from center to outside
for (int r = 0; r <= 50; r+=3) { // Step by 3 for faster animation
// Use Integer Math (r * 1.6 is roughly r * 8 / 5)
int ry = (r * 8) / 5;
// Draw concentric ovals
tft.drawEllipse(120, 160, r, ry, color);
tft.drawEllipse(120, 160, r+1, ry+1, color); // Double line for fill density
}
}
void updateBankList() {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print(String(scrollIndex + 1) + "." + userBanks[currentUser][scrollIndex]);
if (scrollIndex + 1 < totalBanks) {
lcd.setCursor(0, 1);
lcd.print(String(scrollIndex + 2) + "." + userBanks[currentUser][scrollIndex + 1]);
}
}
void loop() {
// 1. Handle Keypad Inputs
KeyState kstate = keypad.getState();
char key = keypad.getKey();
if (kstate == HOLD) {
char lastKey = keypad.key[0].kchar;
if (lastKey == 'A') { failMode = 2; }
if (lastKey == 'B') { failMode = 1; }
if (lastKey == 'D' && currentState == MERCHANT_ENTRY) {
lcd.clear(); lcd.print("TOTAL SALES:");
lcd.setCursor(0,1); lcd.print("Rs. " + String(totalSales, 2));
delay(3000); resetSystem();
}
}
if (key == '*') sosActive = true;
if (key == 'B' && currentState == MERCHANT_ENTRY) currentUser = !currentUser;
if (currentState == MERCHANT_ENTRY) {
if (key >= '0' && key <= '9') {
amount += key;
lcd.setCursor(4, 1); lcd.print(amount);
}
else if (key == 'A') {
amount = "";
lcd.setCursor(4, 1); lcd.print(" ");
}
else if (key == '#') {
if (amount.toFloat() > 2000) {
lcd.clear(); lcd.print("LIMIT EXCEEDED!");
lcd.setCursor(0,1); lcd.print("Max Rs. 2000");
digitalWrite(LED_RED, HIGH);
delay(3000); resetSystem();
} else if (amount != "") {
currentState = ID_PHASE;
lcd.clear(); lcd.print("Place Finger on");
lcd.setCursor(0, 1); lcd.print("Scanner...");
tft.fillScreen(ILI9341_BLACK);
tft.drawEllipse(120, 160, 50, 80, ILI9341_CYAN);
tft.drawEllipse(120, 160, 49, 79, ILI9341_CYAN);
}
}
}
else if (currentState == ACCOUNT_SEL) {
if (key == 'D' && scrollIndex < totalBanks - 2) { scrollIndex++; updateBankList(); }
if (key == 'C' && scrollIndex > 0) { scrollIndex--; updateBankList(); }
if (key >= '1' && key <= '9') {
int choice = (key - '0') - 1;
if (choice < totalBanks) {
selectedBank = userBanks[currentUser][choice];
currentState = PIN_PHASE;
lcd.clear(); lcd.print("Selected: " + selectedBank.substring(0,6));
lcd.setCursor(0, 1); lcd.print("Tap Pattern Now");
tft.fillScreen(ILI9341_BLACK);
tft.drawEllipse(120, 160, 50, 80, ILI9341_YELLOW);
tft.drawEllipse(120, 160, 49, 79, ILI9341_YELLOW);
}
}
}
// --- 2. FIXED TOUCH LOGIC ---
if (ctp.touched()) {
// CRITICAL FIX: Always retrieve the point to clear the interrupt/register
TS_Point p = ctp.getPoint();
// Only process if enough time has passed (Debounce)
if (millis() - lastTouch > 250) { // Fast 250ms debounce
lastTouch = millis();
// LOGIC: Check state
if (currentState == ID_PHASE) {
scanFingerEffect(ILI9341_CYAN);
if (failMode == 2) {
lcd.clear(); lcd.print("ACCESS DENIED");
lcd.setCursor(0,1); lcd.print("Unknown Finger");
digitalWrite(LED_RED, HIGH);
scanFingerEffect(ILI9341_RED);
delay(3000); resetSystem();
} else {
lcd.clear(); lcd.print("WELCOME:");
lcd.setCursor(0, 1); lcd.print(userNames[currentUser]);
scanFingerEffect(ILI9341_GREEN);
delay(1500);
currentState = ACCOUNT_SEL;
updateBankList();
tft.fillScreen(ILI9341_BLACK);
tft.drawEllipse(120, 160, 50, 80, ILI9341_WHITE);
}
}
else if (currentState == PIN_PHASE) {
pinTaps++;
if (pinTaps == 1) { lcd.setCursor(0, 1); lcd.print(" "); }
lcd.setCursor(0, 1); lcd.print("PIN: ");
for(int i=0; i<pinTaps; i++) lcd.print("*");
scanFingerEffect(ILI9341_WHITE);
tft.fillScreen(ILI9341_BLACK);
tft.drawEllipse(120, 160, 50, 80, ILI9341_YELLOW);
if (pinTaps == 4) {
lcd.clear();
if (failMode == 1) {
lcd.print("TXN FAILED");
lcd.setCursor(0,1); lcd.print("Wrong Pattern");
digitalWrite(LED_RED, HIGH);
scanFingerEffect(ILI9341_RED);
} else {
lcd.print("PAYMENT SUCCESS");
totalSales += amount.toFloat();
digitalWrite(LED_GRN, HIGH);
scanFingerEffect(ILI9341_GREEN);
lcd.setCursor(0,1);
if (sosActive) lcd.print("SOS ALERT SENT!");
else lcd.print("Ref: " + String(random(1000,9999)));
}
delay(4000); resetSystem();
}
}
}
}
}
5. Key Features
✅ Dual Authentication - Fingerprint OR PIN
✅ Visual Feedback - LED indicators
✅ User Interface - LCD display for guidance
✅ Multiple Options - Menu system (SBI/PNB accounts)
✅ Touch Interface - Capacitive keypad (no mechanical wear)
✅ Secure - Biometric + password protection
LIBRARY FILES TO BE USED:
6. Applications
- Door Lock System - Home/office security
- Safe/Locker Access - Personal storage
- Attendance System - Time tracking
- Banking Kiosk - ATM-style interface (as suggested by display)
- Computer Login - Workstation security
- Cabinet Lock - Secure storage
7. Advantages
- Convenience - No need to carry keys
- Security - Dual-layer authentication
- Backup - If fingerprint fails, use PIN
- User Feedback - Clear LCD messages
- Expandable - Can store multiple fingerprints
- Cost-effective - Uses common components

Comments
Post a Comment