MFRC522 Library for Proteus V1.1: two Arduino UNOs with RFID-RC522 boards, the MFRC522 Advance pop-up with its card editor and the TEP Serial Monitor in its Simple interface

MFRC522 Library for Proteus V1.1 (RC522 RFID + Arduino)

2.5K Views
40
700
60
25
60
PCBWay

Hello friends, I hope you all are doing great. Today, I am going to share the new MFRC522 RFID Library for Proteus V1.1. The MFRC522 is NXP's 13.56 MHz RFID reader chip, and the blue RFID-RC522 board built around it is the first card reader most of us connect to an Arduino. With this MFRC522 Library for Proteus, you place MIFARE cards on the reader with a click, and your Arduino reads their UID and memory over SPI with the same MFRC522 Arduino library you use on real hardware.

Version 1.1 replaces the first version of this post. You now get two devices: MFRC522 Simple, with a card panel on the schematic, and MFRC522 Advance, with a pop-up card wallet, a card editor and four measured RFID test tools. The new Arduino RFID Proteus demo is a small access-control system on two Arduino UNOs, with an access LED and our TEP Serial Monitor, shown in its compact Simple interface. Have you read version 1.0? Then jump to "What's New" below.

NOTICE: This library is very special to our team. Our MFRC522 model has the chip's registers, timer and IRQ pin, and its cards answer like real ones, down to the time every frame takes on the air. It took our team a lot of hard work, many test runs and many design changes. Your feedback is the fuel that keeps us going, so please tell us what you think in the comments below or in the MFRC522 Library board of our forum. And if our free libraries help you, you can buy us a coffee. So, let's get started with the MFRC522 Library for Proteus:

MFRC522 Library for Proteus V1.1: two Arduino UNOs with RFID-RC522 boards, the MFRC522 Advance pop-up with its card editor and the TEP Serial Monitor in its Simple interface
Figure: The MFRC522 demo in Proteus 8.5: both nodes, the MFRC522 Advance pop-up and Serial Monitor U4 in the Simple interface.

What is the MFRC522 RFID Reader?

The MFRC522 is a reader IC made by NXP for contactless cards that work at 13.56 MHz. RFID means radio-frequency identification: the reader drives a small radio field from its antenna, and a card held in that field takes its power from it and answers. The card has no battery. The MFRC522 speaks ISO/IEC 14443 A, the standard of NXP's MIFARE cards and NTAG stickers.

The popular RFID-RC522 board (often just "RC522") carries the chip, a 27.12 MHz crystal, a red power LED and a large PCB antenna: the copper loop that fills most of the board. The chip can also talk over UART or I2C, but the board is used with SPI. People use it for door locks, attendance systems, cashless vending and for reading and writing data on cards and NFC stickers. For the hardware background, read our Introduction to MFRC522 and Interfacing of RFID RC522 with Arduino tutorials.

MFRC522, EM18 or PN532: Which RFID Library Do You Need?

Our RFID libraries for Proteus
Your readerCards and interfaceOur library
RFID-RC522 (MFRC522)13.56 MHz MIFARE Classic, Ultralight, NTAG213; SPIThis article
EM18125 kHz tags; serial (UART) outputEM18 RFID Library for Proteus
PN532 NFC13.56 MHz MIFARE Classic and NTAG213; SPI and I2CPN532 NFC Library for Proteus

A 125 kHz tag cannot be read by a 13.56 MHz reader, and the other way round, so pick the library that matches your reader and your cards.

RFID Terms You Will See in This Article

RFID terms
TermMeaning
PCD, PICCThe reader and the card; the library's function names start with them
UIDThe card's unique number: 4 bytes on a MIFARE Classic, 7 bytes on Ultralight and NTAG213
REQA, ATQAThe reader's "is a card there?" request, and the card's 2-byte answer
Anticollision, SELECT, SAKThe reader reads the UID and selects the card; its 1-byte SAK answer tells the card type
AUTHMIFARE Classic authentication with key A or key B of a sector
HLTAThe halt command: the card stays silent until it leaves the field
Block, sector16 bytes; a group of blocks that share two keys
Access bits3 bytes in the sector trailer that say which key may read or write which block
SPIThe 4-wire bus to the Arduino: SCK (clock), MOSI, MISO and SDA (chip select)

How the MFRC522 Reads a Card

Every read, in the simulation and on your desk, is the same short conversation. The MFRC522 Arduino library does it for you, but knowing the steps makes every test tool in this article easy to understand:

  1. REQA / ATQA: the reader asks "is a card there?", and a card in the field answers (PICC_IsNewCardPresent()).
  2. Anticollision: the reader reads the UID, 4 bytes per cascade level; a 7-byte UID needs two.
  3. SELECT: the reader selects that UID, and the card answers with its SAK (PICC_ReadCardSerial() does steps 2 and 3).
  4. AUTH: a MIFARE Classic sector opens only for a reader that knows its key A or key B (PCD_Authenticate()).
  5. READ / WRITE: each READ returns 16 bytes (MIFARE_Read()).
  6. HLTA: the reader halts the card (PICC_HaltA()).

Why a Halted Card Is Not Read Again

A halted card stays powered, but it ignores every new REQA until it leaves the field and comes back. That is why the demo reads a card once per placement. And if a sketch forgets PICC_HaltA()? Then a selected card goes back to IDLE on the next REQA without answering, and answers the one after: the card is found only every other loop. Our v1.1 model does exactly what real cards do.

