Friday, 23 May 2025

🎯 Build Your Own RFID Attendance System Using Arduino + ESP32 + Google Sheets

 

🎯 Build Your Own RFID Attendance System Using Arduino + ESP32 + Google Sheets

📅 By Dinesh | Tech DIY Projects | May 2025




 

 

🚀 Introduction

Have you ever wanted to build a smart attendance system that logs student or staff attendance directly into Google Sheets in real time?

In this tutorial, I’ll show you how I created a WiFi-connected RFID attendance system using:

  • ✅ Arduino UNO (for RFID + DFPlayer)

  • ✅ ESP32 (for WiFi + Google Sheet logging)

  • ✅ Google Apps Script (to act as a cloud database)

Let’s dive in!


🧠 Project Concept

Here’s how the system works:

  1. User scans an RFID card.

  2. Arduino detects the card, plays a welcome sound using DFPlayer, and sends the name to ESP32.

  3. ESP32 receives the name via serial and logs it to a Google Sheet using a webhook.

  4. Done! The name and timestamp are saved in the cloud.


🧰 Components Used

Component
Quantity
Arduino UNO
1
ESP32 (DevKit v1)
1
MFRC522 RFID Reader
1
RFID Tags/Cards
2+
DFPlayer Mini + Speaker
1
I2C LCD 16x2 Display
1
Jumper Wires
-
Voltage Regulator (if needed for 3.3V logic level)
1
Breadboard
1

🔌 Connections

RFID & DFPlayer to Arduino UNO:

  • RFID SDA → D10

  • RFID RST → D9

  • DFPlayer TX → D4

  • DFPlayer RX → D5

  • LCD I2C → A4 (SDA), A5 (SCL)

Arduino to ESP32:

  • Arduino TX (D1) → ESP32 RX (GPIO 16)

  • IMPORTANT: Use voltage divider or level shifter to avoid 5V-to-3.3V damage to ESP32.


📟 Arduino Code

The Arduino reads the card, displays info, and plays sound:

cpp
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <SoftwareSerial.h>
#include <DFRobotDFPlayerMini.h>
#include <SPI.h>
#include <MFRC522.h>

// LCD I2C
LiquidCrystal_I2C lcd(0x27, 16, 2); // Adjust address if needed

// DFPlayer Mini on pins 4 (RX), 5 (TX) Arduino side
SoftwareSerial dfSerial(4, 5);
DFRobotDFPlayerMini myDFPlayer;

// RFID pins
#define RST_PIN 9
#define SS_PIN 10
MFRC522 rfid(SS_PIN, RST_PIN);

// DFPlayer Reset pin (optional)
#define DFPLAYER_RESET_PIN 8

// Known RFID UIDs and names
String knownUIDs[] = {
  "EA514D63"
};
String names[] = {
  "Dinesh"
};

// Retry DFPlayer initialization
bool initDFPlayer() {
  for (int i = 0; i < 5; i++) {
    if (myDFPlayer.begin(dfSerial)) {
      return true;
    }
    delay(1000); // Wait 1 sec before retry
  }
  return false;
}

void setup() {
  delay(3000); // Let power stabilize

  pinMode(DFPLAYER_RESET_PIN, OUTPUT);
  digitalWrite(DFPLAYER_RESET_PIN, LOW);  // Hold DFPlayer in reset
  delay(100);  // Reset pulse
  digitalWrite(DFPLAYER_RESET_PIN, HIGH); // Release reset
  delay(1000); // Wait for DFPlayer to boot

  Serial.begin(9600);   // Serial to ESP32
  dfSerial.begin(9600); // DFPlayer serial
  SPI.begin();
  rfid.PCD_Init();

  lcd.init();
  lcd.backlight();
  lcd.setCursor(0, 0);
  lcd.print("Scan your ID...");

  if (!initDFPlayer()) {
    lcd.setCursor(0, 1);
    lcd.print("DFPlayer Error");
    Serial.println("Unable to initialize DFPlayer Mini!");
    while (true); // Halt
  }

  myDFPlayer.volume(30); // Set volume (0-30)
}

