Close
0%
0%

Arduino Uno R4 Wi-Fi Based RFID Attendance System

An Arduino Uno R4 Wi-Fi-powered intelligent, automated RFID attendance system that tracks attendance, timing and summary in real-time!

Similar projects worth following
0 followers

Introduction

Despite being a vital component of everyday operations in workplaces, schools, and universities, attendance tracking is frequently tedious and subject to human mistake. With automation and real-time data logging, the Arduino UNO R4 Wi-Fi Based RFID Attendance System provides a sophisticated solution.

This technique makes tracking attendance easier by utilizing RFID (Radio Frequency Identification) technology. Every student receives and RFID card, which the system stamps as "Present - On Time" if it is scanned within the first ten minutes of powering up. Students who do not scan are immediately marked absent, while those who scan after ten minutes have their status changed to "Present - Late."

Additionally, the system has a teacher's master card that, when scanned, shows the attendance summary for every student who has enrolled on a 20x4 I2C LCD screen.

This project combines automation and electronics to provide a practical smart attendance solution that is perfect for:

  • Automated attendance without manual roll calls in schools and universities
  • Training Programs and Workshops: Simple Ways to Monitor Employee Presence
  • RFID-enabled rapid check-ins for seminars and events
  • Future enhancements could include syncing with cloud databases, enabling online data logging to Google Sheets and other platforms or integrating Wi-Fi access with the Arduino Uno R4 Wi-Fi built-in module.

How This System Works

The Arduino Uno R4 Wi-Fi initializes the LCD and RFID module when it is turned on. The active attendance window is indicated by the system starting a 10 minute countdown timer.

Here is a detailed explanation of how the system works:

1. System Initialization: "Ready for Attendance" is the greeting that appears on the LCD when the system is powered on. At the beginning of the session, the Arduino logs the current time.

2. RFID Tag Scanning: The Arduino compares the Unique Identifier (UID) that the RC522 module reads from a student's RFID card with a list of registered UIDs that has been stored.

3. Update on Attendance Status:

  • The student is marked as "Present – On Time" by the system if the card is scanned within ten minutes.
  • "Present – Late" is recorded if the scan is done after ten minutes.
  • Once the teacher's card has been scanned, students who do not scan are immediately declared absent.

4. Teacher Summary Card: The attendance summary is activated by the teacher's RFID card. The LCD screen successively displays each student's name and attendance status (absent, late, or on time).

5. Wi-Fi Extension (Optional): Real-time remote attendance monitoring is made possible by the Arduino Uno R4 Wi-Fi, which allows data to be subsequently transmitted to cloud servers, online databases, or even Google Sheets.

By doing away with the inconvenience of manual attendance sheets, this solution guarantees accuracy, transparency, and efficiency.

Taking the Project to the Next Level - With JUSTWAY

Even while your Arduino attendance system functions flawlessly on a breadboard, it might not seem professional when you show it off at investor demos, tech fairs, or competitions.

Presentation is important, and JUSTWAY helps with that.

JUSTWAY assists you in turning your do it yourself project into a high-quality prototype that feels and looks like genuine product that is ready for the market.

Why JUSTWAY is the Perfect

Rapid Prototyping

  • 24 hour production tracking
  • Real-time production tracking
  • Perfect for students and makers on tight deadlines

CNC Machining (Aluminum 6061 / Stainless Steel 304)

  • Delivers ultra-precise, strong enclosures
  • Gives your project a premium industrial-grade body

Sheet Metal Fabrication

  • Laser-cut and CNC-bent metal sheets
  • Options for powder coating finishes
  • Ideal for casting your attendance system elegantly

Injection Molding

  • Transition from prototypes to mass production
  • High-quality, custom-designed plastic enclosures

Urethane Casting

  • Perfect for...
