The RC522 is everywhere in Uno kits, and it is almost always wired wrong: it is a 3.3 V part, and the Uno drives 5 V on its SPI pins.
The safe way is a cheap 4-channel level shifter between the Uno and the module’s inputs. With that in place the MFRC522 library reads card UIDs exactly as on 3.3 V boards.
Wiring
| Arduino Uno R3 | RC522 RFID reader (MFRC522, 13.56 MHz) | Wire | Notes |
|---|---|---|---|
| 3.3V | 3.3V | red | The Uno’s 3.3V pin supplies about 50 mA; the RC522 needs around 26 mA. |
| GND | GND | black | |
| D13 | SCK | yellow | Via level shifter |
| D11 | MOSI | green | Via level shifter |
| D12 | MISO | blue | RC522 output (3.3 V) into the Uno: reads as HIGH, no shifter needed. |
| D10 | SDA | purple | Via level shifter |
| D9 | RST | orange | Via level shifter — Shifter LV = 3.3V, HV = 5V, GND shared. |
3.3 V only part, 5 V board. Power the RC522 from 3.3 V — never 5 V. The MFRC522 chip’s pins are not rated for 5 V either: many people wire it straight to an Uno and it works for a while, but for a build that lasts, drop the Uno’s SCK, MOSI, SDA (SS) and RST signals to 3.3 V with a level shifter or dividers. ESP32 and Pico connect directly.
Board quirks
- The RC522 is a 3.3 V chip and its inputs are not rated for 5 V. Many tutorials skip the level shifter and it often works — until the module dies.
- D10–D13 are the Uno’s hardware SPI pins; D10 must stay an output, which the library handles.
- MISO is the only line coming back to the Uno, and 3.3 V is a valid HIGH for it.
Code
// RC522 (MFRC522) RFID reader on an Arduino Uno R3.
// The RC522 is a 3.3 V part: power it from the Uno's 3.3V pin and pass SDA, SCK, MOSI and RST
// through a 5 V → 3.3 V level shifter. MISO comes back at 3.3 V, which the Uno reads fine.
// SDA(SS) → D10, SCK → D13, MOSI → D11, MISO → D12, RST → D9.
#include <SPI.h>
#include <MFRC522.h>
const uint8_t SS_PIN = 10;
const uint8_t RST_PIN = 9;
MFRC522 rfid(SS_PIN, RST_PIN);
void setup() {
Serial.begin(9600);
SPI.begin();
rfid.PCD_Init();
byte v = rfid.PCD_ReadRegister(MFRC522::VersionReg);
if (v == 0x00 || v == 0xFF) {
Serial.println(F("RC522 not answering - check 3.3V, the level shifter and SPI wiring"));
} else {
Serial.println(F("RC522 ready. Tap a card..."));
}
}
void loop() {
if (!rfid.PICC_IsNewCardPresent() || !rfid.PICC_ReadCardSerial()) return;
Serial.print(F("Card UID:"));
for (byte i = 0; i < rfid.uid.size; i++) {
Serial.print(rfid.uid.uidByte[i] < 0x10 ? F(" 0") : F(" "));
Serial.print(rfid.uid.uidByte[i], HEX);
}
Serial.println();
rfid.PICC_HaltA();
rfid.PCD_StopCrypto1();
}// RC522 (MFRC522) RFID reader on an Arduino Uno R3.
// The RC522 is a 3.3 V part: power it from the Uno's 3.3V pin and pass SDA, SCK, MOSI and RST
// through a 5 V → 3.3 V level shifter. MISO comes back at 3.3 V, which the Uno reads fine.
// SDA(SS) → D10, SCK → D13, MOSI → D11, MISO → D12, RST → D9.
#include <SPI.h>
#include <MFRC522.h>
const uint8_t SS_PIN = 10;
const uint8_t RST_PIN = 9;
MFRC522 rfid(SS_PIN, RST_PIN);
void setup() {
Serial.begin(9600);
SPI.begin();
rfid.PCD_Init();
byte v = rfid.PCD_ReadRegister(MFRC522::VersionReg);
if (v == 0x00 || v == 0xFF) {
Serial.println(F("RC522 not answering - check 3.3V, the level shifter and SPI wiring"));
} else {
Serial.println(F("RC522 ready. Tap a card..."));
}
}
void loop() {
if (!rfid.PICC_IsNewCardPresent() || !rfid.PICC_ReadCardSerial()) return;
Serial.print(F("Card UID:"));
for (byte i = 0; i < rfid.uid.size; i++) {
Serial.print(rfid.uid.uidByte[i] < 0x10 ? F(" 0") : F(" "));
Serial.print(rfid.uid.uidByte[i], HEX);
}
Serial.println();
rfid.PICC_HaltA();
rfid.PCD_StopCrypto1();
}Library: MFRC522 (GithubCommunity) — compiled with MFRC522 1.4.12.
Expected serial output
RC522 ready. Tap a card...
Card UID: 4A 3F 9C 2B
Card UID: 04 6E 21 A2 4F 61 80RC522 ready. Tap a card... Card UID: 4A 3F 9C 2B Card UID: 04 6E 21 A2 4F 61 80
Common errors
“RC522 not answering”
Check the shifter has both LV (3.3V) and HV (5V) connected, and the SPI lines are on D10–D13.
Reads once, then stops
Weak 3.3 V supply. Add a 10 µF capacitor at the module’s 3.3V pin.