Sensors/ NFC/ RC522

RC522 RFID/NFC Module

The RC522 RFID/NFC module offers an affordable and reliable solution for integrating NFC and RFID functionality into your projects. Its compact size, multi-protocol support, and robust performance make it a great choice for a wide range of applications.

RC522 RFID/NFC Module image
RC522 · SPI / I2C / UART
3modes
SPI · I2C · UART
8pins
Connections
3.3V
Supply
-20 to +80 °C
Operating temp
$3.00
Typical price
On this page

RC522 pinout

8 pins · SPI · I2C · UART

The RC522 supports multiple communication protocols (SPI, I²C, UART) with 8 main pins for interfacing.

View:
RC522 RFID/NFC Module pinout
PinTypeDescriptionNotes
VCCPowerPower supply input (3.3V). Typically 3.3V for most modules.Some modules support 5V - check your specific module.
GNDPowerGround connection. Connect to system ground.
RSTControlReset signal (active low). Used to reset the module.Connect to GPIO for software reset control.
IRQInterruptInterrupt signal output. Triggers when card is detected.Optional - can be left unconnected for polling mode.
MISOSPISPI Master In Slave Out. Data from RC522 to microcontroller.Connect to ESP32 MISO (GPIO 19).
MOSISPISPI Master Out Slave In. Data from microcontroller to RC522.Connect to ESP32 MOSI (GPIO 23).
SCKSPISPI clock line. Clock signal for SPI communication.Connect to ESP32 SCK (GPIO 18).
SDA/SSSPI/I2CSPI: Slave Select (chip select). I²C: Serial Data line.For SPI: Connect to any GPIO (e.g., GPIO 5). For I²C: data line.
  • Supports ISO/IEC 14443 Type A RFID/NFC tags (13.56 MHz)

  • Multiple protocols: SPI (most common), I²C, UART

  • Operating voltage: 3.3V (some modules tolerate 5V)

  • Reading distance: typically 0-6cm depending on tag size

  • SPI is the most widely used interface for RC522

Wiring the RC522 to ESP32

8 connections · 1 optional

To interface the RC522 with an ESP32 via SPI, connect VCC to 3.3V, GND to ground, and the SPI pins (MISO, MOSI, SCK, SDA/SS) to the corresponding ESP32 SPI pins.

RC522 RFID/NFC Module wiring with ESP32
RC522 pinESP32 pinPurpose
VCC3.3VPower supply. Use 3.3V for most modules.
GNDGNDGround connection.
RSTGPIO 4Reset control. Any available GPIO pin.
MISOGPIO 19SPI MISO - data from RC522 to ESP32.
MOSIGPIO 23SPI MOSI - data from ESP32 to RC522.
SCKGPIO 18SPI clock signal.
SDA/SSGPIO 5SPI Slave Select (chip select). Any available GPIO.
IRQOptional GPIOInterrupt pin for card detection (optional). · optional
  • SPI is the recommended interface (most reliable and well-documented)

  • Use MFRC522 library for Arduino/ESP32 compatibility

  • Reading range: 0-6cm depending on tag antenna size

  • Compatible cards: MIFARE Classic 1K, MIFARE Ultralight, NTAG213/215/216

  • For 5V systems: use level shifter on SPI and control pins

  • IRQ pin optional - polling mode works fine for most applications

  • Orient antenna parallel to RFID tag for best reading performance

  • Add 100µF capacitor across VCC and GND for stable operation

RC522 code examples

5 platforms
Platform:

RC522 Arduino example

Copy
// Requires library: "MFRC522"
#include <SPI.h>
#include <MFRC522.h>

#define RST_PIN 4 // GPIO4, matches the wiring above
#define SS_PIN 5  // GPIO5 (SDA/SS); SCK=GPIO18, MISO=GPIO19, MOSI=GPIO23 (ESP32 VSPI defaults)
MFRC522 rfid(SS_PIN, RST_PIN);

void setup() {
    Serial.begin(115200);
    SPI.begin();
    rfid.PCD_Init();
    Serial.println("RC522 initialized. Waiting for cards...");
}

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

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

    rfid.PICC_HaltA();
}

This Arduino sketch interfaces with the RC522 module over SPI using the MFRC522 library. The setup function initializes the module, while the loop scans for RFID cards and prints their UIDs when detected. Additional functionality, such as reading or writing card data, can be implemented using the MFRC522 library.

RC522 ESP-IDF example

Copy
// Requires the rc522 driver from the ESP Component Registry:
//   idf.py add-dependency "abobija/rc522^4.0.0"

#include <stdio.h>
#include "rc522.h"
#include "driver/rc522_spi.h"
#include "rc522_picc.h"