MIFARE Classic Memory: Sectors, Blocks, Keys and Access Bits

A MIFARE Classic 1K has 16 sectors of 4 blocks of 16 bytes: 16 x 4 x 16 = 1024 bytes (the 4K has 32 sectors of 4 blocks plus 8 of 16). The last block of each sector is its sector trailer: key A, the access bits and key B. In our cards:

  • Block 0 holds the UID, its check byte BCC, the SAK and the ATQA, and it is read-only. CARD 1 starts with DE AD BE EF 22 08 04 00: the BCC 22 is DE XOR AD XOR BE XOR EF.
  • Block 1 holds our demo text, for example "TEP RFID DEMO 09".
  • Every trailer starts with key A FF FF FF FF FF FF (the factory key), the transport access bits FF 07 80 69 and key B FF FF FF FF FF FF.
MIFARE Classic sector trailer in the MFRC522 Advance card editor: key A, access bits FF 07 80 69 and key B of sector 0, and block 0 with the UID DE AD BE EF
Figure: CARD 1, block 3 (the trailer of sector 0) in the card editor (PC render of the window).

The access bits decide which key may read or write each block. The transport setting FF 07 80 hides a surprise: key A can read key B there, and a readable key B cannot be used. Authentication with it succeeds, but every read gets NAK (a "no"). Our model enforces the access table of the MIFARE Classic data sheet.

Classic, Ultralight and NTAG213

MIFARE Ultralight and NTAG213 are simpler: a 7-byte UID, pages of 4 bytes and no keys (Ultralight 16 pages, NTAG213 45). Both answer SAK 00, so the library calls both "MIFARE Ultralight or Ultralight C"; only GET_VERSION tells them apart. NTAG213 is the common NFC sticker, and ours holds an NDEF text record, "TEP RFID DEMO".

What's New in MFRC522 Library for Proteus V1.1

