This post offers an introduction to RFID (Radio Frequency ID) tags and readers.
RFID – pronounced as letters, R-F-I-D or, areFID (less common) is a technology that allows tags, fobs and cards to be read by matching readers. The tags are passive — they do not need power/battery, while readers are powered and connected you your microcontroller.
RFID is analogous to a barcode reader system — but instead of using a visual machine readable code, it uses radio transmission (a tiny radio network) to read tags. While it is technically possible with some systems to write information to tags as well, that is beyond this post.
Here I will only focus on reading tags.
Please note that different readers use different frequencies and it is important to match tags to readers — they are NOT cross-compatible.
We have two kinds of readers and tags. Keep them sorted!
ParalLax readers (5V)
We have a few older parallax readers. These operate at 125kHz and have a rectangular hole in the middle. If you look closely you can see the antenna traces around the edge of the opening.
The range on this reader is about 3in or 10cm.

We have a variety of tags for these readers. The majority look like these disks.

These readers have become ridiculously expensive and are unlikely to be replaced if broken — please use with reasonable care.
The readers are connected to an asynchronous serial port (RX,TX pins) for reading. This creates different challenges depending on which microcontroller you are using.
RC522 readers (3.3V)
We also own a number of RC522 readers. These are newer and use 13,56MHz. a much higher frequency, to communicate with tags.

These have less physical range (~3cm) compared with the parallax readers (~10cm), and connect to your micro controller using the SPI serial protocol. The wiring is very different. As of 2024, we only have the blue keyfob tags for these readers.
These higher frequency tags also store A LOT more information (about 1K) than the lower frequency tags. Most of this data is unnecessary, but it could be useful in projects that want to explore beyond reading IDs.
Connections and Code
There are several setups that arise from the various hardware we have access to. Each has a nuance that you need to be looking out for but all do basically the same thing.
Each combination is linked below:
UNO to Parallax Reader
The quickest setup for learning RFID is to use an Arduino UNO with a PARALLAX reader. It uses serial you are familiar with and only a few connections.
Note: I do not think this example works with the black version of the reader board. We do not have black boards so not an issue for borrowed parts, but in case you go shopping…
Specific to this example:
Given the set up I have chosen, the RFID and the USB cable both talk to the main UNO chip on the same pins. Like software collisions where only one software platform can be connected to your device at a time, this can cause trouble for uploading and then RFID reading.
You will need to connect and remove the BLUE wire between UNO RX and the reader SOUT as described below.
To UPLOAD CODE:
REMOVE the connection between UNO RX (pin0) and the RFID reader"s SOUT pin
TO READ RFID:
RECONNECT RX (pin0) and the RFID reader's SOUT pin
Circuit

Remember, this reader is a 5V device.
Code
Note: multi line comments get split when copy and pasting. If you get unsolvable errors in the Arduino editor use download link at bottom of code.
ESP32 to Parallax Reader
The code for the ESP32 is little more complex than for the UNO. This is due to hardware differences between an ESP32 and the chip that makes and UNO and UNO.
One advantage of the ESP32 setup is you DO NOT have to change the circuit to upload code and change it back to read RFID (see above example).
NOTE: I do not think this example works with the black version of the reader board. We do not have black boards — but in case you go shopping…
Circuit
Remember, this reader is a 5V device. Your esp32 is 3.3V
The Vcc pin on the reader should get connect to the USB pin (5V) on the ESP32 — not to the 3.3V power rail!
Also, the /ENABLE pin is pulled low (connected to ground) to activate. In the UNO example above /ENABLE is connected to a digital pin, which is written low in setup to turn the reader on.
Both strategies work, this system does not let you disable the reader. If that is important, do not connect /ENABLE directly to ground. Rather, connect /ENABLE to a digital pin and write that pin high (disable) or low (enable)

Code
Specific to this example:
The ESP32 has multiple hardware serial options — while the UNO only has one. In almost all other examples (regardless of platform), we simply use the Serial functions set.
This works because the Arduino environment connects Serial (code) to the USB cable on all hardware. This allows us to debug code and see variables.
On the UNO the USB connection is connected (broken out) to PINS 0, 1. So talking to hardware Serial on an UNO also communicates with these pins.
This is not the case in the ESP32.
The ESP32 has a Serial port for the USB cable (Serial) and different serial ports for devices connected to the pins of the microcontroller (Serial1, Serial2). The number suffixes matter – a lot.
This is important to understand because we will be connecting the RFID reader to one set of Serial pins for tag reading (Serial2) AND then debugging the tag value with the familiar Serial (USB) interface.
To use the UART pin interface on an ESP32 you must explicitly define the pins for RX (receive, listen) and TX (transmit, speak).
#define RXD2 16
#define TXD2 17
You must also start the Serial2 port with the line:
Serial2.begin(2400, SERIAL_8N1, RXD2, TXD2);
This sets teh speed — 2400 BAUD – to the speed of the reader. Sets up the bit pattern (SERAIL_8N1) and identifies the correct pins to use.
Finally, to get the data from the RFID reader we connect scissors to Serial2, not Serial
RFID_reader.begin(Serial2);
Full Example
Comments may cut and paste oddly — if you get errors, check that multiline comments did not get split – zip code at bottom.
Using the RC522 RFID reader
This connection uses the SPI interface. SPI is a synchronous serial interface. This means both devices are synchronized with each other through a clock pin.
Naming the Pins – racism’s legacy
There is historically problematic language, due to racism, privilege and white supremacy, in the naming of the signal pins with this protocol. I could ask you to just follow the picture below and ignore it, but I don’t think that is the correct path.
Historically there was a dominance relationship and metaphor (master and slave) used to describe two devices connected with SPI. There is lots written about this — and you can learn more by googling the old terms if you want a fuller understanding.
While I will use new label metaphors, images and pin numbers where possible, you will see TONS of examples and even physical parts labelled using the old terms. This includes many examples attached to Arduino – and this post. As the awareness and transition are relatively recent (2020), you will encounter old labels often.
Our field is riddled with terms arising from privileged communities creating language around new technologies. We should know the history and use the more inclusive terms where possible.
New Pin Labels
The official naming protocols for SPI uses a peripheral and controller metaphor (think star topology) to indicate who is talking and who is listening. This language is excellent — but the associated labels (PICO/POCI) do not match our hardware.
Our RC522 readers use the old labels identified above. It is important that we think about the metaphors we use. It is important that we leave problematic language behind.
In this post I am going to use the wiki language and metaphor for SPI pins. In this convention M stands for MAIN, and S stands for SUB (potentially problematic in other ways). It is a compromise.
The labels on hardware are :
This is not perfect but when you look up pinouts for various devices, it will match.
Circuit – UNO
At least one user has reported that putting the 522 onto a breadboard causes reader errors or fails (https://www.youtube.com/watch?v=pdBrvLGH0PE) .
I have only set these up without a breadboard — YMMV.

Circuit – ESP32 (huzzah)

Specifics to this example:
Software library
You need to install an MFRC522 library to get this to work. I am using the library:
MFRC522 by github community
It can be installed through the Arduino library interface.
Code
The code for the two micro-contollers is almost identical. There is just a small change that is needed to switch between UNO and ESP32.
You need to tell the UNO or ESP where to find the chip select (SS) and reset pins. These are found in the example below at lines 49-55.
You should uncomment the lines that match the microcontroller you are using. And comment-out the lines for the other.
Uno
ESP32
Full example
Comments may cut and paste oddly — if you get errors, check that multiline comments did not get split – zip code at bottom.