#define MISO_GPIO 19
#define MOSI_GPIO 23
#define SCLK_GPIO 18
#define CS_GPIO   5   // SS, matches the wiring above
#define RST_GPIO  4   // RST, matches the wiring above

static rc522_spi_config_t driver_config = {
    .host_id = SPI3_HOST,
    .bus_config = &(spi_bus_config_t){
        .miso_io_num = MISO_GPIO,
        .mosi_io_num = MOSI_GPIO,
        .sclk_io_num = SCLK_GPIO,
    },
    .dev_config = {
        .spics_io_num = CS_GPIO,
    },
    .rst_io_num = RST_GPIO,
};

static rc522_driver_handle_t driver;
static rc522_handle_t scanner;

static void on_picc_state_changed(void *arg, esp_event_base_t base, int32_t event_id, void *data)
{
    rc522_picc_state_changed_event_t *event = (rc522_picc_state_changed_event_t *)data;
    rc522_picc_t *picc = event->picc;

    if (picc->state == RC522_PICC_STATE_ACTIVE) {
        char uid_str[RC522_PICC_UID_STR_BUFFER_SIZE_MAX];
        rc522_picc_uid_to_str(&picc->uid, uid_str, sizeof(uid_str));
        printf("Card detected, UID: %s\n", uid_str);
    }
}

void app_main(void)
{
    ESP_ERROR_CHECK(rc522_spi_create(&driver_config, &driver));
    ESP_ERROR_CHECK(rc522_driver_install(driver));

    rc522_config_t scanner_config = {
        .driver = driver,
    };
    ESP_ERROR_CHECK(rc522_create(&scanner_config, &scanner));
    ESP_ERROR_CHECK(rc522_register_events(scanner, RC522_EVENT_PICC_STATE_CHANGED, on_picc_state_changed, NULL));
    ESP_ERROR_CHECK(rc522_start(scanner));
}

ESP-IDF ships no MFRC522 driver of its own, so this example uses the well-maintained abobija/rc522 driver from the ESP Component Registry. Install it into your project first with idf.py add-dependency "abobija/rc522^4.0.0", then build as usual.

The driver is event-based: rc522_spi_create() and rc522_driver_install() set up the SPI transport, rc522_create() starts a scanner task, and the registered RC522_EVENT_PICC_STATE_CHANGED callback fires whenever a card enters the field. When the card reaches RC522_PICC_STATE_ACTIVE, its UID is formatted with rc522_picc_uid_to_str() and printed. The RST pin is optional (-1 uses soft reset); adjust the SPI pin defines to your wiring.

RC522 ESPHome example

Copy
spi:
  clk_pin: GPIO18
  mosi_pin: GPIO23
  miso_pin: GPIO19

rc522_spi:
  cs_pin: GPIO5    # SDA/SS, matches the wiring above
  reset_pin: GPIO4 # RST
  update_interval: 1s
  on_tag:
    - logger.log:
        format: "Tag scanned: %s"
        args: ['x.c_str()']

binary_sensor:
  - platform: rc522
    uid: 74-10-37-94  # replace with your tag's UID (see the log line above)
    name: "RC522 Known Tag"

ESPHome drives the RC522 through the rc522_spi hub (pins per the wiring above: CS on GPIO5, RST on GPIO4) plus an spi: bus. Every scanned tag fires on_tag - logged here - and a binary_sensor with a specific UID turns on while that tag is present. Scan once, copy the UID from the log, and paste it into the binary_sensor.

RC522 PlatformIO example

Copy
[env:esp32dev]
platform = espressif32
board = esp32dev
framework = arduino
monitor_speed = 115200
lib_deps =
    miguelbalboa/MFRC522 @ ^1.4.12
src/main.cppCopy
#include <Arduino.h>
#include <SPI.h>
#include <MFRC522.h>

#define RST_PIN 4 // GPIO4, matches the wiring above
#define SS_PIN 5  // GPIO5 (SDA/SS); SCK=GPIO18, MISO=GPIO19, MOSI=GPIO23 (ESP32 VSPI defaults)
MFRC522 rfid(SS_PIN, RST_PIN);

void setup() {
    Serial.begin(115200);
    SPI.begin();
    rfid.PCD_Init();
    Serial.println("RC522 initialized. Waiting for cards...");
}

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

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

    rfid.PICC_HaltA();
}

This PlatformIO example interfaces with the RC522 module using the MFRC522 library over SPI. The code initializes the module, scans for RFID tags, and logs their UIDs to the Serial Monitor. Additional NFC features can be implemented using the library.

RC522 MicroPython example

Copy
# Requires driver: mfrc522.py from https://github.com/wendlers/micropython-mfrc522
# Copy it to the board: mpremote cp mfrc522.py :
from mfrc522 import MFRC522
import time

