RFID cards and tags are everywhere! We use them in buildings for access control. Printers and photocopiers can use them to identify staff members. Livestock tagging and pet identification tags all use a form of RFID. The tech to read an RFID device is cheap, for around $5 you can get the reader, and for $4, a Raspberry Pi Pico can read the IDs from the cards / tags.
In this how to, we will learn how to read RFID tags and cards using an MFRC522 reader and a Raspberry Pi Pico, the goal will be to create a fictional RFID access control system that will allow users into a building, or alert security to remove them. Before we can do that, we need to identify the ID of our cards / tags. The first section of this how to will do just that, and then we will insert some code to control two LEDs to simulate the locking mechanism.
For this how to you will need
- Raspberry Pi Pico running MicroPython
- MFRC522 RFID reader
- Large breadboard
- 11 x Male to male jumper wires
- Green LED
- Red LED
- 2 x 100 Ohm resistors (Brown – Black – Brown – Gold)
Building the Hardware
The hardware build is split into two sections. First is the wiring for the MFRC522 RFID reader. The reader uses SPI to communicate with the Raspberry Pi Pico and it requires seven pins to do so. Two are for power (3.3V and GND) and the rest are for SPI.
MFRC522 | Raspberry Pi Pico | Wire Color |
---|---|---|
SDA | GP1 | Blue |
SCK | GP2 | Orange |
MOSI | GP3 | Purple |
MISO | GP4 | Blue |
GND | Any GND | Black |
RST | GP0 | White |
3.3 | 3V3 Out (Physical pin 36) | Red |
Second are our outputs. To see if the correct card has been presented, we need to add two LEDs. Red for an incorrect RFID card, green for a correct card. The LEDs connect to a GPIO pin which we control to turn the LED on/off, and to any available GND pin via a 100 Ohm resistor. You can use a 220 or 330 Ohm resistor, I just happened to have some 100 Ohm resistors on my desk. Need to work out the correct resistor? We’ve got a guide for you!
Header Cell – Column 0 | Raspberry Pi Pico | Wire Color |
---|---|---|
Red LED Anode (+) | GP14 | Red |
Red LED Cathode (-) | Any GND | Black |
Green LED Anode (+) | GP15 | Green |
Green LED Cathode (-) | Any GND | Black |
Before moving on, check that your wiring is correct.
Installing the RFID Reader Software
The MFRC522 is a simple RFID reader, and to make it even simpler we are using a MicroPython module that will make short work of using the reader. The module, pico-rfid is from friend of Tom’s Hardware, Kevin McAleer, and is based on the work of Danjperron.
1. Connect your Raspberry Pi Pico to your computer, and open Thonny. We assume that you already know how to set up your Raspberry Pi Pico. If not, we have this handy guide.
2. Create a new blank file and copy the contents of this link into the blank file. Then save it to the Raspberry Pi Pico as mfrc522.py. This is the Python module / library that will enable our code to talk to the RFID reader.
Writing the Project Code
With all the setup complete, we now get down to coding the project. For this we will again use Thonny, and write code to check the ID of any RFID card presented to the reader. For this first part, we will need to make a note of the ID, as we will later use it with a conditional test that checks if the ID matches a hard coded value, then it will allow entry. If not, then we will get an ACCESS DENIED message.
1. Create a new blank file in Thonny.
2. Import three modules (libraries) for using the MFRC522 RFID reader, controlling the pace of the code, and for using the GPIO.
from mfrc522 import MFRC522
import utime
from machine import Pin
3. Create an object, reader, to tell the code where the RFID reader is connected.
reader = MFRC522(spi_id=0,sck=2,miso=4,mosi=3,cs=1,rst=0)
4. Create two objects for the red and green LEDs, telling the code where the LEDs are connected and that they are output devices that we want to send current to.
red = Pin(14, Pin.OUT)
green = Pin(15, Pin.OUT)
5. Write a short message to the user, instructing them to present the card to the reader. The “\n” is Python’s syntax to introduce a new line at the end of the print() function.
print("Present the card to the reader\n")
6. Create a list called “PreviousCard” and store the value zero inside of it. We’ll use this list later to store the current card ID.
PreviousCard = [0]
7. Create a while True loop to continually run the code within it.
while True:
8. Initialize the reader so that it is ready for use.
reader.init()
9. Create a tuple to store the reader status and the RFID tag type.
(stat, tag_type) = reader.request(reader.REQIDL)
10. An if conditional will read the contents of the card if the reader is ready. Then it will update the stat and uid objects with details from the card.
if stat == reader.OK:
(stat, uid) = reader.SelectTagSN()
11. If the uid of the card is the same as the value stored in the PreviousCard object, then the code will continue. This will happen when the same card is repeatedly shown to the reader.
if uid == PreviousCard:
continue
12. Create an if conditional statement to check that the card read was ok.
if stat == reader.OK:
13. Print a message to the user, and then store the card’s UID to an object called “card”. Then print the card details to the Python shell.
print("The card details are as follows")
card = reader.tohexstring(uid)
print(card)
14. Update the PreviousCard object with the uid of the presented card.
PreviousCard = uid
15. Create an else condition which will run when no cards are presented. Updating the PreviousCard object. Then add a 50ms pause to the code before the main loop repeats.
else:
PreviousCard=[0]
utime.sleep_ms(50)
16. Save the code to the Raspberry Pi Pico as reader.py and then click on Run >> Run Current Script (or press the green play button). Follow the instructions and present the RFID card / tag to the reader.
17. Copy the entire card details, this is the uid of the RFID card and we will need that for the next part of this how to. The uid looks something like this, yours will be different.
[0x04, 0xBC, 0xA0, 0x9A, 0xB3, 0x43, 0x80]
Complete Code Listing
from mfrc522 import MFRC522
import utime
from machine import Pin
reader = MFRC522(spi_id=0,sck=2,miso=4,mosi=3,cs=1,rst=0)
red = Pin(14, Pin.OUT)
green = Pin(15, Pin.OUT)
print("Present the card to the reader\n")
PreviousCard = [0]
while True:
reader.init()
(stat, tag_type) = reader.request(reader.REQIDL)
if stat == reader.OK:
(stat, uid) = reader.SelectTagSN()
if uid == PreviousCard:
continue
if stat == reader.OK:
print("The card details are as follows")
card = reader.tohexstring(uid)
print(card)
PreviousCard = uid
else:
PreviousCard=[0]
utime.sleep_ms(50)
We’ve got the code, now we need to tell the project code that we want to use that code to give us access, and to light up the green LED. If another card / tag is presented to the reader, then the red LED will light up.
1. Between these two lines, create new lines of code.
print(card)
NEWCODE GOES HERE
PreviousCard = uid
2. Create an if condition that checks for your card’s uid. Note that it looks like a Python list, but in reality it is stored as a string, so we need to wrap the value in “ “. Don’t forget the [ ] brackets.
if card == "[0x04, 0xBC, 0xA0, 0x9A, 0xB3, 0x43, 0x80]":
3. If the value stored in the card object matches the hard coded value, print “ACCESS GRANTED” to the Python shell.
print("ACCESS GRANTED")
4. Create a for loop to toggle the green LED on / off ten times., with a 0.1 second gap between each change of state. Turn the green LED off at the end of the for loop.
for i in range(10):
green.toggle()
utime.sleep(0.1)
green.off()
5. Use an else condition for when an unrecognized card / tag is presented to the reader. This will toggle the red LED on and off just like the green LED.
else:
print("ACCESS DENIED")
for i in range(10):
red.toggle()
utime.sleep(0.1)
red.off()
6 .Save the code as reader.py to the Raspberry Pi Pico. Click on Run >> Run Current Script (or press the green play button). Follow the instructions and present the RFID card / tag to the reader. If the card is correct, then the green LED will flash and the Python shell will print “ACCESS GRANTED”. Try another RFID card / tag, this should make the red LED light up, and the Python shell will print “ACCESS DENIED”
Complete Code Listing
from mfrc522 import MFRC522
import utime
from machine import Pin
reader = MFRC522(spi_id=0,sck=2,miso=4,mosi=3,cs=1,rst=0)
red = Pin(14, Pin.OUT)
green = Pin(15, Pin.OUT)
print("Present the card to the reader\n")
PreviousCard = [0]
while True:
reader.init()
(stat, tag_type) = reader.request(reader.REQIDL)
if stat == reader.OK:
(stat, uid) = reader.SelectTagSN()
if uid == PreviousCard:
continue
if stat == reader.OK:
print("The card details are as follows")
card = reader.tohexstring(uid)
print(card)
if card == "[0x04, 0xBC, 0xA0, 0x9A, 0xB3, 0x43, 0x80]":
print("ACCESS GRANTED")
for i in range(10):
green.toggle()
utime.sleep(0.1)
green.off()
else:
print("ACCESS DENIED")
for i in range(10):
red.toggle()
utime.sleep(0.1)
red.off()
PreviousCard = uid
else:
PreviousCard=[0]
utime.sleep_ms(50)