Back to Sensors & Actuators Series

RFID/NFC Readers: MFRC522 & PN532

July 21, 2025 Wasil Zafar 14 min read

MFRC522 & PN532 deep dive — RFID/NFC protocols, SPI/I2C/HSU wiring, MIFARE auth, NFC peer-to-peer, card emulation, reader comparison, and applications.

Contents

  1. Working Principle
  2. Electrical Characteristics
  3. Interfacing with MCU
  4. Calibration
  5. Code Example
  6. Real-World Applications
  7. PN532 NFC Module
  8. Reader Comparison
  9. Limitations

Working Principle

The MFRC522 is a 13.56 MHz contactless reader/writer IC from NXP. It communicates with MIFARE-compatible RFID tags using ISO 14443A protocol. The reader generates a 13.56 MHz electromagnetic field via its antenna coil. When a passive tag enters this field, it draws power inductively and responds by modulating the field (load modulation). The MFRC522 demodulates this response to read tag data, UIDs, and memory sectors.

Electrical Characteristics

MFRC522 Key Specifications

ParameterValue
Operating Frequency13.56 MHz
Supported ProtocolsISO 14443A/MIFARE
Communication InterfaceSPI (up to 10 Mbit/s), I2C, UART
Supply Voltage2.5–3.3 V DC
Operating Current13–26 mA (during RF transmission)
Read Range~0–50 mm (depends on antenna and tag)
Data Transfer Rate106 kbit/s, 212 kbit/s, 424 kbit/s, 848 kbit/s
Tag CompatibilityMIFARE Classic 1K/4K, MIFARE Ultralight, NTAG213/215/216

Interfacing with an MCU

The RC522 module uses SPI by default: connect SDA (SS), SCK, MOSI, MISO, RST, and GND. The module operates at 3.3 V — do not connect VCC to 5 V. Some modules have a 3.3 V regulator but the SPI lines are not 5 V tolerant. Use logic-level shifters with 5 V Arduinos, or use 3.3 V boards (ESP32, STM32).

Calibration

The MFRC522 is factory-calibrated for antenna tuning. For maximum read range, ensure the antenna coil has clear space (no metal within 20 mm). Adjust the RxGain register (default 0x48) to increase receiver sensitivity. The TModeReg and TPrescalerReg control timeout for slow-responding tags.

Code Example

// MFRC522 RFID — read UID and authenticate on Arduino
#include <SPI.h>
#include <MFRC522.h>

#define SS_PIN   10
#define RST_PIN   9

MFRC522 rfid(SS_PIN, RST_PIN);
MFRC522::MIFARE_Key key;

void setup() {
    Serial.begin(115200);
    SPI.begin();
    rfid.PCD_Init();

    // Default MIFARE key (factory default = 0xFF x 6)
    for (byte i = 0; i < 6; i++) key.keyByte[i] = 0xFF;

    Serial.println("MFRC522 RFID Ready");
    Serial.print("Firmware: 0x");
    Serial.println(rfid.PCD_ReadRegister(rfid.VersionReg), HEX);
}

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

    // Print UID
    Serial.print("UID: ");
    for (byte i = 0; i < rfid.uid.size; i++) {
        Serial.print(rfid.uid.uidByte[i] < 0x10 ? " 0" : " ");
        Serial.print(rfid.uid.uidByte[i], HEX);
    }
    Serial.println();

    // Print tag type
    Serial.print("Type: ");
    Serial.println(rfid.PICC_GetTypeName(rfid.PICC_GetType(rfid.uid.sak)));

    // Authenticate and read block 4
    byte block = 4;
    byte buffer[18];
    byte size = sizeof(buffer);
    MFRC522::StatusCode status;

    status = rfid.PCD_Authenticate(MFRC522::PICC_CMD_MF_AUTH_KEY_A, block, &key, &(rfid.uid));
    if (status == MFRC522::STATUS_OK) {
        status = rfid.MIFARE_Read(block, buffer, &size);
        if (status == MFRC522::STATUS_OK) {
            Serial.print("Block 4: ");
            for (byte i = 0; i < 16; i++) {
                Serial.print(buffer[i] < 0x10 ? " 0" : " ");
                Serial.print(buffer[i], HEX);
            }
            Serial.println();
        }
    }

    rfid.PICC_HaltA();
    rfid.PCD_StopCrypto1();
    delay(1000);
}

