Attendance management systems are crucial in various domains, such as workplaces, educational institutions, and events. Traditional systems require manual intervention, making them susceptible to errors and delays. This biometric-based system automates the attendance process using fingerprint verification, ensuring a secure, efficient, and accurate record of attendance. ESP32, a Wi-Fi-enabled microcontroller, connects the system to the internet, allowing remote attendance logging.

Components

  1. ESP32S 38Pin Board:

    • This is the main control board, responsible for handling the fingerprint sensor, managing Wi-Fi connections, and sending attendance data.
    • It has GPIO pins for communication with sensors, displays, and other peripherals.
  2. Fingerprint Sensor:

    • Used for capturing and verifying fingerprints to identify authorized users.
    • This sensor is highly secure as it recognizes unique biometric patterns for each person, ensuring that only authorized fingerprints are recorded.
  3. OLED Display:

    • Provides visual feedback for the user, displaying messages like "Place Finger," attendance status, and Wi-Fi connection notifications.
    • The display operates on I2C protocol, minimizing the number of connections to the ESP32.
  4. Buzzer:

    • Produces a sound as feedback during fingerprint authentication.
    • The buzzer sounds differently for successful and unsuccessful attempts, making it easy for users to understand the result without looking at the display.

Circuit Diagram and Connections

  • ESP32 to Fingerprint Sensor: The RX and TX pins on the fingerprint sensor connect to TX2 (GPIO17) and RX2 (GPIO16) on the ESP32, allowing serial communication between the two devices.

  • ESP32 to OLED Display: The I2C pins (SDA and SCL) of the OLED are connected to GPIO21 and GPIO22 of the ESP32. This allows two-wire communication with the display.

  • ESP32 to Buzzer: The buzzer connects to GPIO15 of the ESP32. It will buzz based on the feedback from fingerprint recognition

Explanation of Code

This project consist of 2 coding parts , 1st is registering the fingerprints in the fingerprint sensor, those registered fingerprints will be stored in the fingerprint sensor's internal memory with the help of enroll code from the example section of Arduino IDE. Then you have to write another code for the esp for monitoring the attendance.
For that you have to install Adafruit fingerprint sensor library from github.

In the enroll example code, you have to make some changes (as given in pictures below of before and after) to register your fingerprints.

Before Changes


After Changes