void loop() {
  if (!rfid.PICC_IsNewCardPresent() || !rfid.PICC_ReadCardSerial()) {
    return;
  }

  // Read UID and convert to uppercase hex string
  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();
  Serial.println("UID: " + uid);

  bool matchFound = false;
  for (int i = 0; i < 6; i++) {
    if (uid == knownUIDs[i]) {
      lcd.clear();
      lcd.setCursor(0, 0);
      lcd.print("Welcome,");
      lcd.setCursor(0, 1);
      lcd.print(names[i]);
      Serial.println("Attendance marked for " + names[i]);

      // Send matched UID and name to ESP32
      Serial.print("MATCH:");
      Serial.print(uid);
      Serial.print(",");
      Serial.println(names[i]);

      myDFPlayer.play(1); // Play welcome sound
      matchFound = true;
      break;
    }
  }

  if (!matchFound) {
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("Unknown card");
    Serial.println("Unknown UID");

    // Send unknown info to ESP32
    Serial.println("UNKNOWN");

    myDFPlayer.play(2); // Play error sound (optional)
  }

  delay(3000); // Wait before next scan
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("Scan your ID...");
}

📡 ESP32 Code (Receives & Sends to Google Sheet)

cpp
#include <WiFi.h>
#include <HTTPClient.h>

#define RXD2 16  // Arduino TX to ESP32 RX
#define TXD2 17  // Not used, but required for Serial2 init

const char* ssid = "*****";         // 🔁 Replace with your WiFi SSID
const char* password = "****";       // 🔁 Replace with your WiFi password

const char* serverName = "*****"; // 🔁 Replace with excelsheet link

void setup() {
  Serial.begin(115200);
  Serial2.begin(9600, SERIAL_8N1, RXD2, TXD2);  // Serial2 from Arduino

  Serial.println("Connecting to WiFi...");
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }

  Serial.println("\nWiFi connected!");
}

void loop() {
  if (Serial2.available()) {
    String name = Serial2.readStringUntil('\n');
    name.trim(); // Remove leading/trailing whitespace

    Serial.println("Received from Arduino: " + name);

    // Remove "MATCH:" prefix if present
    if (name.startsWith("MATCH:")) {
      name = name.substring(6);
    }

    // Remove everything before the first comma, including the comma
    int commaIndex = name.indexOf(',');
    if (commaIndex != -1) {
      name = name.substring(commaIndex + 1);
    }

    Serial.println("Cleaned name: " + name);

    if (WiFi.status() == WL_CONNECTED) {
      HTTPClient http;

      String url = String(serverName) + name;
      http.begin(url);
      int httpResponseCode = http.GET();

      if (httpResponseCode > 0) {
        Serial.println("Data sent to Google Sheet!");
      } else {
        Serial.print("Error sending data: ");
        Serial.println(httpResponseCode);
      }

      http.end();
    } else {
      Serial.println("WiFi disconnected!");
    }
  }
}


🎉 Final Result

✅ RFID card scanned
✅ Welcome message on LCD
✅ Sound plays via DFPlayer
✅ Name logged in Google Sheet

No need for SD cards or Excel files — everything is real-time in the cloud 🌐.


❤️ Let’s Connect

Have doubts or want to build your own version?

📧 Contact me on: dtrendchannel@gmail.com






Friday, 9 May 2025

🌞 DIY Arduino Solar Tracker with Motor Control – Complete Guide

 

🌞 DIY Arduino Solar Tracker with Motor Control – Complete Guide



🔧 Overview:

This project uses Light Dependent Resistors (LDRs) to track the sun's position and adjust the orientation of a solar panel using two servo motors. Additionally, based on the sunlight intensity, it controls a motor using two buttons – ideal for automating a solar-powered device like a water pump.


🧰 Components Required:

Component
Quantity
Description
Arduino Uno
1
Microcontroller board
Servo Motor (SG90/MG90)
2
For horizontal and vertical rotation
LDR (Light Sensor)
5
For detecting sunlight intensity and direction
10kΩ Resistors
5
Pull-down resistors for each LDR
Push Buttons
2
For controlling motor direction
DC Motor
1
Can be used for pumping or rotation purposes
NPN Transistor (optional)
1
For driving higher power motors
Diode (1N4007)
1
For back EMF protection
Power Supply (9V/12V)
1
To power the motor
      Breadboard + Jumper Wires                      As needed    For circuit connections

