Biometric Access System with Dual Authentication using Arduino Uno

 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:

  1. 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
  2. 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
  3. 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