If you used version 1.0, here is what has changed:

  • Two devices in TEPMFRC522.LIB: MFRC522 Simple (MFRC522TEP, the v1.0 device, so old designs keep working) and MFRC522 Advance (MFRC522ADVTEP) with a pop-up window.
  • A redrawn board: the blue RFID-RC522 is now tall, with the antenna as big as on the real board. The antenna glows cyan while the RF field is on and green while a card answers, and the card is drawn on it.
  • Two LEDs: the real board's red PWR LED and a new green CARD LED that flashes on every card exchange, a TEP addition (the real RC522 board has only the power LED).
  • Close and reopen: a red X on the card panel, PANEL / OPEN PANEL on the board.
  • Cards page with a card editor (Advance): Tap or Hold any card, change its type, UID and memory.
  • Four measured test tools: Read test, Card types, Authentication and Register check.
  • Real timing: a frame nobody answers ends with the chip's 25 ms timer (v1.0 answered "no card" at once), and every answer takes its air time at 106 kbit/s.
  • Real RF field and card states: with the antenna off, no card answers; halted cards and cards left selected behave like real ones.
  • More cards: MIFARE Classic 4K and NTAG213 join Classic 1K and Ultralight (TYPE1 - TYPE4).
  • Keys and access bits in every sector trailer, enforced like on a real card.
  • Chip details: the self test passes, CHIPVER sets the version (0x92, 0x91 or the FM17522 clone's 0x88), and the IRQ pin is open drain after a reset (v1.0: push-pull).
  • A two-UNO demo (Simple + Advance) with access LEDs and a new access-control sketch: ADD, DEL, STATUS, DUMP, KEY A, KEY B, ANTENNA ON / OFF and HELP on the TEP Serial Monitor, which replaces the Virtual Terminal.
  • Lighter package: about 1.4 MB, without the C++ source code (v1.0: about 7.5 MB).

MFRC522 Library for Proteus: Simple vs Advance

Both devices run the same MFRC522 model with the same properties; only the panel differs:

MFRC522 Simple vs Advance
FeatureSimpleAdvance
Full MFRC522 model (SPI, registers, timer, IRQ pin, four cards)✔✔
Tall RFID-RC522 board with PWR and CARD LEDs, antenna glow and waves✔✔
The card on the reader drawn on the antenna✔✔
Card panel on the schematic (CARD 1 - 4, REMOVE CARD, last exchanges)✔✘
Card wallet in a pop-up window you can move, resize and minimise✘✔
Tap (0.5 s) and Hold for every card✘✔
Card editor: type, UID keypad, memory, keys and access bits✘✔
Read test, Card types, Authentication and Register check✘✔
TEP Dark / Light theme, text size, Help page with Copy diagnostics✘✔
Same device name as v1.0 (old designs keep working)✔✘

Choose Simple to keep the cards beside your circuit, and Advance when your sheet is full or you want hard numbers about your RFID code. The demo has one of each.

Download MFRC522 Library for Proteus

Click the button below to download MFRC522-RFID-Library-for-Proteus-v1.1.zip (about 1.4 MB, without the C++ source code):

MFRC522 RFID Library for Proteus V1.1
  • README.txt: a detailed guide to the files, the wiring, the cards and the model.
  • Proteus Library Files: TEPMFRC522.LIB (both devices), TEPSERIALMON.LIB and our Arduino UNO library ArduinoV3TEP.LIB / ArduinoV3TEP.IDX.
  • Proteus Model Files: TEPMFRC522.DLL and TEPSERIALMON.DLL.
  • Proteus Simulation: MFRC522-ArduinoUnoV3.pdsprj, MFRC522_Demo.hex and copies of both DLLs.
  • Arduino Code: MFRC522_Demo.ino and the MFRC522 Arduino library 1.4.12 by GithubCommunity (miguelbalboa), unmodified, under the Unlicense.

If you don't have Proteus yet, read How to Download and Install Proteus 7 and 8. New to libraries? Follow How to Install a New Library in Proteus.

How to Install MFRC522 Library for Proteus

  1. Close Proteus and extract the whole zip file.
  2. Copy the four files from Proteus Library Files into the LIBRARY folder, usually C:\Program Files (x86)\Labcenter Electronics\Proteus 8 Professional\LIBRARY (on some PCs C:\ProgramData\Labcenter Electronics\Proteus 8 Professional\LIBRARY).
  3. Copy TEPMFRC522.DLL and TEPSERIALMON.DLL into the MODELS folder.
  4. Start Proteus, press P and search for MFRC522 (or RFID). You get the Simple and the Advance device (category Sensors > RFID).

Updating from v1.0? Replace TEPMFRC522.LIB and TEPMFRC522.DLL, and delete TEPMFRC522.IDX if there is one in LIBRARY. A v1.0 design keeps its old symbol and runs with the new model, with the v1.0 panel (no new board parts, no red X); re-pick the part to get the v1.1 board. Tested in Proteus 8.5; Proteus 7 is not supported.

The RFID-RC522 Board in Proteus

We designed the reader as a clean TEP board in the RC522's blue and made it tall, because on the real board the antenna is the biggest part. Three copper turns fill the top; below them sit the MFRC522 chip, the 27.12 MHz crystal, the red PWR LED and the green CARD LED. Here is the Advance board with CARD 2 halted on the antenna:

RFID-RC522 board of the MFRC522 Advance in Proteus with CARD 2 halted on the antenna, the red PWR LED, the dark CARD LED and the OPEN PANEL button
Figure: MFRC522 Advance (U2): CARD 2 HALTED on the antenna, the ADVANCE badge and OPEN PANEL.

Pinout

The eight pins keep the v1.0 order. The header of a real board reads SDA, SCK, MOSI, MISO, IRQ, GND, RST, 3.3V, so always wire by the names:

MFRC522 pins (3V3 GND SCK MISO MOSI SDA RST IRQ)
PinFunctionDemo connection
3V3Power (3.3 V on a real board)Supply terminal
GNDGroundGND
SCKSPI clock from the ArduinoArduino D13
MISOSPI data from the readerArduino D12
MOSISPI data to the readerArduino D11
SDASPI chip select (SS), active LOWArduino D10
RSTReset, LOW = resetArduino D9
IRQInterrupt output, open drain after a resetNot connected

"SDA" confuses many beginners, because it is also the I2C data line. In SPI mode, it is the chip select (SS_PIN in the sketch).

LEDs, Antenna and Waves

Board animations (the same on both devices)
IndicatorWhat it shows
PWR LED (red)The board has power (3V3 and GND wired)
CARD LED (green)Lit while a card answers the reader (REQA, anticollision, SELECT, AUTH, READ / WRITE) and 0.35 s after the last answer; dark with no card, the antenna off or a halted card
Antenna loopCopper = field off, cyan = field on, green = a card answers (one brighter turn ripples round the loop); the waves above it follow
Card on the antennaType band, CARD n, the UID and the state (IN FIELD, SELECTED, HALTED); "PLACE A CARD HERE · 13.56 MHz" when empty

The board button is PANEL on the Simple (green dot = SHOWN, grey dot = CLOSED) and OPEN PANEL on the Advance.

Component Properties

MFRC522 properties (double-click the reader > Edit Properties)
PropertyMeaningDefault
UID1 - UID4The four card UIDs: 8 hex characters (4 bytes) or 14 (7 bytes)DEADBEEF, 12345678, 04112233445566, A1B2C3D4
TYPE1 - TYPE4AUTO (8 hex = Classic 1K, 14 = Ultralight, as in v1.0), 1K, 4K, UL or NTAG213AUTO
KEYA, KEYBThe MIFARE Classic keys every sector trailer starts with (12 hex characters)FFFFFFFFFFFF
CHIPVERVersionReg: 92 (v2.0), 91 (v1.0) or 88 (FM17522 clone)92

What a sketch writes stays on the card while the simulation runs; every new run starts with fresh cards.

MFRC522 Simple: The Card Panel on the Sheet

Beside the Simple board, we have drawn a card panel. Here it is right after Run. The antenna is already cyan, because the sketch called PCD_Init() and the field is on; the log says ANTENNA ON (TXCONTROLREG 83):

MFRC522 Simple in Proteus right after Run: cyan antenna, PLACE A CARD HERE 13.56 MHz, the red PWR LED and the MFRC522 RFID CARDS panel with NO CARD IN FIELD
Figure: Right after Run: NO CARD IN FIELD, READS 0, VERSION 92 and the field on.
The MFRC522 Simple card panel
PartWhat it does
Header MFRC522 RFID CARDSThe red X closes the panel
State barNO CARD IN FIELD, CARD n: SELECTED BY READER, CARD n: HALTED BY READER, ANTENNA OFF - SKETCH: PCD_Init() or NO POWER
READS, LAST UID, VERSIONCards the sketch has selected, the last UID and the chip's VersionReg
CARD 1 - CARD 4Click one to hold it on the reader; click it again to place it again. The band shows the type: 1K blue, 4K purple, UL teal, NTAG orange
REMOVE CARDTakes the card away (red while a card is on the reader)
LAST EXCHANGES WITH THE CARDThe newest commands and answers, newest at the top

Placing CARD 1: ACCESS GRANTED

Click CARD 1. The card appears on the antenna, the sketch reads it, Serial Monitor U3 prints "-> ACCESS GRANTED" and the access LED D1 lights for 3 s. A moment later, the panel looks like this:

MFRC522 Proteus simulation after CARD 1: CARD 1 HALTED on the antenna, CARD 1: HALTED BY READER, READS 1, LAST UID DE AD BE EF and the exchanges SELECT, AUTH A 1, READ 1 and HLTA
Figure: CARD 1 read and halted: four exchanges, newest at the top.

Read the log from the bottom up: SELECT -> CL1 SAK 08 (a Classic 1K), AUTH A 1 -> OK (key A opened sector 0), READ 1 -> 16 BYTES and HLTA -> CARD HALTED. The card and the state bar say HALTED, REMOVE CARD is red, and the antenna is cyan again: the halted card is silent, so the sketch reads it once. Click CARD 1 again to place it again.

The CARD LED Blinks on Every Read

The green CARD LED lights whenever the card answers and stays on 0.35 s after the last answer, so every read is a short blink. I caught U1 in that moment:

RFID-RC522 board in Proteus during a read: the green CARD LED lit, the antenna loop and waves green, the red PWR LED and CARD 1 on the antenna
Figure: A read in progress: the CARD LED, the antenna and the waves are green.

The antenna and the waves are green, because a card has just answered. The card already says HALTED: the sketch halts it about 100 ms after its READ, inside the 0.35 s. Then the LED goes dark and the antenna turns cyan. PWR stays red the whole time.

CARD 3 and CARD 4: ACCESS DENIED

CARD 3 is a MIFARE Ultralight (UID 04 11 22 33 44 55 66). It needs no key, so the sketch reads its pages 4-7, then prints ACCESS DENIED: the UID is not in its list. CARD 4 (A1 B2 C3 D4), a Classic 1K, is denied too, until we allow it from the Serial Monitor below.

Closing the Panel

Need room on the sheet? Click the red X. The board button says PANEL: CLOSED with a grey dot, while the reader and the sketch keep running. Click PANEL to bring it back.

MFRC522 Simple board in Proteus with the card panel closed: PANEL: CLOSED and CARD 1 still halted on the antenna
Figure: The panel closed: PANEL: CLOSED, CARD 1 is still on the reader.

MFRC522 Advance: The Pop-Up Card Wallet

The Advance device keeps only the board on the schematic. At Run, a TEP pop-up window opens with the look of our TEP Serial Monitor and no Windows title bar: move it by its header, resize or minimise it, and reopen it with OPEN PANEL. The header shows the state (for example U2 · HALTED), the Cards and Test tabs and the theme, Settings and Help icons.

The Cards Page

MFRC522 Advance Cards page in Proteus: the READER card, CARD 2 held and halted, and the card editor with the UID keypad and sector 0 of a MIFARE Classic 1K
Figure: The Cards page: CARD 2 held and halted, its block 1 and sector 0 in the editor.

On the left, the READER card shows the field ("on - looking for cards"), the card and its state ("card 2 - halted by the reader"), the reads and the chip: "92 = v2.0 · SPI 4.00 MHz", a clock measured on your Arduino's SCK pin. Under it are the four cards: Tap puts a card on the reader for 0.5 s, like a quick swipe, and Hold leaves it there until you click Remove the card. I held CARD 2, and U4 printed "TEP RFID DEMO 00" and ACCESS GRANTED (see the first image).

The Card Editor

Click a card to edit it on the right: its type (1K, 4K, UL or NTAG213), a new UID from the hex keypad (or Random) and Apply. Below is its memory, block by block on a Classic, 4 pages at a time on Ultralight and NTAG213; the presets Text, Zeros and Value 100 fill the block, and Write stores it. Block 1 of CARD 2 is 54 45 50 20 52 46 49 44 20 44 45 4D 4F 20 30 30, "TEP RFID DEMO 00" in ASCII. Under it, the editor decodes the keys ("Key A FF FF FF FF FF FF · key B FF FF FF FF FF FF"), the access bits ("FF 07 80: read/write A|B (transport)") and shows the whole of sector 0: B0 starts with 12 34 56 78 08 08 04 00 (UID, BCC, SAK and ATQA), and B3 is the trailer.

The editor really writes the card: write a trailer, and that sector's keys change. A type change resets the memory, and a 4-byte UID on an Ultralight or NTAG213 becomes 04 + the 4 bytes + 80 01. Here is CARD 4 turned into an NTAG213:

MFRC522 Advance card editor with CARD 4 changed to NTAG213: UID 04 A1 B2 C3 D4 80 01 and pages 4-7 with the NDEF text record
Figure: CARD 4 as an NTAG213: 45 pages, the NDEF record in pages 4-7 (PC render of the window).

Its UID is now 04 A1 B2 C3 D4 80 01. Pages 4-7 start with 03 14 D1 01 10 54 02 65 6E: an NDEF message with one text record (54 is "T"), the language "en", then "TEP RFI..." of our text. Hold it, and the sketch prints these pages.

The Test Page: Four Measured RFID Test Tools

The Test tab has four tools. They only place cards on the reader and read the reader's own log; they never talk to your Arduino. So every number is what your sketch's SPI traffic and the card really did, measured with the simulation clock. A tool refuses to start, with the reason, when the reader has no power, the antenna is off or another test runs.

1. Read Test: How Fast Does Your Sketch Read a Card?

Choose a card, the tap length (0.2, 0.5 or 1 s) and 3, 5 or 10 runs. The tool taps the card and times every step from the tap: detected (REQA answered), the UID (SELECT), AUTH, READ and HLTA. Card 1, five taps of 0.5 s:

MFRC522 read test in Proteus: card 1, five taps of 0.5 s, 5 of 5 detected, UID after 13.7 ms, block read after 19.6 ms, HLTA after 120 ms
Figure: Read test: 5 / 5 detected, the UID after 13.7 ms and the block after 19.6 ms on average.

All five taps were read. Detection took 3.83 to 21.07 ms: it depends on where your loop() is when the card arrives, because a REQA with no card waits 25 ms for the timer. Then the steps are steady: the UID 2.8 ms later, AUTH 3.4 ms after that and the READ 2.4 ms later. The big one is HLTA, about 100 ms after the READ. That is not the card; it is the sketch printing its lines at 9600 baud before it halts the card. Good for: seeing how fast your loop() notices and reads a card.

2. Card Types: Does Your Sketch Read Every Card?

This tool holds one test card of each type on the reader for 1 s and lists what your sketch did with it:

MFRC522 card types test in Proteus: MIFARE Classic 1K, Classic 4K, Ultralight and NTAG213, 4 of 4 detected, read and halted
Figure: Card types: 4 / 4 detected, 4 / 4 data read, 4 / 4 halted.
The Card types test with the demo sketch
CardATQA, SAK, UIDWhat the demo sketch did
Classic 1K04 00, 08, 4 bytes (1 cascade level)REQA, SELECT (4 B UID), AUTH A 1 ok, READ 1 ok, HLTA
Classic 4K02 00, 18, 4 bytes (1 cascade level)REQA, SELECT (4 B UID), AUTH A 1 ok, READ 1 ok, HLTA
Ultralight44 00, 00, 7 bytes (2 cascade levels)REQA, SELECT (7 B UID), READ 4 ok, HLTA
NTAG21344 00, 00, 7 bytes (2 cascade levels)REQA, SELECT (7 B UID), READ 4 ok, HLTA

The grey line under each card is what the library's PICC_GetType() makes of the SAK, and the UID reached the Arduino after 17.5 ms on average. Good for: checking that your sketch handles 4- and 7-byte UIDs, Classic and NTAG.

3. Authentication: Which Key Does Your Sketch Send?

This tool uses a Classic 1K test card (UID A0 7E 51 22) in three set-ups: Keys as set, Key A changed (A0 A1 A2 A3 A4 A5 on the card) and Key B only (access bits 0F 00 FF: the data blocks need the secret key B). Each run shows the key your sketch sent, read from the chip's MFAuthent command, and both answers. Key A changed, three runs:

MFRC522 authentication test in Proteus with key A changed: the sketch sent A FF FF FF FF FF FF, the card has A0 A1 A2 A3 A4 A5, no answer after 26.53 ms
Figure: Key A changed: 0 / 3 answered; the reader's timer ends each AUTH after 26.53 ms.

The sketch sent key A FF FF FF FF FF FF, but the card expects A0 A1 A2 A3 A4 A5. A real MIFARE card does not say "wrong key": it stays silent. So the reader's timer ends the AUTH after 26.53 ms, and the demo prints "Authentication failed: Timeout in communication." Now Key B only:

MFRC522 authentication test with key B only: AUTH ok in 1.95 ms three times, but every READ gets NAK
Figure: Key B only: AUTH ok in 1.95 ms, READ NAK (PC render of the window).

This time AUTH answers "ok - sector open" in 1.95 ms, 3 / 3, but the access bits allow the data blocks only with key B, so every READ gets NAK ("MIFARE_Read failed: A MIFARE PICC responded with NAK." in the demo). Type KEY B on the Serial Monitor, run it again, and both are ok. Good for: seeing which key your sketch really sends.

4. Register Check: What Did Your Sketch Set in the Chip?

The last tool shows the MFRC522's registers right now, decoded, and the SPI traffic:

MFRC522 register check in Proteus: TxControlReg 83 antenna ON, RxGain 33 dB, timer 25.03 ms, VersionReg 92 v2.0, SPI 4.00 MHz and the last card exchanges
Figure: Register check: what PCD_Init() set, SPI 4.00 MHz and the last card exchanges.
  • RF: TxControlReg 83 = antenna ON, ModeReg 3D = CRC preset 6363 (ISO 14443A), TxASKReg 40 = 100 % ASK, RFCfgReg 48 = RxGain 33 dB.
  • Timer: TPrescaler 0A9, TReload 1000 = 25.03 ms, our "no answer" time. 0A9 is 169, so the timer ticks at 13.56 MHz / (2 x 169 + 1) = 40 kHz, and 1001 ticks of 25 µs make 25.03 ms.
  • Chip and traffic: VersionReg 92 = v2.0, SPI clock 4.00 MHz, 3797 frames sent and 3744 without an answer, mostly REQAs of loops without a card.

The right column lists the last card exchanges of the Authentication test: REQA: ATQA 04 00 (0.36 ms), SELECT: CL1 SAK 08 (1.14 ms), AUTH A blk 1: wrong key (26.53 ms) and HLTA: card halted (25.38 ms). Even HLTA takes 25 ms, because a card never answers HLTA. Then "REQA: no answer x32": the halted card stayed in the field and kept silent. Good for: checking what your sketch set in the chip.

Settings and Help

The gear opens Settings: theme (TEP Dark or Light), text size, open the panel at Run and the window size, saved for your Windows user.

Settings page of the MFRC522 Advance pop-up: theme, text size, open the panel at Run and window size
Figure: Settings, saved under HKCU\Software\TheEngineeringProjects\TEP MFRC522 Advance.

The ? icon opens Help & Support: eight cards (bug report, feature request, article, user guide, updates, donate, website, forum) and Copy diagnostics, which copies the reader, its registers, the cards and the test results for a bug report. Cards whose link is not published yet say "Link coming soon"; a links.ini file next to the DLL can change them.

Help and Support page of the MFRC522 Advance with eight cards and the Copy diagnostics button
Figure: Help & Support: TEP MFRC522 Advance v1.1, build 2026-10-06.

MFRC522 Access Control with Arduino in Proteus

Open MFRC522-ArduinoUnoV3.pdsprj from the Proteus Simulation folder. It has two Arduino UNOs from our Arduino Library for Proteus V3.0, both running MFRC522_Demo.hex (the first image of this article shows the whole circuit):

  • NODE 1: UNO 1 (ARD1) with the MFRC522 Simple (U1), the access LED D1 on A0 and Serial Monitor U3.
  • NODE 2: UNO 2 (ARD2) with the MFRC522 Advance (U2), the access LED D2 on A0 and Serial Monitor U4.

Wiring

Demo wiring (the same on both UNOs, as in the v1.0 demo)
FromToWhy
MFRC522 3V3 / GNDSupply / groundPower
MFRC522 SCKArduino D13SPI clock
MFRC522 MISOArduino D12Data from the reader
MFRC522 MOSIArduino D11Data to the reader
MFRC522 SDAArduino D10Chip select (SS_PIN)
MFRC522 RSTArduino D9Reset (RST_PIN)
MFRC522 IRQOpenNot used by the sketch
LED + 220 ΩA0 to GNDThe access LED, 3 s on ACCESS GRANTED
Serial Monitor RXD / TXD / GNDArduino D1 / D0 / groundShows what the Arduino prints, sends what you type

D11, D12 and D13 are the UNO's hardware SPI pins, so the sketch doesn't name them; SS and RST can be any pins (see our Introduction to Arduino UNO). In the simulation, 3V3 goes to the power terminal; the model only checks that it is powered.

The Arduino Code

The sketch uses the unmodified MFRC522 Arduino library by GithubCommunity (miguelbalboa). It starts with the pins:

#define SS_PIN  10
#define RST_PIN 9
#define LED_PIN A0
const unsigned long LED_MS = 3000;
const byte MAX_ALLOWED = 8;

MFRC522 rfid(SS_PIN, RST_PIN);

In setup(), PCD_Init() resets the chip, sets its 25 ms timer and switches the antenna on, and the key gets the factory default:

  Serial.begin(9600);
  SPI.begin();
  rfid.PCD_Init();
  for (byte i = 0; i < 6; i++) key.keyByte[i] = 0xFF;   // factory default key

The loop() polls for a card. These two lines are steps 1 - 3 of the conversation above:

  if (!rfid.PICC_IsNewCardPresent()) return;   // REQA every loop; a card answers once placed
  if (!rfid.PICC_ReadCardSerial()) return;     // anticollision + select

For a Classic card, the sketch authenticates block 1 with key A (or key B after KEY B) and reads it:

    MFRC522::StatusCode status = rfid.PCD_Authenticate(useKeyB ? MFRC522::PICC_CMD_MF_AUTH_KEY_B : MFRC522::PICC_CMD_MF_AUTH_KEY_A, 1, &key, &rfid.uid);
    if (status == MFRC522::STATUS_OK) {
      byte buffer[18]; byte size = sizeof(buffer);
      status = rfid.MIFARE_Read(1, buffer, &size);

Why 18 bytes for a 16-byte block? The card adds a 2-byte CRC. New in v1.1: Ultralight and NTAG cards need no key, so the sketch reads their pages 4-7 directly:

  // Ultralight / NTAG (v1.1): pages 4-7 need no key
  else if (type == MFRC522::PICC_TYPE_MIFARE_UL) {
    byte buffer[18]; byte size = sizeof(buffer);
    MFRC522::StatusCode status = rfid.MIFARE_Read(4, buffer, &size);

Then comes the decision: the access LED lights for 3 s, and the card is halted:

  if (isAuthorised(rfid.uid)) {
    Serial.println(F("  -> ACCESS GRANTED"));
    digitalWrite(LED_PIN, HIGH); ledOn = true; ledOffAt = millis() + LED_MS;
  } else Serial.println(F("  -> ACCESS DENIED"));

  rfid.PICC_HaltA();        // card stays silent until it is removed and placed again
  rfid.PCD_StopCrypto1();

PCD_StopCrypto1() ends the encrypted session of the authentication; without it, the reader cannot start a new communication. The decision uses the UID only, as in v1.0, but the allowed list now holds up to 8 UIDs of 4 or 7 bytes (v1.0: 4-byte UIDs only):

struct AllowedUid { byte size; byte uid[7]; };
AllowedUid allowed[MAX_ALLOWED] = { {4, {0xDE, 0xAD, 0xBE, 0xEF}}, {4, {0x12, 0x34, 0x56, 0x78}} };

The Serial Monitor command ADD appends the last card read, or a typed UID, to that list:

      allowed[allowedCount].size = size; memcpy(allowed[allowedCount].uid, uid, size); allowedCount++;
      Serial.print(F("Added ")); printHex(uid, size); Serial.print(F(" (")); Serial.print(allowedCount); Serial.println(F(" allowed)"));

The list lives in the UNO's RAM, so a reset brings back the two default cards. If you change the sketch, load the new HEX file into both UNOs; see How to get the HEX file from Arduino. New to Arduino? Start with our Arduino Tutorial for Beginners.

Serial Monitor Commands

Commands of the demo sketch (monitor quick buttons: STATUS, ADD, DEL, DUMP)
CommandWhat it does
HELPThe command list
STATUSReads, allowed UIDs, key, antenna, LED and reader version
ADD [uid]Allows the last card read, or a UID in hex (8 or 14 digits, spaces allowed)
DEL [uid]Removes it from the list
DUMPPrints the next card's whole memory (PICC_DumpToSerial)
KEY A / KEY BThe key type that opens sector 0 for the block 1 read
ANTENNA ON / OFFPCD_AntennaOn() / PCD_AntennaOff(): with the field off, no card answers

How to Run the Demo

  1. Open the project, with the .hex file and both DLLs beside it, and press Run. Both Serial Monitors and U2's pop-up open, and both antennas turn cyan.
  2. On U1's panel, click CARD 1 (granted, D1 lights), CARD 3 and CARD 4 (denied).
  3. Type ADD in U3's send box and click CARD 4 again: granted.
  4. In U2's pop-up, Tap, Hold and edit the cards, and run the four tools.

MFRC522 Proteus Simulation Results

The Serial Monitor in Its Simple Interface

Both monitors in this demo run in the Simple interface of our TEP Serial Monitor, and every monitor screenshot in this article shows them that way. It keeps only the log, the send box and one slim toolbar row: baud rate, follow, pause, search and clear. The header, the quick buttons and the status bar are hidden, so the window stays small next to your schematic.

  • Switch to it: right-click the log and choose Simple interface, or press Ctrl+Shift+U.
  • Back to the full view: click the corner button (the expand arrows at the top right), press Esc or Ctrl+Shift+U, or right-click and choose Full interface.
  • Your choice is remembered.

In the Simple interface, type commands such as STATUS or ADD in the send box and press Enter; the quick buttons (STATUS, ADD, DEL, DUMP) come back with the full view. RXD2, the monitor's second input, is not used: the reader is an SPI device, so there is no serial line to watch. Read all about the monitor in TEP Serial Monitor Advance for Proteus.

Start-Up and CARD 1

After Run, each monitor prints the banner. Here is U3 after I clicked CARD 1:

Arduino RFID Proteus output in the TEP Serial Monitor Simple interface: TEP MFRC522 RFID Reader Demo v1.1, Firmware Version 0x92 = v2.0 and CARD 1 ACCESS GRANTED
Figure: U3 in the Simple interface: the banner and Read #1 (CARD 1).
TEP MFRC522 RFID Reader Demo v1.1
Reader firmware: Firmware Version: 0x92 = v2.0
Authorised: DE AD BE EF, 12 34 56 78
Click a card on the reader panel...
Serial Monitor: HELP, STATUS, ADD [uid], DEL [uid], DUMP, KEY A, KEY B, ANTENNA ON / OFF

Read #1
  UID : DE AD BE EF
  SAK : 0x8
  Type: MIFARE 1KB
  Block 1: 54 45 50 20 52 46 49 44 20 44 45 4D 4F 20 30 39  "TEP RFID DEMO 09"
  -> ACCESS GRANTED

"Firmware Version: 0x92 = v2.0" is the library reading VersionReg, the proof that SPI works (a wiring fault gives 0x0 or "Communication failure"). Read #1 shows the UID, the SAK 0x8 (0x08 without its leading zero), the type name "MIFARE 1KB" and block 1, where 54 45 50 is "TEP" in ASCII. The last digit comes from the last UID byte: 0xEF is 239, which ends in 9, so CARD 1 says 09.

CARD 2 and CARD 3

U4 shows the read of CARD 2, held on the Advance pop-up: UID 12 34 56 78, "TEP RFID DEMO 00", ACCESS GRANTED.

TEP Serial Monitor U4 in the Simple interface: Read #1 of CARD 2, UID 12 34 56 78, TEP RFID DEMO 00, ACCESS GRANTED
Figure: U4: CARD 2 held on the Advance pop-up, granted.

CARD 3, the Ultralight, prints its pages instead of block 1 (the expected output from the README):

Read #2
  UID : 04 11 22 33 44 55 66
  SAK : 0x0
  Type: MIFARE Ultralight or Ultralight C
  Pages 4-7: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  "................"
  -> ACCESS DENIED

Its pages 4-7 are still empty, and its 7-byte UID is not in the list, so it is denied.

Typing Commands: ADD Allows CARD 4

Now the best part of the new sketch. I clicked CARD 4 and got ACCESS DENIED. Then I typed ADD in U3's send box, pressed Enter and clicked CARD 4 again. Lines you send carry a blue TX tag, the Arduino's lines a green RX tag:

TEP Serial Monitor Simple interface in Proteus: CARD 4 ACCESS DENIED, ADD typed in the send box, Added A1 B2 C3 D4 (3 allowed), then CARD 4 ACCESS GRANTED
Figure: U3: ADD typed in the send box, and CARD 4 is granted.
Read #3
  UID : A1 B2 C3 D4
  SAK : 0x8
  Type: MIFARE 1KB
  Block 1: 54 45 50 20 52 46 49 44 20 44 45 4D 4F 20 30 32  "TEP RFID DEMO 02"
  -> ACCESS DENIED
ADD
Added A1 B2 C3 D4 (3 allowed)

Read #4
  UID : A1 B2 C3 D4
  SAK : 0x8
  Type: MIFARE 1KB
  Block 1: 54 45 50 20 52 46 49 44 20 44 45 4D 4F 20 30 32  "TEP RFID DEMO 02"
  -> ACCESS GRANTED

ADD took the last card read, and the list grew to 3 UIDs. Read #4 is the same card, now granted. In v1.0, this meant editing the sketch and building a new HEX file. DEL removes it again, and STATUS prints the list.

Troubleshooting

  • "Firmware Version: 0x0" or "Communication failure": check SCK -> D13, MISO -> D12, MOSI -> D11, SDA -> D10, RST -> D9 and 3V3 / GND (the PWR LED must be lit).
  • No card is detected: the antenna must be cyan; the sketch must call PCD_Init(), and after ANTENNA OFF it needs ANTENNA ON.
  • A card is read once only, or only every other loop: the first is correct (it is halted); the second means your sketch forgot PICC_HaltA().
  • "Authentication failed: Timeout in communication." or "...responded with NAK.": wrong key, or access bits that refuse that key; the Authentication tool shows both keys.
  • Each loop() without a card takes about 26 ms: correct, the timer waits 25 ms for an answer.
  • No panel, pop-up or monitor: a DLL is missing from MODELS and the project folder; click OPEN PANEL or OPEN MONITOR.
  • No red X / the board looks like v1.0: replace the LIB, delete TEPMFRC522.IDX and re-pick the part.

Things to Know Before Using a Real RC522

The demo sketch uses only the standard MFRC522 library, so it runs on a real UNO and RC522 too. Keep in mind:

  • 3.3 V module: feed 3V3 from the Arduino's 3.3 V pin (up to about 26 mA), never from 5 V.
  • 5 V signals: the UNO's SCK, MOSI, SS and RST are 5 V outputs, but the MFRC522's inputs are specified up to its 3.3 V supply. Use a level shifter, or 1 k / 2 k dividers on those four lines; many boards survive 5 V for a while, but it is out of spec. MISO (3.3 V) is read correctly by the UNO.
  • IRQ: open drain after a reset (active LOW); if you use it, add a 10 k pull-up to 3.3 V and wire it to D2 or D3.
  • Range: a few centimetres, and metal near the antenna detunes it. The simulation has no distance: a card is in the field or not.
  • Security: a UID is not a secret. Cards with a copied UID exist, and the Crypto1 encryption of MIFARE Classic is known to be weak, so a UID list is fine for learning, but not for a real door.

Limitations of the Simulation

  • Not modelled: Crypto1 on the air (keys are compared directly), several cards at once (collisions), the RF level, distance and antenna tuning, the UART / I2C host interfaces, MIFARE Plus / DESFire cards and the NTAG password.
  • The model is our own implementation, written from NXP's published data sheets and ISO/IEC 14443-3; it contains no NXP firmware or code.
  • Tested in Proteus 8.5 on 6 Oct 2026 (the CARD LED in a second run the same day) and with 1,639 automatic checks on the PC, all passed, 104 of them with the unmodified MFRC522 library driving the model bit by bit over SPI. The images marked "PC render" were drawn by the model's own code. Proteus 7 is not supported.

Need a 125 kHz reader? See our EM18 RFID Library for Proteus; for NFC over SPI or I2C, our PN532 NFC Library for Proteus. To send a UID somewhere, add our HC-05 Library for Proteus or HC-12 Library for Proteus, text an alarm with our SIM800L Library for Proteus, or stamp each read with the time and place from our NEO-6M Library for Proteus.

So, that was all about the MFRC522 RFID Library for Proteus V1.1. I hope the card panel, the card editor and the four test tools make RFID much easier to understand, so your access-control project works the first time you wire a real RC522. If you use the MFRC522 Library for Proteus in a project, please share your feedback in the comments or in our forum, and if you have any questions, ask in the comments and I will help you out. Till the next tutorial, take care and have fun!


Comments

0

Join the conversation