🔌 Pin Configuration:

Arduino PinConnected Component
A1LDR Top Left
A2LDR Top Right
A3LDR Bottom Left
A4LDR Bottom Right
A5LDR Middle Top (Sunlight Detection)
D5Horizontal Servo Signal
D6Vertical Servo Signal
D7Motor Control A
D8Motor Control B
D9Button 1 (Forward)
D10Button 2 (Reverse)
GNDAll GND connections
5VPower supply for LDRs and buttons

⚙️ How It Works:

  • LDRs detect light intensity. The 4 corner LDRs determine the direction of sunlight, and the middle LDR checks whether there is enough light.

  • The Arduino calculates the average light values and adjusts the horizontal and vertical servo angles accordingly.

  • If sunlight is detected and button 1 is pressed, the motor rotates in one direction.

  • If no sunlight is present and button 2 is pressed, the motor rotates in the opposite direction.

  • If neither condition is met, the motor stops.


🖼️ Circuit Diagram:

📟 Arduino Code:

#include <Servo.h>


Servo horizontal; // horizontal servo

Servo vertical; // vertical servo
// LDR analog pins
const int button1 = 9;
int pos = 0;
void setup() {
  pinMode(motorA, OUTPUT);
  delay(2500); // Give servos time to initialize
void loop() {
    int lt = analogRead(ldrlt);
    int avt = (lt + rt) / 2;
    if (abs(dvert) > tol) {
    if (abs(dhoriz) > tol) {
    delay(dtime);
    for (pos = oldvalue; pos <= 180; pos++) {
    buttonStateB = digitalRead(button2);


int servoh = 180;

int servohLimitHigh = 175;

int servohLimitLow = 5;



int servov = 0;

int servovLimitHigh = 60;

int servovLimitLow = 0;



int ldrlt = A1; // Top Left

int ldrrt = A2; // Top Right

int ldrld = A3; // Bottom Left

int ldrrd = A4; // Bottom Right

int ldrmt = A5; // Middle Top LDR



const int button2 = 10;

const int motorA = 7;

const int motorB = 8;

int buttonStateA = 0;

int buttonStateB = 0;



int pos2 = 0;

int oldvalue, oldvalue2;



  horizontal.attach(5);

  vertical.attach(6);

  horizontal.write(180);

  vertical.write(0);



  pinMode(motorB, OUTPUT);

  pinMode(button1, INPUT);

  pinMode(button2, INPUT);



}



  int ldrStatus = analogRead(ldrmt);

  

  if (ldrStatus > 30) {

    buttonStateA = digitalRead(button1);

    if (buttonStateA == LOW) {

      digitalWrite(motorA, HIGH);

      digitalWrite(motorB, LOW); // Motor rotates in one direction

    } else {

      digitalWrite(motorA, LOW);

      digitalWrite(motorB, LOW); // Stop motor

    }



    int rt = analogRead(ldrrt);

    int ld = analogRead(ldrld);

    int rd = analogRead(ldrrd);

    int dtime = 10;

    int tol = 90;



    int avd = (ld + rd) / 2;

    int avl = (lt + ld) / 2;

    int avr = (rt + rd) / 2;

    int dvert = avt - avd;

    int dhoriz = avl - avr;



      if (avt > avd) {

        servov++;

        if (servov > servovLimitHigh) servov = servovLimitHigh;

      } else {

        servov--;

        if (servov < servovLimitLow) servov = servovLimitLow;

      }

      vertical.write(servov);

    }



      if (avl > avr) {

        servoh--;

        if (servoh < servohLimitLow) servoh = servohLimitLow;

      } else {

        servoh++;

        if (servoh > servohLimitHigh) servoh = servohLimitHigh;

      }

      horizontal.write(servoh);

    }



  }

  else {

    oldvalue = horizontal.read();

    oldvalue2 = vertical.read();



      horizontal.write(pos);

      delay(15);

    }

    for (pos2 = oldvalue2; pos2 >= 0; pos2--) {

      vertical.write(pos2);

      delay(15);

    }



    if (buttonStateB == LOW) {

      digitalWrite(motorA, LOW);

      digitalWrite(motorB, HIGH); // Reverse motor

    } else {

      digitalWrite(motorA, LOW);

      digitalWrite(motorB, LOW);

    }

  }

}

