Learn

An Arduino RFID door with the RC522 reader

Intermediate

Or see every lesson.

  • 261parts on the bench
  • 31boards running now
  • 1.00xreal time, on every board
Arduino Uno: RFID door with an RC522live0.000 s 0.00x
Click to open it in the editor
The RFID door example on a simulated ATmega328P. Tap a card: the UID prints, and the green or red LED answers.

The RC522 is the blue RFID board that comes in almost every Arduino kit, with a white card and a blue key fob in the bag. Hold a card near it and the board reads the card’s ID number. That is all you need to build a door lock, a time clock or a "who is here" logger.

The circuit above is an Arduino Uno with an RC522 and two LEDs. Tap a card beside the reader and the Uno prints its ID. Two of the four cards light the green LED. The other two light the red one. It runs in your browser on the same sketch you can read below, so you can change the list of cards and run it again.

What you need

  • An Arduino Uno
  • An RC522 (MFRC522) RFID module with its card and key fob
  • A green LED and a red LED, each with a 220 ohm resistor
  • A half-size breadboard and jumper wires

Wiring

Part and pinGoes toNote
RC522 SDAPin 10This is the SPI chip select, even though it is labeled SDA
RC522 SCKPin 13SPI clock
RC522 MOSIPin 11Data from the Uno to the reader
RC522 MISOPin 12Data from the reader to the Uno
RC522 RSTPin 9Reset; the sketch names this pin
RC522 3.3V3.3 VNot 5 V
RC522 GNDGNDShared ground
RC522 IRQNot connectedMost sketches leave it unwired
Green LEDPin 7Through a 220 ohm resistor to GND
Red LEDPin 6Through a 220 ohm resistor to GND

How the reader finds a card

The RC522 talks to 13.56 MHz cards, the same kind used for hotel keys and bus passes. Every card has a UID, a short ID number set at the factory. The white MIFARE card has a four-byte UID. An NFC sticker has a seven-byte one.

The Uno talks to the reader over SPI, which is four wires: a clock, a wire each way for data, and a chip select. The MFRC522 library does the hard part. Your sketch asks two questions in a row: is there a new card, and can you read its serial number? If both answers are yes, the UID is waiting in reader.uid.

The sketch, step by step

In setup(), the sketch starts SPI and the reader, then prints the reader’s firmware version. That one line is your wiring test. On a good connection it prints "Firmware Version: 0x92 = v2.0".

In loop(), it waits for a card. When one arrives, it prints each byte of the UID in hex. Then it checks the UID against a short list called ALLOWED. A match lights the green LED for a second and a half. Anything else lights the red one.

The last call, PICC_HaltA(), puts the card to sleep. A sleeping card stays quiet until it leaves the field. That is why a card left on the reader opens the door once, not once every loop. Tap it off and on again to read it again.

The loop, from the RFID door example
void loop()
{
    if (!reader.PICC_IsNewCardPresent() || !reader.PICC_ReadCardSerial()) {
        return;
    }
    Serial.print("UID:");
    for (byte i = 0; i < reader.uid.size; i++) {
        Serial.print(reader.uid.uidByte[i] < 0x10 ? " 0" : " ");
        Serial.print(reader.uid.uidByte[i], HEX);
    }
    Serial.println();

    int led = onTheList() ? GREEN_LED : RED_LED;
    Serial.println(led == GREEN_LED ? "Welcome in." : "Not this card.");
    reader.PICC_HaltA();

    digitalWrite(led, HIGH);
    delay(1500);
    digitalWrite(led, LOW);
}

Fixing "Firmware Version: 0x0 = (unknown)"

This is the RC522 error people ask about most. The full message is "Firmware Version: 0x0 = (unknown)" and then "WARNING: Communication failure, is the MFRC522 properly connected?" It means the Uno asked the reader a question and got nothing back.

You can make it happen on purpose here. Open the circuit in the editor and delete the MISO wire, or the 3.3 V wire, and press Run. The serial monitor prints that exact warning. Put the wire back and the version line comes back too.

On a real desk, check these in order. Is MISO on pin 12 and MOSI on pin 11, not swapped? Is SDA on the pin your sketch names (10 here)? Does the module get 3.3 V and a shared ground? Are the header pins soldered to the module? A module with loose pins just pressed into the holes is a very common cause.

Add your own card

You do not need to know a card’s UID ahead of time. Tap any card and copy the four bytes the serial monitor prints. Paste them into ALLOWED as a new line, like {0xC3, 0x5A, 0x1E, 0x94}, and run the sketch again. That card now opens the door.

You can also change the cards themselves. Click the reader and look at its uids property in the properties panel. It holds up to four cards as hex bytes, split by commas.

Try it in the editor

Change the delay(1500) to delay(5000) and the door stays open for five seconds. Add a buzzer on another pin that beeps for the red card.

Swap the green LED for a servo and you have a real latch. The Servo library works here the same way it does on a real Uno.

Common mistakes

Powering the module from 5 V. The RC522 is a 3.3 V board. Use the Uno’s 3.3 V pin.

Mixing up SDA and the reset pin. The library’s constructor takes the chip select pin first and the reset pin second: MFRC522 reader(10, 9).

Expecting a card to read on every loop. After PICC_HaltA(), a card must leave the field and come back before it reads again.

Comparing a seven-byte sticker against a four-byte list. Check reader.uid.size first, as the example does.

Questions

Which pins does an RC522 use on an Arduino Uno?

SCK to 13, MOSI to 11, MISO to 12, SDA (chip select) to 10 and RST to 9, with 3.3 V and ground. Pins 11, 12 and 13 are the Uno’s SPI pins, so they are fixed. SDA and RST can move if you change the numbers in the sketch.

Why does my RC522 say "Firmware Version: 0x0"?

The Uno got no answer from the reader. It is almost always wiring: MISO and MOSI swapped, no 3.3 V, no shared ground, the wrong SDA pin in the sketch, or header pins that are not soldered. Pull a wire in the circuit above and you will see the same message.

Can the RC522 write to a card?

Yes. With the right key, MIFARE_Read and MIFARE_Write work on a MIFARE Classic card here, and what you write stays on the card for the rest of the run. Every sector’s key is FF FF FF FF FF FF as delivered.

What does Mokxi not model on the RC522?

The radio. There is no range, no field strength and no two cards colliding. Only one card sits on the antenna at a time. The chip’s registers, its SPI link and the way cards answer are modeled from the datasheets.

Build this for real

Open the editor, change a value and watch the number move with it. Nothing to install, and no account needed.