Master RFID Technology with Arduino
Learn how to build your own RFID-based inventory management system from scratch
What is RFID Technology?
Key Components of RFID Systems
- 1. RFID Tags (Transponders) - Contains a microchip and antenna - Stores unique identification data - Available in various form factors (cards, key fobs, stickers)
- 2. RFID Reader (Interrogator) - Emits radio waves to communicate with tags - Decodes information from tags - Interfaces with host systems
- 3. Antenna - Transmits and receives radio signals - Determines read range and coverage area
- 4. Backend Software - Processes collected data - Manages database operations - Provides user interface
Types of RFID Systems
- Passive RFID: No internal power source; powered by reader's electromagnetic field. Range: 10cm - 1m. Cost: Low ($0.10-$1 per tag)
- Active RFID: Battery-powered tags with longer range. Range: Up to 100m. Cost: Higher ($5-$100 per tag)
- Semi-Passive RFID: Battery assists chip operation but not transmission. Range: 10-30m. Cost: Medium ($1-$10 per tag)
RFID Frequency Bands
| Frequency | Range | Applications | Data Rate |
|---|---|---|---|
| LF (125-134 kHz) | 10 cm | Animal tracking, access control | Low |
| HF (13.56 MHz) | 10 cm - 1 m | Payment cards, ticketing | Medium |
| UHF (860-960 MHz) | 1 - 12 m | Supply chain, inventory | High |
Types of RFID Systems
Real-World Applications of RFID
📦 Inventory Management
Track products in warehouses, automate stock counting, reduce human errors
🏢 Access Control
Secure building entry, employee attendance tracking, parking management
💳 Contactless Payment
Credit cards, mobile payments, transit cards, toll collection
🏥 Healthcare
Patient tracking, medication management, equipment monitoring
Building Your First RFID Project with Arduino
Project Overview: Smart Inventory Management System
Today, we'll build a complete RFID-based inventory management system that can:
- Read and identify RFID tags
- Store product information
- Track items in/out
- Provide visual and audio feedback
- Connect to a PC application for data management
Required Components
- 1× Arduino Nano (or any Arduino board)
- 1× MFRC522 RFID Module (13.56 MHz)
- 2× RFID Tags (cards or key fobs)
- 1× RGB LED (cathode)
- 1× Piezo Buzzer
- 3× 220Ω Resistors
- 1× Breadboard
- Jumper wires
- USB cable for Arduino
MFRC522 Specifications
- Operating Frequency: 13.56 MHz
- Supply Voltage: 3.3V (Important: Do NOT connect to 5V!)
- Communication: SPI, I2C, UART
- Read Range: 0-60mm (depending on antenna)
- Data Transfer Rate:** Max 424 kbit/s
- Supported Card Types:** MIFARE Classic, MIFARE Ultralight
Wiring the MFRC522 to Arduino Nano
| MFRC522 Pin | Arduino Nano Pin | Description |
|---|---|---|
| VCC | 3.3V | Power supply (3.3V ONLY!) |
| RST | D9 | Reset and power-down |
| GND | GND | Ground |
| IRQ | Not connected | Interrupt pin (optional) |
| MISO | D12 | Master In Slave Out |
| MOSI | D11 | Master Out Slave In |
| SCK | D13 | Serial Clock |
| SDA/SS | D10 | Slave Select |
RGB LED Connections:
Green Pin: Arduino D5 (through 220Ω resistor)
Blue Pin: Arduino D4 (through 220Ω resistor)
Cathode: GND
Buzzer Connection:
Negative Pin: GND
Launch the Arduino IDE on your computer (version 1.8.0 or higher recommended)
Go to Tools → Manage Libraries... (or press Ctrl+Shift+I)
Search for "MFRC522" by GithubCommunity and click Install
#include
#include
// Pin Definitions
#define SS_PIN 10 // SDA/SS pin
#define RST_PIN 9 // Reset pin
#define RED_LED 6 // Red LED pin
#define GREEN_LED 5 // Green LED pin
#define BLUE_LED 4 // Blue LED pin
#define BUZZER_PIN 3 // Buzzer pin
// Create MFRC522 instance
MFRC522 rfid(SS_PIN, RST_PIN);
// Variables for storing card data
String tagUID = "";
String authorizedUIDs[] = {"43 7C A3 A9", "B3 C7 42 1A"}; // Add your card UIDs here
int totalAuthorizedCards = 2;
// System states
bool accessGranted = false;
unsigned long lastReadTime = 0;
const unsigned long readDelay = 2000; // 2 seconds between reads
void setup() {
// Initialize Serial Communication
Serial.begin(9600);
while (!Serial); // Wait for Serial Monitor to open
Serial.println("=================================");
Serial.println("RFID Inventory Management System");
Serial.println("=================================");
Serial.println("Initializing system...");
// Initialize SPI bus
SPI.begin();
// Initialize MFRC522
rfid.PCD_Init();
// Check if RFID reader is connected
if (rfid.PCD_PerformSelfTest()) {
Serial.println("✓ RFID Reader detected and working!");
} else {
Serial.println("✗ RFID Reader not found. Check connections!");
while(1); // Stop if reader not found
}
// Initialize outputs
pinMode(RED_LED, OUTPUT);
pinMode(GREEN_LED, OUTPUT);
pinMode(BLUE_LED, OUTPUT);
pinMode(BUZZER_PIN, OUTPUT);
// Test indicators
startupSequence();
Serial.println("✓ System ready!");
Serial.println("Place your RFID card near the reader...\n");
// Set default LED state (blue = ready)
setLEDColor(0, 0, 255);
}
void loop() {
// Check if enough time has passed since last read
if (millis() - lastReadTime < readDelay) {
return;
}
// Look for new cards
if (!rfid.PICC_IsNewCardPresent()) {
return;
}
// Select one of the cards
if (!rfid.PICC_ReadCardSerial()) {
return;
}
// Process the card
lastReadTime = millis();
tagUID = getTagUID();
Serial.println("=================================");
Serial.print("Card Detected! UID: ");
Serial.println(tagUID);
// Check if card is authorized
if (isAuthorized(tagUID)) {
grantAccess();
} else {
denyAccess();
}
// Additional card information
displayCardInfo();
// Halt PICC
rfid.PICC_HaltA();
// Stop encryption on PCD
rfid.PCD_StopCrypto1();
// Reset LED to ready state after delay
delay(1500);
setLEDColor(0, 0, 255); // Blue = ready
}
// Function to get tag UID as string
String getTagUID() {
String uid = "";
for (byte i = 0; i < rfid.uid.size; i++) {
uid += String(rfid.uid.uidByte[i] < 0x10 ? "0" : "");
uid += String(rfid.uid.uidByte[i], HEX);
if (i < rfid.uid.size - 1) uid += " ";
}
uid.toUpperCase();
return uid;
}
// Check if tag is authorized
bool isAuthorized(String uid) {
for (int i = 0; i < totalAuthorizedCards; i++) {
if (uid == authorizedUIDs[i]) {
return true;
}
}
return false;
}
// Grant access sequence
void grantAccess() {
Serial.println("✓ ACCESS GRANTED!");
Serial.println("Welcome! This card is authorized.");
// Visual feedback - Green LED
setLEDColor(0, 255, 0);
// Audio feedback - Success tone
tone(BUZZER_PIN, 1000, 200);
delay(250);
tone(BUZZER_PIN, 1500, 200);
// Log the access
logAccess(tagUID, true);
}
// Deny access sequence
void denyAccess() {
Serial.println("✗ ACCESS DENIED!");
Serial.println("This card is not authorized.");
// Visual feedback - Red LED
setLEDColor(255, 0, 0);
// Audio feedback - Error tone
for (int i = 0; i < 3; i++) {
tone(BUZZER_PIN, 300, 100);
delay(150);
}
// Log the attempt
logAccess(tagUID, false);
}
// Display detailed card information
void displayCardInfo() {
Serial.println("\n--- Card Information ---");
// Card UID
Serial.print("UID (HEX): ");
Serial.println(tagUID);
// Card UID in decimal
Serial.print("UID (DEC): ");
for (byte i = 0; i < rfid.uid.size; i++) {
Serial.print(rfid.uid.uidByte[i]);
if (i < rfid.uid.size - 1) Serial.print(", ");
}
Serial.println();
// Card type
MFRC522::PICC_Type piccType = rfid.PICC_GetType(rfid.uid.sak);
Serial.print("Card Type: ");
Serial.println(rfid.PICC_GetTypeName(piccType));
// Memory size (for Mifare Classic)
if (piccType == MFRC522::PICC_TYPE_MIFARE_1K) {
Serial.println("Memory Size: 1KB (16 sectors × 4 blocks × 16 bytes)");
} else if (piccType == MFRC522::PICC_TYPE_MIFARE_4K) {
Serial.println("Memory Size: 4KB");
}
Serial.println("------------------------\n");
}
// Log access attempts
void logAccess(String uid, bool granted) {
Serial.print("[LOG] ");
Serial.print(millis() / 1000); // Time in seconds
Serial.print("s - UID: ");
Serial.print(uid);
Serial.print(" - Status: ");
Serial.println(granted ? "GRANTED" : "DENIED");
}
// Set RGB LED color
void setLEDColor(int red, int green, int blue) {
// For common cathode RGB LED
analogWrite(RED_LED, red);
analogWrite(GREEN_LED, green);
analogWrite(BLUE_LED, blue);
}
// Startup sequence for testing
void startupSequence() {
Serial.println("Testing indicators...");
// Test each LED color
Serial.print("Testing RED LED... ");
setLEDColor(255, 0, 0);
delay(500);
Serial.println("OK");
Serial.print("Testing GREEN LED... ");
setLEDColor(0, 255, 0);
delay(500);
Serial.println("OK");
Serial.print("Testing BLUE LED... ");
setLEDColor(0, 0, 255);
delay(500);
Serial.println("OK");
// Test buzzer
Serial.print("Testing Buzzer... ");
tone(BUZZER_PIN, 1000, 100);
delay(150);
tone(BUZZER_PIN, 1500, 100);
Serial.println("OK");
// Turn off all
setLEDColor(0, 0, 0);
delay(500);
}
// Function to write data to card (Advanced)
void writeToCard(byte sector, byte blockAddr, byte* data) {
// This is an advanced function for writing data to RFID cards
// Use with caution as incorrect usage can damage the card
MFRC522::StatusCode status;
byte trailerBlock = sector * 4 + 3; // Trailer block for the sector
MFRC522::MIFARE_Key key;
// Using default key (all 0xFF)
for (byte i = 0; i < 6; i++) {
key.keyByte[i] = 0xFF;
}
// Authenticate
status = rfid.PCD_Authenticate(MFRC522::PICC_CMD_MF_AUTH_KEY_A,
trailerBlock, &key, &(rfid.uid));
if (status != MFRC522::STATUS_OK) {
Serial.print("Authentication failed: ");
Serial.println(rfid.GetStatusCodeName(status));
return;
}
// Write data
status = rfid.MIFARE_Write(blockAddr, data, 16);
if (status != MFRC522::STATUS_OK) {
Serial.print("Write failed: ");
Serial.println(rfid.GetStatusCodeName(status));
} else {
Serial.println("Data written successfully!");
}
}
## Understanding the Code
### Key Functions Explained
1. Setup Function
Initializes all components, performs self-test, and prepares the system for operation. The startup sequence tests each component to ensure everything is working correctly.
2. Main Loop
Continuously checks for new RFID cards. When detected, it reads the UID, checks authorization, and provides appropriate feedback through LEDs and buzzer.
3. Authorization System
Compares detected card UID with a list of authorized UIDs. You can easily add or remove authorized cards by modifying the authorizedUIDs[] array.
4. Feedback System
Provides both visual (RGB LED) and audio (buzzer) feedback. Green indicates success, red indicates failure, and blue indicates ready state.
- Upload the Code: Connect Arduino to your computer and upload the code
- Open Serial Monitor: Set baud rate to 9600 and watch the initialization process
- Test with RFID Card: Place an RFID card near the reader (within 1-2 cm)
- Note the UID: Copy the UID displayed in Serial Monitor
- Add to Authorized List: Add the UID to the
authorizedUIDs[]array and re-upload - Test Authorization: Try both authorized and unauthorized cards
Writing Product Information to Card
void storeProductInfo(String productID, String productName, float price) {
byte dataBlock[16];
// Format: [ID:4bytes][Name:8bytes][Price:4bytes]
// Convert and store data in byte array
// Example: Store product ID
for (int i = 0; i < 4; i++) {
if (i < productID.length()) {
dataBlock[i] = productID[i];
} else {
dataBlock[i] = 0x00;
}
}
// Write to sector 1, block 4
writeToCard(1, 4, dataBlock);
}
```
### Feature 2: PC Communication Protocol
For inventory management, we need to communicate with a PC application:
void sendToPC(String command, String data) {
// Protocol:
Serial.print("<");
Serial.print(command);
Serial.print(":");
Serial.print(data);
Serial.println(">");
}
// Usage examples:
// sendToPC("CARD_READ", tagUID);
// sendToPC("ACCESS", "GRANTED");
// sendToPC("INVENTORY", "ITEM_IN");
```
Building the PC Application
Creating the Inventory Management Software
While the Arduino handles the hardware interface, we need a PC application to manage the inventory database. Here's a simple C# implementation structure:
C# Application Components
// Main components needed:
// 1. Serial Communication Handler
// 2. Database Manager (SQLite recommended for simplicity)
// 3. User Interface (Windows Forms or WPF)
// 4. Reporting Module
public class RFIDInventorySystem
{
private SerialPort arduinoPort;
private SQLiteConnection database;
public void Initialize()
{
// Setup serial communication
arduinoPort = new SerialPort("COM3", 9600);
arduinoPort.DataReceived += ProcessRFIDData;
// Initialize database
InitializeDatabase();
}
private void ProcessRFIDData(object sender, SerialDataReceivedEventArgs e)
{
string data = arduinoPort.ReadLine();
// Parse protocol:
// Update inventory based on command
}
}
## Extending Your Project
🚪 Door Lock System
Add a relay module to control an electronic door lock
📊 LCD Display
Add an I2C LCD to show card information without PC
📱 IoT Integration
Use ESP8266/ESP32 to send data to cloud database
⏰ Time Attendance
Add RTC module for employee attendance tracking
Important Security Notes
- Default Keys:Most MIFARE cards use default keys (0xFFFFFFFFFFFF). Change these for production use!
- UID Cloning: UIDs can be cloned. For high-security applications, use encrypted sectors and rolling codes.
- Communication Security: Serial communication is unencrypted. For production, implement encryption between Arduino and PC.
- Physical Security: RFID readers should be in secure enclosures to prevent tampering.
Performance Optimization Tips
- Reduce Read Delay:** Adjust `readDelay` variable based on your needs
- Optimize Memory:** Use PROGMEM for storing constant strings
- Batch Processing:** Read multiple cards before sending data to PC
- Power Management:** Implement sleep modes when not actively reading
| Card Type | Memory | Security | Cost | Use Case |
|---|---|---|---|---|
| MIFARE Classic 1K | 1KB | Basic | $0.30 | Access control, transit |
| MIFARE Classic 4K | 4KB | Basic | $0.50 | Multiple applications |
| MIFARE Ultralight | 64B | Low | $0.20 | Tickets, tags |
| MIFARE DESFire | 2/4/8KB | High | $2.00 | High security, payment |
Conclusion
Congratulations! You've successfully built an RFID-based inventory management system. This project demonstrates fundamental concepts of RFID technology, embedded systems programming, and serial communication. With this foundation, you can expand into more complex applications like automated warehouses, smart retail systems, or IoT-enabled tracking solutions. Remember to experiment with different features and share your innovations with the community!
0 comments:
Post a Comment