🔔 DON’T FORGET TO SUBSCRIBE TO D TREND FOR MORE AWESOME PROJECTS AND TECH CONTENT! 🔔


Friday, 18 April 2025

🚗 Driver Drowsiness and Alcohol Detection System Using Arduino & GSM Module

🚗 Driver Drowsiness and Alcohol Detection System Using Arduino & GSM Module

Published on: April 18, 2025
Author: Dinesh | Learn with D Trend





Introduction

Road safety is a paramount concern in today's fast-paced world. Accidents resulting from driver fatigue and alcohol consumption are alarmingly common. To address this issue, I've developed a Driver Drowsiness and Alcohol Detection System using Arduino and a GSM module. This project aims to enhance vehicular safety by monitoring the driver's alertness and sobriety, providing real-time alerts, and taking preventive actions when necessary.


Objectives

  • Monitor Driver Alertness: Detect prolonged eye closure indicating drowsiness.

  • Detect Alcohol Consumption: Identify the presence of alcohol in the driver's breath.

  • Automated Alerts: Send SMS notifications to a predefined contact upon detection.

  • Preventive Measures: Disable the vehicle's motor to prevent potential accidents.


Components Required

Component Quantity Description
Arduino UNO 1 Microcontroller board
IR Sensor 1 Detects eye closure
MQ3 Alcohol Sensor 1 Detects alcohol levels in breath
SIM900A GSM Module 1 Sends SMS alerts
5V Relay Module 1 Controls motor operation
Buzzer 1 Provides audible alerts
Jumper Wires As needed For connections
Breadboard 1 For prototyping
Power Supply (5V) 1 Powers the circuit


Pin Configuration

Arduino Pin Connected Component
D2 IR Sensor Output
A0 MQ3 Sensor Analog Output
D8 Relay Module Input
D9 Buzzer
D10 GSM Module TX
D11 GSM Module RX


Block Diagram

[IR Sensor] [MQ3 Sensor]
| |
v v
[Arduino UNO] --- [GSM Module]
|
v
[Relay Module] --- [Motor]
|
v
[Buzzer]

Note: Ensure proper voltage level shifting for GSM module communication.


Working Principle

  1. Drowsiness Detection:

    • The IR sensor monitors the driver's eye.

    • If eyes remain closed for more than 5 seconds, the system identifies drowsiness.

    • The motor is disabled, a buzzer sounds, and an SMS alert is sent.

  2. Alcohol Detection:

    • The MQ3 sensor detects alcohol levels in the driver's breath.

    • If alcohol is detected above a certain threshold, the motor is disabled, a buzzer sounds, and an SMS alert is sent.

  3. System Reset:

    • After 10 seconds, the system resets, re-enabling the motor and resuming monitoring.


Arduino Code

#include <SoftwareSerial.h>