Once yo've

    1. Library Inclusions and Global Settings

    #include <Adafruit_Fingerprint.h>
    #include <WiFi.h>
    #include <Adafruit_GFX.h>
    #include <Adafruit_SSD1306.h>
    #include <NTPClient.h>
    #include <WiFiUdp.h>

    These libraries are essential for the various hardware components:

    • Adafruit_Fingerprint: Manages the fingerprint sensor, providing methods for fingerprint recognition and data handling.
    • WiFi: Handles ESP32’s Wi-Fi functionality for connecting to the internet.
    • Adafruit_GFX and Adafruit_SSD1306: Control the OLED display, allowing text and graphic rendering.
    • NTPClient and WiFiUdp: Libraries for retrieving the current time from NTP servers.

       

      2. OLED Display and Fingerprint Sensor Configuration

      #define SCREEN_WIDTH 128
      #define SCREEN_HEIGHT 64
      #define OLED_RESET -1
      Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

      • SCREEN_WIDTH and SCREEN_HEIGHT specify the resolution of the OLED display.
      • OLED_RESET is set to -1 because ESP32 does not use a reset pin with the display.
      • display: Instantiates the OLED with the settings above, which allows display functions to be called throughout the code. 

      Adafruit_Fingerprint finger = Adafruit_Fingerprint(&Serial2);

      • finger: Initializes the fingerprint sensor on the Serial2 interface, setting up communication through this secondary serial channel of ESP32.

       

      3. Wi-Fi and IFTTT Webhook Configuration

       

      const char* ssid = "SSID";

       

      const char* password = "PASS";
      String Event_Name = "fingerprint";
      String Key = "Your_Webhooks_Key";
      String resource = "/trigger/" + Event_Name + "/with/key/" + Key;
      const char* server = "maker.ifttt.com";

      Here:

      • ssid and password: Wi-Fi network credentials for connecting ESP32 to the internet.
      • Event_Name and Key: Used to trigger the correct IFTTT Webhook event. Event_Name specifies the IFTTT event name, and Key is the unique Webhook key.You can get yours from IFTTT website.
      • resource: Builds the endpoint path for the IFTTT request, which is /trigger/[Event_Name]/with/key/[Key].
      • server: Specifies IFTTT’s base server address.
      WiFiUDP ntpUDP;
      NTPClient timeClient(ntpUDP, "pool.ntp.org", 19800, 60000); // 19800 sec offset for IST
      • WiFiUDP ntpUDP: Creates an instance of the UDP protocol used for NTP communications.

      • NTPClient timeClient(...): Initializes an NTP client using the created UDP instance. It connects to the "pool.ntp.org" server, uses a 19800 seconds offset to adjust for Indian Standard Time (IST), and checks the time every 60,000 milliseconds (60 seconds).

      4. Global Variables and Buzzer Setup

       

      #define BUZZER_PIN 15
      String NAME;
      String ID;

       

      • BUZZER_PIN: Defines GPIO pin 15 for the buzzer.
      • NAME: A string variable to store the name of the recognized user based on their fingerprint.
      • ID: A string variable to store the ID corresponding to the recognized fingerprint. This allows tracking of which user’s attendance has been marked.

      5. Setup Function

       

      void setup() {
      Serial.begin(115200);
      Serial2.begin(57600);
      pinMode(BUZZER_PIN, OUTPUT);

       

      • Serial.begin(115200) and Serial2.begin(57600): Initialize serial communication for ESP32’s main serial interface and secondary serial for the fingerprint sensor. 115200 and 57600 are baud rates for data transfer speeds.
      • pinMode(BUZZER_PIN, OUTPUT): Configures the buzzer pin as an output to allow control.
      if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
      Serial.println(F("SSD1306 allocation failed"));
      for(;;);
      }
      display.clearDisplay();

       

      • display.begin(): Initializes the OLED display at I2C address 0x3C. If the display fails to initialize, it prints an error and halts the system.
      • display.clearDisplay(): Clears the display to start with a blank screen.

      connectWiFi();

      • Calls connectWiFi() to connect ESP32 to the specified Wi-Fi network.

      if (finger.verifyPassword()) {
      Serial.println("Found fingerprint sensor!");
      } else {
      Serial.println("Fingerprint sensor not found :(");
      while (1) { delay(1); }
      }

      • finger.verifyPassword() checks if the ESP32 can communicate with the fingerprint sensor. If unsuccessful, it halts execution.

      finger.getTemplateCount();
      Serial.print("Sensor contains "); Serial.print(finger.templateCount); Serial.println(" templates");

      • finger.getTemplateCount(): Retrieves and prints the number of fingerprint templates stored in the sensor’s memory.

       

      6. Main Loop - Attendance Verification Process

      void loop() {
      timeClient.update(); // Update the time
      String formattedTime = timeClient.getFormattedTime();

      int id = getFingerprintIDez();

          if (id != -1) {
              // Update NAME based on fingerprint ID
              if (id == 1) {
                  NAME = "A";//modify names as needed
              } else if (id == 2) {
                  NAME = "Tushar";
              } else if (id == 3) {
                  NAME = "B";
              } else if (id == 4) {
                  NAME = "C";
              } else if (id == 5) {
                  NAME = "D";
              } else {
                  NAME = "Unknown";
              }// Modify as needed
      ID = String(id);


      if (finger.confidence >= 60) {
      Serial.print("Attendance Marked for "); Serial.println(NAME);
      displayAttendance(NAME.c_str());
      makeIFTTTRequest();
      digitalWrite(BUZZER_PIN, HIGH); // Activate buzzer
      delay(500); // Buzzer duration
      digitalWrite(BUZZER_PIN, LOW); // Deactivate buzzer
      }
      }
      delay(1000);
      }

      • Continuously checks for fingerprints.
      • If a fingerprint is recognized, it marks attendance by printing the name and activating a buzzer.
      • Calls the function to send the attendance data to IFTTT.

      7. Fingerprint Scanning Functions

      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) {
      Serial.print("Found ID #"); Serial.print(finger.fingerID);
      Serial.print(" with confidence of "); Serial.println(finger.confidence);
      return finger.fingerID;
      }
      return -1;
      }

      getFingerprintIDez(): Scans and identifies fingerprints by following these steps:
      • getImage(): Captures an image of the fingerprint.
      • image2Tz(): Converts the image to a template.
      • fingerFastSearch(): Searches for a match among stored fingerprints and returns the ID if found.

      8. Display Attendance Function

      void displayAttendance(const char* name) {
      display.clearDisplay();
      display.setTextSize(1);
      display.setTextColor(SSD1306_WHITE);
      display.setCursor(0,0);
      display.println("Attendance Marked");
      display.print("User: ");
      display.println(name);
      display.display();
      }

      displayAttendance(): Updates the OLED display to show the attendance message.

      • display.clearDisplay(): Clears any previous content on the display.

      • display.setTextSize(1): Sets the text size for the display. The value 1 is a standard size, where 1 is the smallest.

      • display.setTextColor(SSD1306_WHITE): Sets the text color to white (the display background is typically black).

      • display.setCursor(0,0): Positions the cursor at the top-left corner of the display.

      • The next lines display the "Attendance Marked" message and the user’s name on the OLED screen.

      • display.display(): Sends the buffered content to the OLED for rendering.

       

         

        9. Making IFTTT Requests
        void makeIFTTTRequest(String timestamp) {

        WiFiClient client;

        if (!client.connect(server, 80)) {

        Serial.println("Connection to server failed");

        return;

        }

        String url = resource + "?value1=" + NAME + "&value2=" + ID + "&value3=" + timestamp; // Include name, ID, and timestamp

        Serial.print("Requesting URL: ");

        Serial.println(url);

        client.print(String("GET ") + url + " HTTP/1.1\r\n" +

        "Host: " + server + "\r\n" +

        "Connection: close\r\n\r\n");

        }

        makeIFTTTRequest(): Handles the HTTP GET request to trigger the IFTTT webhook.

        • WiFiClient client: Creates a client instance to handle network communications.

        • client.connect(...): Attempts to connect to the IFTTT server on port 80 (HTTP). If the connection fails, an error message is printed, and the function exits.

        • String url = resource: Assigns the constructed resource URL.

        • client.print(...): Sends the HTTP GET request to the server, including headers for the host and connection.

         

        Importance of IFTTT in This Project

        IFTTT (If This Then That) is a web-based service that connects various apps, devices, and services to automate actions based on specific triggers. It’s widely used to simplify processes across the Internet of Things (IoT) by linking different online services and hardware devices. In this project, IFTTT is crucial because it allows the ESP32 to send attendance data to a cloud-based platform without requiring a complex server or database setup.

        In the IoT Attendance System project, IFTTT is used as a bridge to log attendance data in real-time by sending a notification when a fingerprint is matched. This data could be stored in Google Sheets, sent via email, or recorded in any compatible platform connected to IFTTT. Here’s why IFTTT is so useful:

        1. Remote Attendance Logging:

          • IFTTT sends attendance data (e.g., the recognized person’s name and ID) to the cloud instantly. This could be useful in real-world applications, like sending a record of arrivals and departures to a centralized attendance database.

        2. No Need for Dedicated Server:

          • Without IFTTT, a more complex backend server and API would be required to manage the data. IFTTT eliminates the need for this setup by handling the data transmission directly, simplifying the project and saving on setup costs and maintenance.

        3. Platform Integration:

          • IFTTT can connect with Google Sheets, Gmail, Slack, etc., enabling easy integration with commonly used apps. For instance, each attendance event could automatically update a Google Sheet in real time.

        4. Minimal Code and Resources on ESP32:

          • The ESP32 only needs a few lines of code to format and send the attendance data as a JSON object to IFTTT, minimizing resource use on the microcontroller.

        How IFTTT Works in This Project
        1. Setting Up the IFTTT Webhook:
          • A webhook URL is created within IFTTT, consisting of:

            • Event Name: (e.g., "fingerprint") which identifies the specific IFTTT trigger for this project.

            • Key: A unique key that links the ESP32 request to your IFTTT account, ensuring security.

        2. Sending Data to IFTTT:

          • When a fingerprint is matched, the project uses the makeIFTTTRequest() function to send an HTTP POST request to the webhook URL. Here’s how it works:

            • JSON Payload: The function creates a JSON object with value1 and value2, containing the user's name and ID.

            • HTTP POST Request: The ESP32 connects to IFTTT’s server (maker.ifttt.com) and sends this JSON payload to trigger the event.

        3. IFTTT Executes the Action:

          • When the IFTTT webhook receives the data, it performs the specified action, such as logging the information in Google Sheets or sending an email.

        Workflow Summary

        1. The ESP32 identifies a user by fingerprint.

        2. If a match is found, it sends a POST request with the user’s data to the IFTTT webhook.

        3. IFTTT receives this data and triggers the predefined action, like updating a Google Sheet.

        Code

        // 1. Library Inclusions and Global Settings
        #include <Adafruit_Fingerprint.h>
        #include <WiFi.h>
        #include <Adafruit_GFX.h>
        #include <Adafruit_SSD1306.h>
        #include <NTPClient.h>
        #include <WiFiUdp.h>

        // 2. OLED Display and Fingerprint Sensor Configuration
        #define SCREEN_WIDTH 128
        #define SCREEN_HEIGHT 64
        #define OLED_RESET -1
        Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
        Adafruit_Fingerprint finger = Adafruit_Fingerprint(&Serial2);

        // 3. Wi-Fi and IFTTT Webhook Configuration
        const char* ssid = "SSID"; // Replace with your Wi-Fi SSID
        const char* password = "PASS"; // Replace with your Wi-Fi password
        String Event_Name = "fingerprint";
        String Key = "Your_Webhooks_Key"; // Replace with your IFTTT Webhooks key
        String resource = "/trigger/" + Event_Name + "/with/key/" + Key;
        const char* server = "maker.ifttt.com";

        // NTP Client Configuration
        WiFiUDP ntpUDP;
        NTPClient timeClient(ntpUDP, "pool.ntp.org", 19800, 60000); // 19800 sec offset for IST

        // 4. Global Variables and Buzzer Setup
        #define BUZZER_PIN 15
        String NAME;
        String ID;

        // 5. Setup Function
        void setup() {
        Serial.begin(115200);
        Serial2.begin(57600);
        pinMode(BUZZER_PIN, OUTPUT);

        if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
        Serial.println(F("SSD1306 allocation failed"));
        for(;;);
        }
        display.clearDisplay();

        connectWiFi();
        timeClient.begin(); // Initialize the NTP client

        if (finger.verifyPassword()) {
        Serial.println("Found fingerprint sensor!");
        } else {
        Serial.println("Fingerprint sensor not found :(");
        while (1) { delay(1); }
        }

        finger.getTemplateCount();
        Serial.print("Sensor contains "); Serial.print(finger.templateCount); Serial.println(" templates");
        }

        // 6. Main Loop - Attendance Verification Process
        void loop() {
        timeClient.update(); // Update the time
        String formattedTime = timeClient.getFormattedTime(); // Get the formatted time

        int id = getFingerprintIDez();
        if (id != -1) {
        NAME = (id == 1) ? "Priyanshu" : "Tushar"; // Modify as needed
        ID = String(id);

        if (finger.confidence >= 60) {
        Serial.print("Attendance Marked for "); Serial.println(NAME);
        displayAttendance(NAME.c_str());
        makeIFTTTRequest(formattedTime); // Pass the time to the request
        digitalWrite(BUZZER_PIN, HIGH); // Activate buzzer
        delay(500); // Buzzer duration
        digitalWrite(BUZZER_PIN, LOW); // Deactivate buzzer
        }
        }
        delay(1000);
        }

        // 7. Fingerprint Scanning Functions
        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) {
        Serial.print("Found ID #"); Serial.print(finger.fingerID);
        Serial.print(" with confidence of "); Serial.println(finger.confidence);
        return finger.fingerID;
        }
        return -1;
        }

        // 8. IFTTT Webhook Request
        void makeIFTTTRequest(String timestamp) {
        WiFiClient client;
        if (!client.connect(server, 80)) {
        Serial.println("Connection to server failed");
        return;
        }

        String jsonObject = String("{\"value1\":\"") + NAME + "\",\"value2\":\"" + ID + "\",\"value3\":\"" + timestamp + "\"}";
        String url = resource + " HTTP/1.1\r\n" +
        "Host: " + server + "\r\n" +
        "Content-Type: application/json\r\n" +
        "Connection: close\r\n" +
        "Content-Length: " + jsonObject.length() + "\r\n" +
        "\r\n" + jsonObject;

        client.print(url);

        delay(500);
        while (client.available()) {
        String line = client.readStringUntil('\r');
        Serial.print(line);
        }
        client.stop();
        }

        // 9. Wi-Fi Connection Function
        void connectWiFi() {
        Serial.print("Connecting to ");
        Serial.println(ssid);
        WiFi.begin(ssid, password);

        int retries = 0;
        while (WiFi.status() != WL_CONNECTED && retries < 20) {
        delay(500);
        Serial.print(".");
        retries++;
        }

        if (WiFi.status() == WL_CONNECTED) {
        Serial.println("WiFi connected");
        Serial.println("IP address: ");
        Serial.println(WiFi.localIP());
        } else {
        Serial.println("WiFi connection failed");
        }
        }

        // 10. Display Attendance Function
        void displayAttendance(const char* name) {
        display.clearDisplay();
        display.setTextSize(1);
        display.setTextColor(SSD1306_WHITE);
        display.setCursor(0, 0);
        display.print("Attendance Marked for:");
        display.setTextSize(2);
        display.setCursor(0, 16);
        display.print(name);
        display.display();
        delay(2000);
        }

         

         

         

        Leave a comment

        Please note, comments must be approved before they are published

        Your cart

        ×