The RC522 RFID module is one of the most popular contactless communication devices used by hobbyists, students, and professionals across India. Whether you are building an attendance system, access control panel, or a smart inventory tracker, understanding how to read and write Mifare tags using the RC522 RFID library is an essential skill. In this comprehensive tutorial, we cover everything from wiring and library setup to reading UIDs, writing data blocks, and troubleshooting common issues.
Table of Contents
- What Is the RC522 RFID Module?
- Understanding Mifare Tags and Memory Layout
- Wiring the RC522 to Arduino
- Installing the MFRC522 Library
- Reading the UID from a Mifare Tag
- Writing Data to a Mifare Tag Block
- Real-World Project Ideas
- Frequently Asked Questions
What Is the RC522 RFID Module?
The RC522 is a highly integrated reader/writer IC designed by NXP Semiconductors for contactless communication at 13.56 MHz. It supports the ISO/IEC 14443 A standard, which is the foundation for Mifare Classic, Mifare Mini, Mifare Ultralight, and Mifare DESFire cards. The module communicates with a microcontroller over SPI (Serial Peripheral Interface), making it easy to connect to an Arduino Uno, Nano, or Mega.
Key features of the RC522 module include:
- Operating voltage: 3.3 V (logic-level tolerant up to 5 V with resistors)
- Communication interface: SPI up to 10 Mbit/s
- Integrated antenna with a typical read range of 0–50 mm
- Built-in CRC co-processor and 64-byte FIFO buffer
- Support for Mifare Classic 1K and 4K cards
The low cost, small footprint, and wide software support make the RC522 the go-to choice for beginners and professionals alike.
Understanding Mifare Tags and Memory Layout
Before writing any code, it helps to understand what is physically stored on a Mifare Classic 1K card. The card has 1024 bytes of EEPROM memory organized into 16 sectors, each containing 4 blocks of 16 bytes. This gives a total of 64 blocks.
Important memory map facts:
- Block 0 (Sector 0): Manufacturer block — contains the UID and manufacturer data. This block is read-only on most cards.
- Sector Trailers (Block 3 of each sector): Store the two 6-byte keys (Key A and Key B) and the access condition bits. Default Key A and Key B are both
FF FF FF FF FF FF. - Data Blocks: Blocks 1 and 2 of each sector are freely writable for your application data.
Each data block holds 16 bytes. You can store short strings, numeric counters, or binary flags. For a typical access control system, the UID alone (4 or 7 bytes) is usually sufficient without writing custom data.
Mifare Ultralight cards have a simpler flat memory (512 bits, 64 pages of 4 bytes) and no authentication, making them faster to read but less secure.
Wiring the RC522 to Arduino
The RC522 module operates at 3.3 V. While the SDA and SCK lines can usually tolerate 5 V logic from an Arduino Uno directly, it is recommended practice to use voltage dividers on MOSI, SCK, and SS lines if you want to be safe. For most hobby projects, a direct connection works reliably.
Pin connections for Arduino Uno:
| RC522 Pin | Arduino Uno Pin |
|---|---|
| SDA (SS) | Digital 10 |
| SCK | Digital 13 |
| MOSI | Digital 11 |
| MISO | Digital 12 |
| IRQ | Not connected |
| GND | GND |
| RST | Digital 9 |
| 3.3V | 3.3V |
Always power the RC522 from the 3.3 V pin of the Arduino — never connect VCC directly to 5 V, as this can permanently damage the module.
Installing the MFRC522 Library
The most widely used Arduino library for the RC522 is the MFRC522 library by miguelbalboa, available on GitHub and through the Arduino Library Manager.
Installation steps:
- Open Arduino IDE.
- Go to Sketch → Include Library → Manage Libraries.
- Search for
MFRC522. - Click Install on the entry by miguelbalboa.
After installation, you will find example sketches under File → Examples → MFRC522. The library includes examples for reading UIDs, reading/writing blocks, and changing authentication keys.
The library header and instantiation:
#include <SPI.h>
#include <MFRC522.h>
#define SS_PIN 10
#define RST_PIN 9
MFRC522 mfrc522(SS_PIN, RST_PIN);
void setup() {
Serial.begin(9600);
SPI.begin();
mfrc522.PCD_Init();
Serial.println("RC522 initialized. Hold a tag near the reader.");
}
Reading the UID from a Mifare Tag
Reading the UID (Unique Identifier) is the most common operation. Every Mifare tag has a factory-programmed UID that cannot be changed on standard cards. This UID is perfect for identifying users in an access control or attendance system.
void loop() {
// Look for new cards
if (!mfrc522.PICC_IsNewCardPresent()) return;
if (!mfrc522.PICC_ReadCardSerial()) return;
Serial.print("Card UID:");
for (byte i = 0; i < mfrc522.uid.size; i++) {
Serial.print(mfrc522.uid.uidByte[i] < 0x10 ? " 0" : " ");
Serial.print(mfrc522.uid.uidByte[i], HEX);
}
Serial.println();
mfrc522.PICC_HaltA();
}
When a card is detected, the UID bytes are printed to the Serial Monitor. A typical Mifare Classic 1K card has a 4-byte (32-bit) UID, while newer 7-byte UID cards offer a larger address space for large deployments.
Tips for reliable reading:
- Keep the card parallel to and within 3 cm of the antenna.
- Avoid metal objects directly behind the RC522 module — metal reflects RF fields and reduces range.
- Always call
PICC_HaltA()after reading to reset the card state.
Writing Data to a Mifare Tag Block
Writing to a Mifare Classic card requires authentication with Key A or Key B before accessing each sector. By default, both keys are FF FF FF FF FF FF.
void writeBlock(byte blockNum, byte dataArray[]) {
MFRC522::MIFARE_Key key;
for (byte i = 0; i < 6; i++) key.keyByte[i] = 0xFF;
MFRC522::StatusCode status;
// Authenticate using key A
status = mfrc522.PCD_Authenticate(
MFRC522::PICC_CMD_MF_AUTH_KEY_A,
blockNum, &key, &(mfrc522.uid)
);
if (status != MFRC522::STATUS_OK) {
Serial.print("Auth failed: ");
Serial.println(mfrc522.GetStatusCodeName(status));
return;
}
// Write 16 bytes
status = mfrc522.MIFARE_Write(blockNum, dataArray, 16);
if (status != MFRC522::STATUS_OK) {
Serial.print("Write failed: ");
Serial.println(mfrc522.GetStatusCodeName(status));
} else {
Serial.println("Write successful!");
}
}
To call this function, prepare a 16-byte array with your data:
byte block4Data[16] = {
'Z','b','o','t','i','c',' ','U','s','e','r',' ',' ',' ',' ',' '
};
writeBlock(4, block4Data);
After writing, you can verify by reading the block back using MIFARE_Read(). Always avoid writing to block 0 (manufacturer block) and sector trailers (blocks 3, 7, 11, etc.) unless you are intentionally changing access conditions — overwriting a sector trailer with wrong values can permanently lock the sector.
Real-World Project Ideas
Once you can reliably read UIDs and write data blocks, a wide range of practical projects opens up:
1. RFID Attendance System
Store student or employee UIDs in a lookup table on the Arduino or in EEPROM. When a card is scanned, match the UID and log the timestamp via Serial or send it to a connected Raspberry Pi or ESP8266 server. Combine with an LCD display for instant feedback.
2. Smart Door Lock
Connect a servo motor or electric solenoid lock. When an authorized UID is detected, unlock for 3 seconds, then re-lock. Store multiple authorized UIDs in EEPROM so they persist across power cycles.
3. Prepaid Balance Card
Write a balance value to block 4 of the card. Each time the card is used at a vending machine or canteen reader, decrement the balance and write it back. This creates a simple contactless payment system for controlled environments.
4. Asset Tracking
Write a unique asset ID to each card/tag and attach tags to equipment. Scan to check in/check out items with a timestamp, building a basic inventory audit trail.
Frequently Asked Questions
Why does my RC522 module not detect any card?
The most common cause is powering the RC522 from the 5 V pin instead of 3.3 V. Other causes include incorrect SPI wiring (mixed up MOSI/MISO), a bad solder joint on the module’s antenna, or a missing SPI.begin() call before mfrc522.PCD_Init(). Double-check all connections and ensure your card is a 13.56 MHz Mifare type and not a 125 kHz EM4100 card.
Can I use the RC522 with an Arduino Nano?
Yes. The Arduino Nano uses the same SPI pins — MOSI on D11, MISO on D12, SCK on D13, and any digital pin for SS. Use D10 for SS and D9 for RST as a convention. The 3.3 V pin on the Nano can supply the RC522 module directly for short-range single-reader setups.
What is the difference between Mifare Classic 1K and 4K?
Mifare Classic 1K has 1024 bytes of storage in 16 sectors of 4 blocks each. Mifare Classic 4K has 4096 bytes with 32 sectors of 4 blocks and 8 additional sectors of 16 blocks, providing more data storage for complex applications like multi-application transit cards. The authentication mechanism and key structure are identical.
Can I change the UID of a Mifare tag?
Standard Mifare Classic cards have a write-protected UID. However, special “magic” UID-writable cards (often called Gen1 or CUID cards) allow block 0 to be overwritten. These are sometimes used for RFID emulation testing. For production systems, always rely on the UID as a read-only identifier.
How do I secure my RFID system against cloning?
Change the default Key A and Key B from FF FF FF FF FF FF to a custom secret key before deploying. Store application data encrypted within data blocks. For higher security, use Mifare DESFire or Mifare Plus cards which support AES encryption at the hardware level and are far more resistant to cloning attacks.
Start Your RFID Project Today
The RC522 RFID module combined with the MFRC522 Arduino library gives you a powerful, low-cost platform for building contactless identification and data storage systems. From attendance tracking to smart locks, the possibilities are virtually endless. The key steps are getting the wiring right, installing the library, and understanding the Mifare memory layout before you start writing data blocks.
Ready to get started? Browse the full range of Arduino boards and compatible modules at zbotic.in Arduino & Microcontrollers and pick up everything you need in one place. Free shipping on orders above ₹999 across India.
Add comment