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 NodeMCU ESP8266 — SPI wiring and UID code

Wire an RC522 RFID reader to a NodeMCU ESP8266 on HSPI (D5–D8) with RST on D0, at 3.3 V, and print card UIDs with the MFRC522 library.

Arduino C++Verified — core esp8266 3.1.2, MFRC522 1.4.12, 3 Nov 2026Compile-only

Community draft — report a mistake

The RC522 is the cheapest way to add card or key-tag access to a project, and on a NodeMCU it pairs naturally with Wi-Fi for attendance logs or door locks that report to a server.

It uses SPI. The ESP8266 has one SPI bus free for you — D5, D6, D7 — plus D8 as chip select. Reset goes to D0, the odd pin that can’t do PWM or interrupts but is fine as a plain output. Both parts are 3.3 V, so the wiring is direct.

Wiring

NodeMCU ESP8266Only the pins used are shown · 3.3 V logicRC522 RFID reader (MFRC522, 13.56 MHz)GND3V3D0D5D6D7D8SDASCKMOSIMISOIRQ (not connected)GNDRST3.3V
Every connection
NodeMCU ESP8266RC522 RFID reader (MFRC522, 13.56 MHz)WireNotes
3V33.3Vred3.3 V only — never VIN.
GNDGNDblack
D5SCKyellowGPIO14, HSPI clock.
D6MISOblueGPIO12, HSPI MISO.
D7MOSIgreenGPIO13, HSPI MOSI.
D8SDApurpleSDA is the RC522’s chip select. D8 (GPIO15) is the usual HSPI CS.
D0RSTorangeGPIO16 as a plain output. IRQ stays unconnected.

3.3 V only part, 3.3 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 ESP8266’s free SPI bus (HSPI) is fixed to D5 = SCK, D6 = MISO, D7 = MOSI. The other SPI pins (SD0–SD3, CMD, CLK) belong to the flash chip — never wire anything there.
  • D8 (GPIO15) must be LOW at reset. It works as chip select because the board pulls it down and the RC522 doesn’t pull it up. If your board stops booting with the reader attached, move SDA to D2 and change SS_PIN.
  • RST is on D0 (GPIO16). D0 has no PWM or interrupts, but a plain reset output is exactly what it is good for — and it keeps D1/D2 free for an I2C display.
  • The RC522 and the ESP8266 are both 3.3 V parts, so no level shifting is needed — the opposite of the Uno, where the signals must be dropped to 3.3 V.
  • Keep the reader’s antenna away from the NodeMCU’s Wi-Fi antenna end and from metal. Range is 2–4 cm with the white card.

Code

rc522-nodemcu.inoArduino C++Open in PlaygroundOpen in PlaygroundFlash
// MFRC522 RFID reader (RC522 module) on a NodeMCU (ESP8266), hardware SPI (HSPI).
// 3.3V → 3V3, GND → GND, SCK → D5 (GPIO14), MISO → D6 (GPIO12), MOSI → D7 (GPIO13),
// SDA (chip select) → D8 (GPIO15), RST → D0 (GPIO16). IRQ is not used.
#include <SPI.h>
#include <MFRC522.h>

const uint8_t SS_PIN = D8;   // GPIO15: the board's pull-down keeps it LOW at boot, which is what it needs
const uint8_t RST_PIN = D0;  // GPIO16: fine as a plain output, and keeps D1/D2 free for I2C
MFRC522 rfid(SS_PIN, RST_PIN);

void setup() {
  Serial.begin(115200);
  Serial.println();
  SPI.begin();
  rfid.PCD_Init();
  delay(10);
  rfid.PCD_DumpVersionToSerial();  // 0x92 = v2.0, 0x91 = v1.0, 0x88 = clone; 0x00/0xFF = wiring problem
  Serial.println("Tap a card or tag");
}

void loop() {
  if (!rfid.PICC_IsNewCardPresent() || !rfid.PICC_ReadCardSerial()) {
    delay(50);
    return;
  }
  Serial.print("UID:");
  for (byte i = 0; i < rfid.uid.size; i++) Serial.printf(" %02X", rfid.uid.uidByte[i]);
  Serial.print("  (");
  Serial.print(rfid.PICC_GetTypeName(rfid.PICC_GetType(rfid.uid.sak)));
  Serial.println(")");
  rfid.PICC_HaltA();
  rfid.PCD_StopCrypto1();
}

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

Expected serial output

Serial Monitor · 115200Output
Firmware Version: 0x92 = v2.0
Tap a card or tag
UID: 4A 3F 9C 1B  (MIFARE 1KB)
UID: 04 5E 21 7A 6B 4F 80  (MIFARE Ultralight or Ultralight C)

Common errors

“Firmware Version: 0x0 = (unknown)” or 0xFF

The ESP8266 can’t talk to the chip: check D5/D6/D7 are not swapped, SDA is on D8 and 3.3V is powered. Full fix.

Board won’t boot with the reader connected

Something is holding D8 high at reset. Move SDA (chip select) to D2 and set SS_PIN = D2.

Reads cards only sometimes

Weak 3V3 supply or long jumper wires. Keep SPI wires under 10 cm and add a 10 µF capacitor across 3.3V/GND at the reader.

↑↓ to move · Enter to open