Case Study

Scan2Attend

An IoT-powered classroom attendance system that records student check-ins via fingerprint scanning on an ESP32 device, synced to a Laravel backend with offline SD card queuing.

2025 – 2026
CS 397: Internet of Everything
ESP32C++ / ArduinoLaravel 12Nuxt.jsPostgreSQLREST API
system_architecture.svg — Live
ESP32 DeviceFingerprint + RTC + LCD
Wi-Fi / REST
Laravel BackendAPI + PostgreSQL
JSON / SSR
Nuxt.js FrontendAdmin Dashboard
SD CardOffline Queue

↑ Animated system architecture — ESP32 → Backend → Frontend data flow

// How It Works

Attendance Pipeline

1

Fingerprint Scan

Student places finger on the AS608 sensor; image is captured and matched

2

ESP32 Processing

Firmware identifies the fingerprint, timestamps with RTC, and builds JSON payload

3

Backend Sync

Check-in is POSTed to the Laravel API, or queued to SD if offline

4

Dashboard View

Attendance records are aggregated and displayed on the Nuxt.js frontend

// Hardware

Component Wiring

ESP32 Dev Module

Main controller

AS608 Fingerprint

Biometric input

GPIO 16/17 (UART2)

DS3231 RTC

Timekeeping

GPIO 21/22 (I2C)

LCD 16×2 I2C

User display

GPIO 21/22 (I2C)

MicroSD Module

Offline storage

GPIO 5/23/19/18 (SPI)

Passive Buzzer

Audio feedback

GPIO 25

// Capabilities

Features

24/7 continuous fingerprint scanning
Offline SD card queuing with auto-sync
Wi-Fi Manager with captive portal
RTC-based accurate timestamps
LCD display & buzzer feedback
RESTful API for device management
Session-aware attendance check-in
Fingerprint enrollment via web interface
Admin dashboard for attendance records

// Code Sample

Fingerprint Scan Loop

ESP32_Fingerprint_Attendance.ino
// 24/7 Continuous Fingerprint Scanning
if (sensorConnected && !enrollRequested) {
  uint8_t p = finger.getImage();

  if (p == FINGERPRINT_OK) {
    p = finger.image2Tz();
    p = finger.fingerSearch();

    if (p == FINGERPRINT_OK) {
      int fpId = finger.fingerID;

      // Check cooldown (prevent duplicate scans)
      if (fpId == lastScannedID &&
          millis() - lastScanTime < SCAN_COOLDOWN) {
        return;  // Same finger, too fast
      }

      String scannedAt = getRTCDateTime();

      // Build JSON payload
      JsonDocument doc;
      doc["fingerprint_id"] = fpId;
      doc["scanned_at"] = scannedAt;

      // POST to Laravel backend
      if (backendConnected) {
        String response = httpPostJson(checkInURL, payload);
        showStudent(displayName, timeStr);
        buzzerSuccess();
      } else {
        // Offline: queue to SD card
        queueAttendance(fpId, scannedAt);
        showOfflineSaved(displayName);
        buzzerOfflineSave();
      }
    }
  }
}

// Technical Deep Dive

Challenges & Solutions

Hardware–Software Integration

Problem

Coordinating multiple peripherals (AS608 sensor, DS3231 RTC, LCD, SD card, buzzer) on a single ESP32 without blocking the main scan loop

Solution

Used non-blocking timer patterns and modular header files for each peripheral, allowing the main loop to continuously scan while background tasks run on intervals

Offline Resilience

Problem

Attendance records would be lost when Wi-Fi or the backend server was unreachable

Solution

Implemented JSONL-based queue on the SD card. Records are appended when offline and automatically replayed via /api/attendance/sync when connectivity is restored

Real-time Backend Sync

Problem

Ensuring attendance records arrive in the correct session with accurate timestamps despite network latency

Solution

The ESP32 uses a DS3231 RTC for precise local timestamps, and the Laravel backend resolves the active session server-side based on the scanned_at value

// Architecture

System Overview

ESP32 Firmware

Runs a 24/7 scan loop with non-blocking timers. Manages AS608 sensor, DS3231 RTC, LCD display, SD card queue, and buzzer — all through modular header files.

Laravel Backend

RESTful API handles check-ins, session resolution, enrollment, and attendance sync. Models the university structure with courses, sections, and sessions.

Nuxt.js Dashboard

Admin-facing frontend for viewing attendance records, managing students, enrolling fingerprints, and monitoring device health in real time.

Explore the Source Code

The project is split across two repositories — ESP32 firmware and the web platform.

Enjoyed this project? Consider supporting my work ☕

Buy Me a Coffee