Preview build — page text is a draft awaiting human review. Code badges come from real compiles. The flasher is real but not yet hardware-tested; the Playground is still a preview.

RC522 RFID with Arduino Nano — 3.3 V wiring done properly

Connect an RC522 RFID reader to an Arduino Nano on SPI with a 3.3 V regulator and a level shifter, read card UIDs and flag one allowed card.

Arduino C++Verified — core avr 1.8.8, MFRC522 1.4.12, 3 Nov 2026Compile-only

Community draft — report a mistake

RFID door locks and attendance systems usually start with an RC522 and a Nano. The reader speaks SPI, which on the Nano lives on D11, D12 and D13, with chip-select on D10 and reset on D9.

The part people get wrong is voltage: the RC522 runs at 3.3 V while the Nano speaks 5 V. This guide powers it from a small regulator and passes the four Nano outputs through a BSS138 level shifter. Copy your card’s UID from the Serial Monitor into ALLOWED to make it the “key”.

Wiring

Arduino NanoOnly the pins used are shown · 5 V logicAMS1117 3.3 V module (IN from Nano 5V)RC522 RFID reader (MFRC522, 13.56 MHz)LV⇄HVLV⇄HVLV⇄HVLV⇄HV3.3VGNDD13GNDD12D11D10D9SDASCKMOSIMISOIRQ (not connected)GNDRST3.3V
Also needed: AMS1117 3.3 V regulator module, 4-channel BSS138 level shifter.
Every connection
Arduino NanoRC522 RFID reader (MFRC522, 13.56 MHz)WireNotes
AMS1117 3.3 V module (IN from Nano 5V) · 3.3V3.3VredModule IN → Nano 5V, module GND → Nano GND. The same 3.3 V feeds the shifter’s LV side.
GNDGNDblack
D10SDApurpleVia level shifter — SDA is the SPI chip-select (SS) on this module.
D13SCKyellowVia level shifter
D11MOSIgreenVia level shifter
D12MISOblueRC522 output at 3.3 V — the Nano reads it as HIGH directly.
D9RSTorangeVia level shifter — Shifter LV = 3.3 V, HV = Nano 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 5 V tolerant. Many tutorials wire it straight to a Nano and it works — for a while. The shifter costs ₹30 and keeps it working.
  • Why a regulator: the Nano’s 3V3 pin comes from the CH340/FT232 USB chip and is meant for tiny loads. The RC522’s antenna draws tens of mA in bursts; a separate 3.3 V supply removes “reads once, then nothing” problems.
  • SPI is fixed on the Nano: SCK = D13, MOSI = D11, MISO = D12. SDA (chip select) and RST can move, but update the sketch.
  • D13 is also the on-board LED, so the LED flickers on every card poll. The sketch frees SPI briefly to show a clean “allowed” flash.
  • The MFRC522 library clocks SPI at 4 MHz, near the limit of a BSS138 shifter. Keep the shifter wires short (under 10 cm); if reads are flaky, a 74HC4050 buffer powered from 3.3 V is a faster one-way alternative.
  • Leave IRQ unconnected.

Code

rc522-nano.inoArduino C++Open in PlaygroundOpen in PlaygroundFlash
// RC522 (MFRC522) RFID reader on an Arduino Nano: prints each card's UID and flashes the LED
// for one "allowed" card. The RC522 is a 3.3 V part: power it from a 3.3 V regulator and pass
// SDA(SS), SCK, MOSI and RST through a level shifter. MISO comes back at 3.3 V (read fine).
// SDA → 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;
const byte ALLOWED[4] = {0xDE, 0xAD, 0xBE, 0xEF};  // replace with your card's UID

MFRC522 rfid(SS_PIN, RST_PIN);

void setup() {
  Serial.begin(115200);
  pinMode(LED_BUILTIN, OUTPUT);  // careful: D13 is also SCK, so the LED flickers during reads
  SPI.begin();
  rfid.PCD_Init();
  byte v = rfid.PCD_ReadRegister(MFRC522::VersionReg);
  Serial.print(F("RC522 version: 0x"));
  Serial.println(v, HEX);
  if (v == 0x00 || v == 0xFF) Serial.println(F("Not answering - check 3.3V, level shifter and SPI wiring"));
  else Serial.println(F("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);
  }
  bool allowed = rfid.uid.size == 4 && memcmp(rfid.uid.uidByte, ALLOWED, 4) == 0;
  Serial.println(allowed ? F("  -> allowed") : F("  -> unknown"));
  rfid.PICC_HaltA();
  rfid.PCD_StopCrypto1();
  if (allowed) {
    SPI.end();  // free D13 so the LED can show the result
    digitalWrite(LED_BUILTIN, HIGH);
    delay(1500);
    digitalWrite(LED_BUILTIN, LOW);
    SPI.begin();
  }
}

Library: MFRC522 (GithubCommunity) — compiled with MFRC522 1.4.12.

Expected serial output

Serial Monitor · 115200Output
RC522 version: 0x92
Tap a card...
Card UID: 7A 3C 91 2B  -> unknown
Card UID: DE AD BE EF  -> allowed

Common errors

Version 0x00 or 0xFF

No SPI contact: check 3.3 V, the shifter’s LV/HV supplies, and that MISO is not going through a one-way channel. Full fix.

Version reads 0x12 or 0xB2

A clone chip. It usually works; if cards are not detected, lower the antenna gain or try a different module.

↑↓ to move · Enter to open