Read more »

  • 1 × Arduino UNO R4 Wi-Fi he most recent Arduino with improved processing performance and integrated Wi-Fi. Offers ease of extension, increased speed, and stability for upcoming IoT integration.
  • 1 × MFRC522 RFID Module Uses SPI connection to find and read the UIDs on RFID cards. Provides a quick and economical method of identifying unique cards.
  • 1 × RFID Tags Each stands for a different student's ID. Easy, long-lasting, and reusable identity technique
  • 1 × 20x4 I2C LCD Shows real-time timer updates, messages, and student names. Reliability is increased and wiring complexity complexity is decreased with the I2C interface.
  • 1 × Jumper Wires Securely joins all parts, guarantees steady signal flow without the need for soldering.

  • 1
    Step 1: Circuit Connections

    Connect The MFRC522 RFID Module to Arduino Uno R4 Wi-Fi

    • SDA To D10
    • SCK To D13
    • MOSI To D11
    • MISO To D12
    • RST To D9
    • 3.3v To 3.3v
    • GND To GND

    Connect the 20x4 I2C LCD Display

    • SDA To A4
    • SCL To A5
    • VCC To 5v
    • GND To GND
  • 2
    Step 2: Upload The Code

    Upload your code using the Arduino IDE. Make sure the libraries are installed :

    • MFRC522.h
    • LiquidCrystal.h.
     #include <wire.h> #include <spi.h> #include <mfrc522.h> #include <liquidcrystal_i2c.h> #define SS_PIN 10 // SDA/SS for RC522 #define RST_PIN 9 // RST for RC522 #define LCD_ADDR 0x27 #define LCD_COLS 20 #define LCD_ROWS 4 MFRC522 rfid(SS_PIN, RST_PIN); LiquidCrystal_I2C lcd(LCD_ADDR, LCD_COLS, LCD_ROWS); // teacher UID (uppercase, no spaces) const char TEACHER_UID[] = "2A7E17B1"; // 10 minutes = 10 * 60 * 1000 milliseconds const unsigned long ATTENDANCE_LENGTH = 10UL * 60UL * 1000UL; // debounce time to avoid reading same card many times quickly const unsigned long DEBOUNCE = 1000UL; // how long to show a student's info (ms) const unsigned long SHOW_MS = 1500UL; // small refresh rate for live timer (ms) const unsigned long REFRESH_MS = 500UL; // --- Student UID list and matching names --- // Duplicate UID removed — ensure all UIDs here are unique (uppercase, no spaces) const char* uids[] = { "E2D2D500", "49F1DF00", "5C55D500", "827ED600", "310AF400", "D7CFE000", "23370EAA", "7EB6F300", "D784D500" }; const char* names[] = { "Amanjeet Kaur", "Siddharth Verma", "Meera Patel", "Arjun Khanna", "Neha Rathi", "Vikram Singh", "Simran Kaur", "Ritik Sharma", "Kavya Menon" }; const int NUM = sizeof(uids) / sizeof(uids[0]); // attendance state: 0=absent, 1=on time, 2=late uint8_t attendance[NUM]; // timing vars unsigned long startTime = 0; bool windowStarted = false; // helpers for debounce and display refresh String lastUID = ""; unsigned long lastUIDTime = 0; unsigned long lastRefresh = 0; void setup() { Serial.begin(9600); while (!Serial) { } // waits for Serial on some boards, harmless on UNO/R4 SPI.begin(); rfid.PCD_Init(); lcd.init(); lcd.backlight(); lcd.clear(); // welcome message lcd.setCursor(0, 0); lcd.print("Welcome to the"); lcd.setCursor(0, 1); lcd.print("RFID attendance"); lcd.setCursor(0, 2); lcd.print("system"); delay(2000); // start attendance window now lcd.clear(); lcd.setCursor(0,0); lcd.print("Ready for attendance"); startTime = millis(); windowStarted = true; // mark everyone absent initially for (int i = 0; i < NUM; i++) attendance[i] = 0; // show initial timer immediately updateTimerOnLCD(); Serial.println("Attendance started."); } void loop() { unsigned long now = millis(); // update the live countdown at intervals if (now - lastRefresh >= REFRESH_MS) { updateTimerOnLCD(); lastRefresh = now; } // check for a new card if (!rfid.PICC_IsNewCardPresent()) return; if (!rfid.PICC_ReadCardSerial()) return; // build UID string (HEX uppercase, no spaces) String uid = ""; for (byte i = 0; i < rfid.uid.size; i++) { if (rfid.uid.uidByte[i] < 0x10) uid += "0"; uid += String(rfid.uid.uidByte[i], HEX); } uid.toUpperCase(); // simple debounce: ignore if same card scanned within DEBOUNCE ms if (uid == lastUID && (now - lastUIDTime) < DEBOUNCE) { rfid.PICC_HaltA(); rfid.PCD_StopCrypto1(); return; } lastUID = uid; lastUIDTime = now; Serial.print("Card scanned: "); Serial.println(uid); // teacher card -> show summary of all students if (uid == String(TEACHER_UID)) { showSummary(); rfid.PICC_HaltA(); rfid.PCD_StopCrypto1(); updateTimerOnLCD(); return; } // find student index int idx = findIndex(uid.c_str()); if (idx < 0) { // unknown card lcd.clear(); lcd.setCursor(0,0); lcd.print("Unknown card:"); lcd.setCursor(0,1); lcd.print(uid); lcd.setCursor(0,3); lcd.print("Not registered"); Serial.println("Unknown UID - not registered."); delay(SHOW_MS); updateTimerOnLCD(); rfid.PICC_HaltA(); rfid.PCD_StopCrypto1(); return; } // if already marked, just display status again if (attendance[idx] != 0) { showStudent(idx); delay(SHOW_MS); updateTimerOnLCD(); rfid.PICC_HaltA(); rfid.PCD_StopCrypto1(); return; } // determine if scan is inside the attendance window bool onTime = windowStarted && ((now - startTime) <= ATTENDANCE_LENGTH); if (onTime) attendance[idx] = 1; // on time else attendance[idx] = 2; // late // show student info showStudent(idx); delay(SHOW_MS); updateTimerOnLCD(); rfid.PICC_HaltA(); rfid.PCD_StopCrypto1(); } // find index of uid in uids[]; return -1 if not found int findIndex(const char* uid) { for (int i = 0; i < NUM; i++) { if (strcmp(uids[i], uid) == 0) return i; } return -1; } // show ready screen and live remaining time void updateTimerOnLCD() { lcd.clear(); lcd.setCursor(0,0); lcd.print("Ready for attendance"); if (windowStarted) { long elapsed = (long)(millis() - startTime); long remaining = (long)ATTENDANCE_LENGTH - elapsed; if (remaining > 0) { unsigned long seconds = remaining / 1000UL; unsigned int mins = seconds / 60UL; unsigned int secs = seconds % 60UL; lcd.setCursor(0,1); // print "Time left: mm:ss" with leading zero for seconds lcd.print("Time left: "); if (mins < 10) lcd.print('0'); lcd.print(mins); lcd.print(':'); if (secs < 10) lcd.print('0'); lcd.print(secs); } else { lcd.setCursor(0,1); lcd.print("Attendance closed"); } } else { lcd.setCursor(0,1); lcd.print("Window not set"); } // clear lower lines for neatness lcd.setCursor(0,2); lcd.print(" "); lcd.setCursor(0,3); lcd.print(" "); } // show one student's info on LCD void showStudent(int i) { lcd.clear(); lcd.setCursor(0,0); lcd.print(names[i]); // name lcd.setCursor(0,1); lcd.print("Present"); lcd.setCursor(0,2); if (attendance[i] == 1) { lcd.print("ON time"); Serial.print(names[i]); Serial.println(" -> ON time"); } else { lcd.print("Came late"); Serial.print(names[i]); Serial.println(" -> Came late"); } } // show one-by-one summary for teacher (Name + Present/Absent + On time/ Late) void showSummary() { for (int i = 0; i < NUM; i++) { lcd.clear(); lcd.setCursor(0,0); lcd.print(names[i]); if (attendance[i] == 0) { lcd.setCursor(0,1); lcd.print("Absent"); Serial.print(names[i]); Serial.println(": Absent"); } else if (attendance[i] == 1) { lcd.setCursor(0,1); lcd.print("Present"); lcd.setCursor(0,2); lcd.print("ON time"); Serial.print(names[i]); Serial.println(": Present (ON time)"); } else { lcd.setCursor(0,1); lcd.print("Present"); lcd.setCursor(0,2); lcd.print("Late"); Serial.print(names[i]); Serial.println(": Present (Late)"); } delay(2500); // pause 2.5 seconds per student } }
  • 3
    Step 3: Register Your RFID Tags

    An RFID tag is given to every pupil. in the code, update their names and UIDs

View all 5 instructions

Enjoy this project?

Share

Discussions

Does this project spark your interest?

Become a member to follow this project and never miss any updates