// Pin Definitions
#define IR_SENSOR 2
#define MQ3_PIN A0
#define RELAY_PIN 8
#define BUZZER_PIN 9
#define GSM_TX 10
#define GSM_RX 11
#define MOTOR_ON LOW
#define MOTOR_OFF HIGH
SoftwareSerial gsm(GSM_RX, GSM_TX);
unsigned long eyeClosedStart = 0;
bool eyeClosed = false;
bool motorRunning = true;
String phoneNumber = "+917824864485"; // Replace with your number
unsigned long lastMotorStopTime = 0;
bool resetTriggered = false;
void setup() {
pinMode(IR_SENSOR, INPUT);
pinMode(MQ3_PIN, INPUT);
pinMode(RELAY_PIN, OUTPUT);
pinMode(BUZZER_PIN, OUTPUT);
digitalWrite(RELAY_PIN, MOTOR_ON);
digitalWrite(BUZZER_PIN, LOW);
Serial.begin(9600);
gsm.begin(9600);
delay(3000);
sendSMS("System Ready. Motor is ON.");
}
void loop() {
if (resetTriggered && millis() - lastMotorStopTime > 10000) {
digitalWrite(RELAY_PIN, MOTOR_ON);
motorRunning = true;
resetTriggered = false;
Serial.println("Motor restarted after event.");
sendSMS("Motor Restarted. Stay Alert.");
}
int irValue = digitalRead(IR_SENSOR);
int alcoholValue = analogRead(MQ3_PIN);
Serial.print("IR: ");
Serial.print(irValue);
Serial.print(" | Alcohol: ");
Serial.println(alcoholValue);
if (alcoholValue > 400 && motorRunning) {
stopMotor("Alcohol Detected! Motor Stopped.");
}
if (irValue == 0) {
if (!eyeClosed) {
eyeClosedStart = millis();
eyeClosed = true;
} else if (millis() - eyeClosedStart > 5000 && motorRunning) {
stopMotor("Drowsiness Detected! Motor Stopped.");
}
} else {
eyeClosed = false;
}
delay(300);
}
void stopMotor(String message) {
digitalWrite(RELAY_PIN, MOTOR_OFF);
digitalWrite(BUZZER_PIN, HIGH);
motorRunning = false;
sendSMS(message);
delay(5000);
digitalWrite(BUZZER_PIN, LOW);
lastMotorStopTime = millis();
resetTriggered = true;
}
void sendSMS(String msg) {
gsm.println("AT");
delay(1000);
gsm.println("AT+CMGF=1");
delay(1000);
gsm.print("AT+CMGS=\"");
gsm.print(phoneNumber);
gsm.println("\"");
delay(1000);
gsm.println(msg);
delay(500);
gsm.write(26);
delay(5000);
}

Testing and Results

  • Drowsiness Simulation: Covered the IR sensor to simulate eye closure. After 5 seconds, the buzzer sounded, the motor stopped, and an SMS was received.

  • Alcohol Simulation: Introduced alcohol vapor near the MQ3 sensor. The system responded similarly, ensuring prompt alerts and motor shutdown.


Applications

  • Commercial Vehicles: Enhances safety in buses, trucks, and taxis.

  • Personal Vehicles: Provides an added layer of safety for individual drivers.

  • Fleet Management: Assists companies in monitoring driver behavior.


Future Enhancements

  • GPS Integration: To send location data along with SMS alerts.

  • Mobile App Interface: For real-time monitoring and control.

  • Data Logging: To maintain records of incidents for analysis.


Conclusion

Implementing a Driver Drowsiness and Alcohol Detection System can significantly reduce road accidents caused by human error. By leveraging simple electronic components and microcontroller programming, we can create effective safety solutions that are both affordable and reliable.


*For more projects and tutorials, stay tuned to "Learn with D Trend"

🧰 Components with Purchase Links (Affiliate-Ready)

ComponentDescriptionBuy Link (Amazon)
Arduino UNOThe brain of your project (microcontroller board)https://amzn.to/42jfRQF
IR Sensor ModuleUsed to detect the driver’s eye closurehttps://amzn.to/3RUsFH5
MQ3 Alcohol SensorDetects alcohol presence in the driver's breathhttps://amzn.to/4it8YRJ
SIM900A GSM ModuleSends SMS alerts to your phonehttps://amzn.to/4jjF5Vc
Relay Module (5V)Turns the motor ON/OFF based on detectionhttps://amzn.to/4jzTxsp
BuzzerAudible alert for drowsiness or alcohol detectionhttps://amzn.to/4cXBVEl
Jumper WiresConnects all the modules togetherhttps://amzn.to/3GuclKD
BreadboardHelps in prototyping the circuit easilyhttps://amzn.to/42Rftcm
12V Power SupplyPowers Arduino and GSM modulehttps://amzn.to/4lEd10g











 


🎯 Build Your Own RFID Attendance System Using Arduino + ESP32 + Google Sheets

  🎯 Build Your Own RFID Attendance System Using Arduino + ESP32 + Google Sheets 📅 By Dinesh | Tech DIY Projects | May 2025     🚀 Intro...