Real-World Applications

Library Book Tracking System

Libraries worldwide use 13.56 MHz RFID tags in book spines with MFRC522-class readers at checkout stations and security gates. Each tag stores a unique identifier linked to the library database, enabling self-checkout, automated inventory scanning, and anti-theft detection — processing thousands of items daily without line-of-sight requirements.

RFIDInventory ManagementLibrary Systems

PN532: Full NFC Module

The NXP PN532 is a full-featured NFC controller that supports everything the MFRC522 does — plus much more. It implements the complete NFC specification with three operating modes:

  • Reader/Writer: Read/write ISO 14443A/B tags, MIFARE Classic/Ultralight, FeliCa, and ISO 15693 vicinity cards
  • Peer-to-Peer: Exchange data between two NFC devices (Android Beam, SNEP/LLCP protocols)
  • Card Emulation: The PN532 itself acts as an NFC tag — useful for mobile payment terminals and access systems

Interfaces: The PN532 supports I2C, SPI, and HSU (High-Speed UART). Most breakout boards (Adafruit, Elechouse) use DIP switches to select the interface. I2C is the most common choice for Arduino projects (address 0x24).

// PN532 NFC — read ISO 14443A tag UID via I2C
#include <Wire.h>
#include <Adafruit_PN532.h>

#define PN532_IRQ   2
#define PN532_RESET 3

Adafruit_PN532 nfc(PN532_IRQ, PN532_RESET);  // I2C mode

void setup() {
    Serial.begin(115200);
    nfc.begin();

    uint32_t versiondata = nfc.getFirmwareVersion();
    if (!versiondata) {
        Serial.println("PN532 not found");
        while (1);
    }
    Serial.print("PN532 Firmware: ");
    Serial.print((versiondata >> 16) & 0xFF);
    Serial.print('.');
    Serial.println((versiondata >> 8) & 0xFF);

    nfc.SAMConfig();  // Configure Secure Access Module
    Serial.println("Waiting for NFC tag...");
}

void loop() {
    uint8_t uid[7];
    uint8_t uidLength;

    if (nfc.readPassiveTargetID(PN532_MIFARE_ISO14443A, uid, &uidLength)) {
        Serial.print("UID (");
        Serial.print(uidLength);
        Serial.print(" bytes): ");
        for (uint8_t i = 0; i < uidLength; i++) {
            Serial.print(uid[i] < 0x10 ? " 0" : " ");
            Serial.print(uid[i], HEX);
        }
        Serial.println();
        delay(1000);
    }
}
When to upgrade: Choose PN532 over MFRC522 when your project requires NFC peer-to-peer communication, card emulation mode, FeliCa/ISO 14443B tag support, or I2C/UART interfaces. The PN532 costs ~$3–5 more but unlocks the full NFC stack.

MFRC522 vs PN532 Comparison

FeatureMFRC522PN532
ProtocolsISO 14443A onlyISO 14443A/B, FeliCa, ISO 15693
NFC ModesReader/Writer onlyReader/Writer + P2P + Card Emulation
InterfacesSPI, I2C, UARTSPI, I2C, HSU (High-Speed UART)
Supply Voltage2.5–3.3 V3.3–5.5 V (on-board regulator)
Read Range~5 cm~5–7 cm (larger antenna)
7-Byte UIDSupportedSupported
Android/Phone NFC✓ (P2P + HCE)
Typical Price~$1–2~$4–7

Limitations

  • Short range: 13.56 MHz RFID is limited to ~5–7 cm. UHF RFID (900 MHz) provides metres of range but requires different hardware entirely.
  • Metal interference: Metallic surfaces near the antenna detune it and drastically reduce read range. Use ferrite shielding.
  • Security: Default MIFARE Classic keys (0xFF) are well-known. Always change authentication keys for security-sensitive applications.
  • Multi-tag collisions: Both readers handle anti-collision, but throughput drops with simultaneous tags.
  • MFRC522 protocol limits: No ISO 14443B, FeliCa, or NFC P2P — upgrade to PN532 for these capabilities.