# Pins per the wiring above: SCK 18, MOSI 23, MISO 19, RST 4, CS (SDA/SS) 5
reader = MFRC522(sck=18, mosi=23, miso=19, rst=4, cs=5)

while True:
    (status, tag_type) = reader.request(reader.REQIDL)
    if status == reader.OK:
        (status, uid) = reader.anticoll()
        if status == reader.OK:
            print("Card UID:", [hex(i) for i in uid])
    time.sleep(0.5)

The example uses wendlers/micropython-mfrc522 (copy mfrc522.py to the board). The constructor takes pin numbers directly - SCK 18, MOSI 23, MISO 19, RST 4, CS 5, matching the wiring above - and the request/anticoll pair polls for a card and reads its UID.

RC522 specifications

From the datasheet
Communication Protocols
SPI, I2C, UART
Operating Voltage
3.3V
Supported Standards
ISO/IEC 14443 Type A
Operating Temperature
-20°C to +80°C
Dimensions
40mm x 60mm x 3mm

About the RC522

The RC522 is a breakout for NXP’s MFRC522, the reader IC behind most of the cheap 13.56 MHz card readers sold for microcontroller projects. It speaks ISO/IEC 14443 Type A, covering MIFARE Classic, MIFARE Ultralight, and NTAG213/215/216 tags, and per NXP’s own datasheet the chip supports SPI, I2C, and UART host interfaces - though nearly every RC522 breakout on the market, this one included, ships wired for SPI, the interface the entire community library ecosystem (built around the widely used MFRC522 Arduino library) targets.

Power it carefully: NXP specs the MFRC522’s own supply at 2.5 to 3.3V, with the digital I/O pins capped at supply-plus-0.5V absolute maximum, which makes this a 3.3V-only part in practice - a common way to damage one is feeding it straight from a 5V Arduino pin without a level shifter. That is not an issue on the ESP32, whose GPIOs are already 3.3V native, so the direct wiring on this page needs no extra components. Also worth knowing before buying a batch: counterfeit and second-source MFRC522 chips circulate widely in the market - some are legitimate compatible parts like Fudan’s FM17522 (which reports a different firmware-version register but works fine with the standard library), others are outright clones that behave oddly on some readers, and an unexpected firmware-version readback is the usual tell.

For plain MIFARE badge reading over SPI, the RC522 remains the cheap, well-documented default. Step up to the pricier PN532 if a project needs to talk to NFC-enabled phones (NDEF tags, peer-to-peer) or wants the host interface selectable without resoldering. The RDM6300 reader elsewhere on this site is a different technology altogether - 125 kHz instead of 13.56 MHz - so its tags are not interchangeable with anything the RC522 reads.

RC522 troubleshooting

5 common issues

Module Fails to Power On

Issue: The RC522 module does not power up or respond to commands.

Possible causes include insufficient power supply, incorrect wiring, or faulty hardware.

Solution: Ensure the module is connected to a stable power source within the recommended voltage range of 3.3V to 5V. Verify that all connections are secure and correctly configured. If the problem persists, consider testing the module with a different power source or replacing it.

Communication Interface Not Working

Issue: The module fails to communicate with the microcontroller over the chosen interface (SPI).

Possible causes include incorrect wiring, improper interface selection, or incompatible voltage levels.

Solution: Double-check the wiring to ensure correct connections for SPI communication. For SPI, verify the MOSI, MISO, SCK, and SS lines are properly connected. Ensure that the microcontroller's SPI interface is enabled and configured correctly.

Unable to Read Tags

Issue: The module initializes correctly but fails to read RFID tags.

Possible causes include incorrect antenna orientation, insufficient power supply, or interference from nearby electronic devices.

Solution: Ensure the module's antenna is properly oriented and positioned near the tags. Verify that the power supply provides adequate current for the module's operation. Keep the module away from sources of electromagnetic interference.

Inconsistent Tag Detection

Issue: The module detects tags intermittently or with delays.

Possible causes include low-quality tags, environmental interference, or firmware issues.

Solution: Test with different tags to rule out tag quality issues. Ensure the operating environment is free from strong electromagnetic interference. Update the module's firmware to the latest version to benefit from bug fixes and improvements.

Library or Software Issues

Issue: The module operates erratically or produces errors during operation.

Possible causes include outdated or incompatible libraries, incorrect initialization, or software bugs.

Solution: Ensure that the latest version of the MFRC522 library is installed and compatible with your development environment. Review the initialization code to confirm that the module is set up correctly. Consult the module's documentation and community forums for guidance on proper usage.

Where to buy the RC522

RC522 RFID/NFC Module
RC522 RFID/NFC Module
$3.00per unit, typical
Amazon and AliExpress links are affiliate links - buying through them supports the site at no extra cost to you.

Resources

Similar sensors