PN532 NFC Module: Read & Write NFC Tags with Arduino
The PN532 NFC module is one of the most capable and versatile NFC chips available for Arduino-based projects. Whether you want to read and write NFC tags, build an attendance system, create contactless payment prototypes, or implement RFID door locks, the PN532 handles them all. In this complete guide, we walk through everything an Indian hobbyist or maker needs to know — from wiring up the module to reading NDEF records and writing custom data to Mifare Classic, Mifare Ultralight, and NTAG2xx cards.
What Is the PN532 NFC Module?
The PN532 is a highly integrated NFC/RFID controller made by NXP Semiconductors, capable of operating at 13.56 MHz. It supports multiple card types and communication standards including ISO 14443A/B (Mifare), FeliCa, and ISO 18092 (NFC peer-to-peer). The breakout module typically includes a PCB antenna and level-shifting circuitry, making it compatible with both 3.3V and 5V microcontrollers like the Arduino Uno, Arduino Nano, and ESP32.
Key Specifications
- Operating frequency: 13.56 MHz
- Supported standards: ISO 14443A (Mifare Classic, Mifare Ultralight, NTAG), ISO 14443B, FeliCa, ISO 18092
- Interfaces: I2C (up to 400 kHz), SPI (up to 5 MHz), UART (HSU)
- Read range: Up to 5 cm (card-to-module, depends on tag and antenna size)
- Supply voltage: 3.3V (5V tolerant inputs on most breakout boards)
- Current consumption: ~100 mA active, ~5 mA power-down
The PN532 is significantly more capable than the simpler RC522 RFID module. It supports card emulation mode (making the ESP32 act like an NFC tag), peer-to-peer communication, and the full ISO 18092 standard — features the RC522 simply does not have.
Interfaces: I2C, SPI, and UART
The PN532 breakout board exposes two small switches (SEL0 and SEL1, or DIP switches on some boards) that select the communication interface:
| SEL0 | SEL1 | Interface | Best For |
|---|---|---|---|
| 0 | 0 | HSU (UART) | Arduino Mega, ESP32 (hardware UART) |
| 1 | 0 | I2C | Arduino Uno/Nano (fewest wires) |
| 0 | 1 | SPI | Fastest, most reliable |
Recommendation: For beginners, use I2C (only 4 wires). For production projects or time-sensitive applications, use SPI for maximum speed and reliability. The Adafruit PN532 library supports all three modes.
Wiring the PN532 to Arduino
I2C Wiring (Arduino Uno/Nano)
| PN532 Pin | Arduino Pin |
|---|---|
| VCC | 5V |
| GND | GND |
| SDA | A4 (SDA) |
| SCL | A5 (SCL) |
Set DIP switches: SEL0=1, SEL1=0. The I2C address is 0x24 by default.
SPI Wiring (Arduino Uno/Nano)
| PN532 Pin | Arduino Pin |
|---|---|
| VCC | 5V |
| GND | GND |
| SCK | D13 |
| MISO | D12 |
| MOSI | D11 |
| SS/CS | D10 |
Set DIP switches: SEL0=0, SEL1=1.
Reading NFC Tags and Card UIDs
Install the Adafruit PN532 library via the Arduino Library Manager (search “Adafruit PN532”). Also install the Adafruit BusIO dependency. Here is a basic sketch to read a tag’s UID:
#include <Wire.h>
#include <Adafruit_PN532.h>
// For I2C
Adafruit_PN532 nfc(SDA, SCL);
void setup() {
Serial.begin(115200);
nfc.begin();
uint32_t versiondata = nfc.getFirmwareVersion();
if (!versiondata) {
Serial.println("PN532 not found. Check wiring!");
while (1);
}
Serial.print("Found PN532 chip, firmware: ");
Serial.println((versiondata >> 16) & 0xFF);
nfc.SAMConfig(); // Normal mode
Serial.println("Waiting for NFC card...");
}
void loop() {
uint8_t uid[7];
uint8_t uidLength;
if (nfc.readPassiveTargetID(PN532_MIFARE_ISO14443A, uid, &uidLength)) {
Serial.print("Card UID: ");
for (uint8_t i = 0; i < uidLength; i++) {
Serial.print(uid[i], HEX);
Serial.print(" ");
}
Serial.println();
delay(1000); // Debounce
}
}
The UID is the unique identifier printed on or embedded in your card/tag. For Mifare Classic 1K cards (the most common in India), the UID is 4 bytes. For NTAG213/215/216 sticker tags, it is 7 bytes.
Writing NDEF Data to NFC Tags
Writing NDEF (NFC Data Exchange Format) records is what makes NFC tags actually useful — you can encode URLs, contact cards (vCards), WiFi credentials, plain text, and more. Use the NDEF library by Don Coleman alongside the Adafruit PN532 library.
#include <Wire.h>
#include <Adafruit_PN532.h>
Adafruit_PN532 nfc(SDA, SCL);
void setup() {
Serial.begin(115200);
nfc.begin();
nfc.SAMConfig();
Serial.println("Hold NTAG213 tag near module to write URL...");
}
void loop() {
uint8_t uid[7];
uint8_t uidLength;
if (nfc.readPassiveTargetID(PN532_MIFARE_ISO14443A, uid, &uidLength, 500)) {
// NDEF URL record: https://zbotic.in
// NDEF Short Record: MB=1, ME=1, SR=1, TNF=0x01 (Well-Known)
uint8_t ndefMsg[] = {
0x03, 0x13, // TLV: NDEF Message, length 19 bytes
0xD1, 0x01, 0x0F, 0x55, // NDEF: MB/ME/SR, type length 1, payload length 15, type 'U' (URI)
0x04, // URI identifier: https://
'z','b','o','t','i','c','.','i','n', // payload
0xFE // TLV Terminator
};
// Write to page 4 of NTAG213
nfc.ntag2xx_WritePage(4, ndefMsg);
nfc.ntag2xx_WritePage(5, ndefMsg + 4);
nfc.ntag2xx_WritePage(6, ndefMsg + 8);
nfc.ntag2xx_WritePage(7, ndefMsg + 12);
Serial.println("NDEF URL written!");
delay(2000);
}
}
Tip for Indian makers: NTAG213 sticker tags are widely available in India and are the easiest to write NDEF data to. Avoid using Mifare Classic for NDEF — it requires sector authentication first and is more complex. Mifare Ultralight / NTAG tags are write-friendly and compatible with all Android and iPhone (XS+) phones.
Mifare Classic: Authentication and Sector Access
Mifare Classic 1K cards are divided into 16 sectors, each with 4 blocks of 16 bytes. Block 3 in each sector is the trailer block containing two 6-byte keys (Key A and Key B) and access bits. You must authenticate with Key A or Key B before reading or writing data blocks.
uint8_t keyA[6] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; // Factory default
uint8_t block = 4; // Block 4 is in sector 1
uint8_t data[16];
// Authenticate sector
if (nfc.mifareclassic_AuthenticateBlock(uid, uidLength, block, 0, keyA)) {
// Read block
if (nfc.mifareclassic_ReadDataBlock(block, data)) {
Serial.print("Block 4 data: ");
nfc.PrintHexChar(data, 16);
}
} else {
Serial.println("Authentication failed! Wrong key?");
}
For an attendance system, store an employee ID in block 4 of sector 1 using a custom Key A you set during card initialisation. This prevents cloning by anyone who doesn’t know your key. Never use the default 0xFF key in production.
Recommended Products for NFC Projects
0.96 Inch I2C OLED LCD Module SSD1306
Display the scanned card UID, user name, or access status on this compact OLED. Perfect companion for PN532-based attendance or access control systems.
0.96 Inch SPI OLED LCD Module SSD1306 (7-pin)
SPI version of the OLED for projects where I2C pins are already occupied by the PN532. Faster refresh for real-time NFC scan feedback displays.
1 Channel 12V 30A Relay Module with Optocoupler
Trigger a door lock or access gate when an authorized NFC card is scanned. This 30A optocoupler relay handles real-world loads safely from Arduino output.
Ai Thinker ESP32-C3-01M Wi-Fi + BLE Module
Combine PN532 NFC scanning with WiFi connectivity on this compact ESP32-C3 module. Log attendance to a server or send Telegram alerts on card scan.
Waveshare ESP32-C3 0.71inch Round Display Development Board
Build a sleek NFC card scanner with onboard display. Show “Access Granted” or card owner’s name on the round screen. Add PN532 via I2C for a complete system.
Frequently Asked Questions
What is the difference between PN532 and RC522?
The RC522 is a basic RFID reader limited to Mifare Classic cards on 13.56 MHz. The PN532 supports Mifare Classic, Mifare Ultralight, NTAG stickers, FeliCa, ISO 14443B, and NFC peer-to-peer mode. The PN532 also supports card emulation (making your Arduino act as an NFC tag). For most projects beyond simple UID reading, the PN532 is the better choice.
Can I write NFC tags that work with Android and iPhone?
Yes, with NTAG213/215/216 tags and a properly formatted NDEF record. Android supports NFC since Android 4.0. iPhones support NFC tag reading from iPhone XS (iOS 13+) and background tag reading from iPhone 7 (iOS 14+). Stick to NDEF URI or Text records for maximum compatibility across both platforms.
Why does my PN532 fail to detect cards sometimes?
The most common causes are: wrong DIP switch position for your chosen interface, insufficient power supply (PN532 needs ~100 mA peak — use a proper 5V supply, not a weak USB hub), and card held at a wrong angle. The PN532 PCB antenna is directional — hold the card flat and parallel to the module for best results.
Can I use PN532 with ESP32 over I2C?
Yes. Connect SDA to GPIO 21 and SCL to GPIO 22 (default I2C pins on ESP32). Use Wire.begin(21, 22) before calling nfc.begin(). The Adafruit PN532 library works identically on ESP32 and Arduino.
How many NFC tags can I enroll in an attendance system?
The limit depends on your storage, not the PN532. Arduino EEPROM can store about 20–30 UIDs (4 bytes each). An ESP32 with SPIFFS/LittleFS can store thousands. For enterprise attendance with hundreds of employees, log UIDs to an SD card or send them over WiFi to a server database.
Build Your NFC Project Today
Get the PN532 module, OLED displays, relay modules, and ESP32 boards from Zbotic — shipped fast across India with secure packaging.
Add comment