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.
1. Arduino UNO R4 Wi-Fi: The most recent Arduino with improved processing performance and integrated Wi-Fi. Offers ease of extension, increased speed, and stability for upcoming IoT integration.
2. 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.
3. RFID Tags: Each stands for a different student's ID. Easy, long-lasting, and reusable identity technique.
4. 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.
5. Jumper Wires: Securely joins all parts, guarantees steady signal flow without the need for soldering.
How This System WorksThe 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.
Steps to Build the ProjectStep 1: Circuit ConnectionsConnect 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
Upload your code using the Arduino IDE. Make sure the libraries are installed :
- MFRC522.h
- LiquidCrystal.h.
/* Beginner-friendly RFID Attendance (RC522 + 20x4 I2C LCD)
For Arduino Uno R4 Wi-Fi (pinout same as UNO-compatible boards)
Wiring (Arduino UNO/R4):
RC522: SDA(SS)=D10, SCK=D13, MOSI=D11, MISO=D12, RST=D9, 3.3V, GND
I2C LCD: SDA=A4, SCL=A5, VCC=5V, GND=GND
Changes in this version:
- Removed duplicate UID entry.
- Updated student names list to new names.
*/
#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
}
}
Step 3: Register Your RFID TagsAn RFID tag is given to every pupil. in the code, update their names and UIDs
Step 4: Power On and Start AttendanceThe system starts the 10-minutes timer as soon as it is powered on. During this period, scan the cards to receive the sticker "On Time". The appropriate labels are applied to late scans.
Step 5: View SummaryTo get a thorough attendance summary of every student on the LCD screen, use the teacher's card.
Taking the Project to the Next Level - With JUSTWAYEven 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 PerfectRapid 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 low-volume production runs
- Delivers professional-grade parts for display models
3D Printing (SLA & HPA-PA12)
- SLA Resin: clear, aesthetic display for internal electronics
- HP-PA12 Nylon: durable and long lasting casting
Pro Tip: Transparent resin highlights your circuitry; matte black adds a stealthy, modern touch.
How To Order in 4 Easy StepsStep 1 Upload Your CAD Files at JUSTWAY.comStart by uploading your STL or STEP files
Choose from plastics, resins, or metals depending on your design.
Live dimension check ensure perfect fitting before production
Transparent pricing, fast delivery, and zero hidden costs.
The Arduino Uno R4 Wi-Fi based RFID Attendance System is powerful demonstration of how automation and IoT can simplify daily administrative tasks. By integrating RFID technology, LCD visualization, and time-based logic, this system ensures accurate, tamper proof attendance tracking. With JUSTWAY, you can elevate this project from a prototype to a professional-grade product, combining functionality, design, and durability. Whether for school, exhibitions, or startups - this system is your gateway to real-world innovation.
Comments