RC522 RFID Reader Module with Raspberry Pi Pico

In this tutorial, we will learn to interface RC522 RFID Reader Module with Raspberry Pi Pico using MicroPython. These RFID reader modules are very handy in today’s fast-paced world. Due to their fast, accurate, and secure nature they are widely used with microcontrollers in various fields e.g. from supermarkets for fast check-outs to well maintained security systems for banks/jails/server rooms.

RC522 RFID Reader Module with Raspberry Pi Pico

The RFID reader module that we will look upon is known as RC522. We will use Raspberry Pi Pico with it and show you a MicroPython project that will use different RFID cards to lighten an RGB LED in three different colors.

By the end of this tutorial you will be able to:

  • Know the introduction about RC522 RFID reader module (features and pin out)
  • Interface the RC522 reader module with Raspberry Pi Pico along with RGB LED
  • Read the RFID tag
  • Control RGB LED using RFID RC522 reader module

Prerequisites

Before we start this lesson, make sure you are familiar with and have the latest version of Python3 installed in your system and set up MicroPython in your Raspberry Pi Pico. Additionally, you should have a running Integrated Development Environment(IDE) to do the programming. We will be using the same Thonny IDE as we had done previously when we learned how to blink and chase LEDs in MicroPython here:

If you are using uPyCraft IDE, you can check this getting started guide:

RC522 RFID Reader Module

RC522 is a Multi-communication RFID Module for Arduino and Microcontrollers. The RC522 is known as MFRC-522 due to its NFX semiconductor microcontroller. The module allows the developers to interface it with any other SPI, I2C, and UART based microcontrollers. It comes with an RFID card tag and key fob consisting of 1KB of memory.

The RC522 module works on 13.56 MHz frequency and it can act as a reader and write for UID/RFID cards. The RFID cards communicate with the module at a short distance with radio frequency due to the mutual induction technique. In most of the security and commercial products, the module is effective because the errors and issues with RFID Tags are detectable by it.

RFID Card Tag 1KB Memory Layout

The RFID card is a memory storage device having 1KB worth of memory. This memory is divided into 16 sectors (0-15) where each sector is further divided into 4 blocks (0,1,2,3). Each block is of 16 bytes each. Thus 4 blocks x 16 bytes x 16 sectors = 1024 bytes that is 1KB

RC522 RFID Reader Features

  • RFID RC522 uses mutual induction to activate the cards and 13.56MHz for data transfer.
  • The RFID Cards are useable from both sides of the module at max 5cm.
  • The only 3.3V is required to activate the device.
  • Its auto-sleep mode makes it less power consumption module.
  • The module has three kinds of communications (UART, SPI, I2C). Therefore, it is useable with almost every microcontroller or device in the market.
  • The RFID cards and reader (RC522) can transfer data up to 10Mb/s.

RC522 RFID Module Applications

  • RFID has most of the usage as a security device.
  • In some companies, the devices use with shopping items.
  • Some airports also start using RFID to identify and keep track of bags and other items.
  • The attendance or Parking system also uses RFID to keep the system secure.

Pin out

In this module, there are only two kinds of pins. So, the first one is power and the second one is the communication pins. Therefore, the device may have its microcontroller chip on itself but it only makes it to works as an RFID. The onboard microcontroller won’t make the module a stand-alone device.

All the pins of MFRC/RC522 RFID card Reader are:

RC522 RFID CARD READERS Pinout
RC522 RFID Reader Module Pin out

The table below shows the eight pins found on the RC522 RFID module. You can also view their descriptions.

PinDescription
VCCThe power pins are VCC. In some versions of RC522, this pin is denoted by 3V3 on the module instead of VCC.
RSTThis is the reset pin for the module. Therefore, it resets the device in case of an error when a device isn’t giving any response.
GNDGround helps to make the common ground with every external device, e.g. power Supply or microcontroller.
IRQThe device can go into sleep mode to save power. So, the IRQ helps to wake it.
MISOThis pin connects with the microcontroller for SPI communication. However, it transfers the data from module to the microcontroller.
The MISO pin is also useable for other functions instead of SPI.
It can also interface with I2C for clock pulse and UART Serial for Data transfer from the module.
MOSIMOSI is the data input pin for RFID module in SPI communication
SCKThe SCK pins help to send the clock pulse in SPI communications.
SSThe SS pin is a chip enable pin in SPI communication. Therefore, it receives the signal when Master (Raspberry Pi Pico) must perform SPI communication.
The SS pin in RFID is useable as a second pin (SDA) for I2C communication.
It also receives data during UART communication.

For more information follow the link below:

RC522 RFID Reader Module

Introducing RGB LED

RGB LED is a light-emitting diode that emits red, green, and blue lights. It consists of three discreet LEDs: red, green, and blue housed in a single packet so by combining these three colors we can create any color. Whenever voltage is applied to the red terminal, a red light will emit, and similarly when the voltage is applied to the Green and blue terminal, green and blue lights will emit respectively.

The RGB LED has four pins. These pins are used in order to control the color of the LED. The longest pin is either the anode or the cathode depending on the type of the RGB LED.

There is two types of RGB light-emitting diodes are available in the market.

  1. Common Anode type: In common Anode type, Anode is common for all three Light emitting diodes and Anode of all the light emitting diodes connects with positive power supply. Other terminals connects with microcontroller and we turn on and off these terminals according to which LED we want to turn on or turn off.  
  2. Common Cathode type: In common Cathode type, Cathode of all three light emitting diodes are common and common cathode terminal is connected with ground of power supply and other terminal of each power LED is connected with pic microcontroller according to which LED we want to turn on or turn off.  

Picture of both common anode and common cathode types RGB LED is shown below:

common Anode and Common Cathode RGB LED

Pinout

RGB LED and its pinout is shown below.

RGB LED pinout
PinDescription
1This is the red color select pin. Connect with digital output pin of microcontroller.
2This is the ground pin for the common cathode type and the 5 volts Vdd pin for the common anode type.
3This is the Blue color select pin. Connect with digital output pin of microcontroller.
4This is the Green color select pin. Connect with digital output pin of microcontroller.

Point to Note:

  • In order to limit the current that will run through the RGB LED , we will need to use three resistors one for each colour pin. If we do not use a resistor or if we use a low resistor value the LED will be destroyed. We need to use a 220 ohm resistor or higher. The higher the resistor value, lower the brightness of the LED.

RGB LED Module

The RGB LED also comes in a module with the current limiting resistors already attached. They are also available in two kinds: the common cathode module and the common anode module.

The RGB LED module already comes with the current limiting resistors so we do not to add external resistors.

Below you can view the two modules with their pin outs.

RGB LED modules pinout diagram

You may like to read other RGB LED guides:

Interfacing the RC522 RFID reader module and RGB LED with Raspberry Pi Pico

We will need the following components to connect our Raspberry Pi Pico board with the RC522 module and RGB LED module.

  • Raspberry Pi Pico
  • RC522 RFID Reader module
  • RGB LED Module
  • Breadboard
  • Connecting Wires

The RC522 module has 8 terminals which we will connect with the Raspberry Pi Pico. As the RC522 requires an operating voltage in the range of 2.5-3.3V hence the VCC terminal of the RC522 module will in common with the 3.3V pin of the board. Likewise, all the devices will have their grounds in common.

The SPI communication helps to communicate with RFID reader module, which is common in every microcontroller. Thus, we will use the SPI interface of Raspberry Pi Pico. Let us first learn about the Raspberry Pi Pico SPI interface.

Raspberry Pi Pico SPI Pins

Raspberry Pi Pico supports two SPI peripherals. Both SPI module pins are accessible through GPIO pins of Raspberry Pi Pico. The following table shows the connection of GPIO pins with both SPI modules. Each connection of SPI controller pins can be configured through multiple GPIO pins as shown in the figure. But before using SPI, you should configure in software which GPIO pins you want to use with a specific SP peripheral. 

SPI ControllerGPIO Pins
SPI0_RXGP0/GP4/GP16
SPI0_TXGP3/GP7/GP19
SPI0_SCKGP2/GP6/GP18
SPI0_CSnGP1/GP5/GP17
SPI1_RXGP8/GP12
SPI1_TXGP11/GP15
SPI1_SCKGP10/GP14
SPI1_CSnGP9/GP13

The figure below shows the SPI pins of Raspberry Pi Pico.

Raspberry Pi Pico pinout diagram

The table below shows the connections between the devices that we will use in our project.

Raspberry Pi Pico with RC522 Module

RC522 RFID Reader ModuleRaspberry Pi Pico
VCC3.3V
RSTGP0
GNDGND
IRQNot connected
MISOGP4
MOSIGP3
SCKGP2
SDAGP1

Raspberry Pi Pico with RGB LED Module (Common Cathode)

We are using the common cathode RGB LED module for this project. The table below shows the connections we are using between the LED module and the Raspberry Pi Pico.

RGB LED ModuleRaspberry Pi Pico
RGP13
GGP12
BGP11
GND

The red, green, and blue pins of the RGB LED module will be connected with GPIO pins of Raspberry Pi Pico. We will use GP13, GP12, and GP11 to connect with each colour pin. You can use any appropriate GPIO pin.

Schematic Diagram

Follow the schematic diagram below and connect the three devices accordingly.

All the connections between the devices are the same as we listed them in the tables above.

Raspberry Pi Pico with RC522 and RGB LED module connection diagram
Raspberry Pi Pico with RC522 and RGB LED module connection diagram
Raspberry Pi Pico with RC522 and RGB LED module

Installing MicroPython MFRC522 Library

For this project we will require the MicroPython MRRC522 library. Copy this library and save it in your Raspberry Pi Pico with the respective file name (mfrc522.py) from the GitHub link.

Open a new file in Thonny. Copy the library given below or from the link given above. Save it to Raspberry Pi Pico with the name mfrc522.py under the lib folder.

mfrc522.py

from machine import Pin, SPI
from os import uname


class MFRC522:

    DEBUG = False
    OK = 0
    NOTAGERR = 1
    ERR = 2

    REQIDL = 0x26
    REQALL = 0x52
    AUTHENT1A = 0x60
    AUTHENT1B = 0x61
  
    PICC_ANTICOLL1 = 0x93
    PICC_ANTICOLL2 = 0x95
    PICC_ANTICOLL3 = 0x97
  

    def __init__(self, sck, mosi, miso, rst, cs,baudrate=1000000,spi_id=0):

        self.sck = Pin(sck, Pin.OUT)
        self.mosi = Pin(mosi, Pin.OUT)
        self.miso = Pin(miso)
        self.rst = Pin(rst, Pin.OUT)
        self.cs = Pin(cs, Pin.OUT)

        self.rst.value(0)
        self.cs.value(1)
        
        board = uname()[0]

        if board == 'WiPy' or board == 'LoPy' or board == 'FiPy':
            self.spi = SPI(0)
            self.spi.init(SPI.MASTER, baudrate=1000000, pins=(self.sck, self.mosi, self.miso))
        elif (board == 'esp8266') or (board == 'esp32'):
            self.spi = SPI(baudrate=100000, polarity=0, phase=0, sck=self.sck, mosi=self.mosi, miso=self.miso)
            self.spi.init()
        elif board == 'rp2':
            self.spi = SPI(spi_id,baudrate=baudrate,sck=self.sck, mosi= self.mosi, miso= self.miso)
        else:
            raise RuntimeError("Unsupported platform")

        self.rst.value(1)
        self.init()

    def _wreg(self, reg, val):

        self.cs.value(0)
        self.spi.write(b'%c' % int(0xff & ((reg << 1) & 0x7e)))
        self.spi.write(b'%c' % int(0xff & val))
        self.cs.value(1)

    def _rreg(self, reg):

        self.cs.value(0)
        self.spi.write(b'%c' % int(0xff & (((reg << 1) & 0x7e) | 0x80)))
        val = self.spi.read(1)
        self.cs.value(1)

        return val[0]

    def _sflags(self, reg, mask):
        self._wreg(reg, self._rreg(reg) | mask)

    def _cflags(self, reg, mask):
        self._wreg(reg, self._rreg(reg) & (~mask))

    def _tocard(self, cmd, send):

        recv = []
        bits = irq_en = wait_irq = n = 0
        stat = self.ERR

        if cmd == 0x0E:
            irq_en = 0x12
            wait_irq = 0x10
        elif cmd == 0x0C:
            irq_en = 0x77
            wait_irq = 0x30

        self._wreg(0x02, irq_en | 0x80)
        self._cflags(0x04, 0x80)
        self._sflags(0x0A, 0x80)
        self._wreg(0x01, 0x00)

        for c in send:
            self._wreg(0x09, c)
        self._wreg(0x01, cmd)

        if cmd == 0x0C:
            self._sflags(0x0D, 0x80)

        i = 2000
        while True:
            n = self._rreg(0x04)
            i -= 1
            if ~((i != 0) and ~(n & 0x01) and ~(n & wait_irq)):
                break

        self._cflags(0x0D, 0x80)

        if i:
            if (self._rreg(0x06) & 0x1B) == 0x00:
                stat = self.OK

                if n & irq_en & 0x01:
                    stat = self.NOTAGERR
                elif cmd == 0x0C:
                    n = self._rreg(0x0A)
                    lbits = self._rreg(0x0C) & 0x07
                    if lbits != 0:
                        bits = (n - 1) * 8 + lbits
                    else:
                        bits = n * 8

                    if n == 0:
                        n = 1
                    elif n > 16:
                        n = 16

                    for _ in range(n):
                        recv.append(self._rreg(0x09))
            else:
                stat = self.ERR

        return stat, recv, bits

    def _crc(self, data):

        self._cflags(0x05, 0x04)
        self._sflags(0x0A, 0x80)

        for c in data:
            self._wreg(0x09, c)

        self._wreg(0x01, 0x03)

        i = 0xFF
        while True:
            n = self._rreg(0x05)
            i -= 1
            if not ((i != 0) and not (n & 0x04)):
                break

        return [self._rreg(0x22), self._rreg(0x21)]

    def init(self):

        self.reset()
        self._wreg(0x2A, 0x8D)
        self._wreg(0x2B, 0x3E)
        self._wreg(0x2D, 30)
        self._wreg(0x2C, 0)
        self._wreg(0x15, 0x40)
        self._wreg(0x11, 0x3D)
        self.antenna_on()

    def reset(self):
        self._wreg(0x01, 0x0F)

    def antenna_on(self, on=True):

        if on and ~(self._rreg(0x14) & 0x03):
            self._sflags(0x14, 0x03)
        else:
            self._cflags(0x14, 0x03)

    def request(self, mode):

        self._wreg(0x0D, 0x07)
        (stat, recv, bits) = self._tocard(0x0C, [mode])

        if (stat != self.OK) | (bits != 0x10):
            stat = self.ERR

        return stat, bits
  
    def anticoll(self,anticolN):

        ser_chk = 0
        ser = [anticolN, 0x20]

        self._wreg(0x0D, 0x00)
        (stat, recv, bits) = self._tocard(0x0C, ser)

        if stat == self.OK:
            if len(recv) == 5:
                for i in range(4):
                    ser_chk = ser_chk ^ recv[i]
                if ser_chk != recv[4]:
                    stat = self.ERR
            else:
                stat = self.ERR

        return stat, recv

    
    def PcdSelect(self, serNum,anticolN):
        backData = []
        buf = []
        buf.append(anticolN)
        buf.append(0x70)
        #i = 0
        ###xorsum=0;
        for i in serNum:
            buf.append(i)
        #while i<5:
        #    buf.append(serNum[i])
        #    i = i + 1
        pOut = self._crc(buf)
        buf.append(pOut[0])
        buf.append(pOut[1])
        (status, backData, backLen) = self._tocard( 0x0C, buf)
        if (status == self.OK) and (backLen == 0x18):
            return  1
        else:
            return 0
    
    
    def SelectTag(self, uid):
        byte5 = 0
        
        #(status,puid)= self.anticoll(self.PICC_ANTICOLL1)
        #print("uid",uid,"puid",puid)
        for i in uid:
            byte5 = byte5 ^ i
        puid = uid + [byte5]
        
        if self.PcdSelect(puid,self.PICC_ANTICOLL1) == 0:
            return (self.ERR,[])
        return (self.OK , uid)
        
    def tohexstring(self,v):
        s="["
        for i in v:
            if i != v[0]:
                s = s+ ", "
            s=s+ "0x{:02X}".format(i)
        s= s+ "]"
        return s
        
  
            
    
    def SelectTagSN(self):
        valid_uid=[]
        (status,uid)= self.anticoll(self.PICC_ANTICOLL1)
        #print("Select Tag 1:",self.tohexstring(uid))
        if status != self.OK:
            return  (self.ERR,[])
        
        if self.DEBUG:   print("anticol(1) {}".format(uid))
        if self.PcdSelect(uid,self.PICC_ANTICOLL1) == 0:
            return (self.ERR,[])
        if self.DEBUG:   print("pcdSelect(1) {}".format(uid))
        
        #check if first byte is 0x88
        if uid[0] == 0x88 :
            #ok we have another type of card
            valid_uid.extend(uid[1:4])
            (status,uid)=self.anticoll(self.PICC_ANTICOLL2)
            #print("Select Tag 2:",self.tohexstring(uid))
            if status != self.OK:
                return (self.ERR,[])
            if self.DEBUG: print("Anticol(2) {}".format(uid))
            rtn =  self.PcdSelect(uid,self.PICC_ANTICOLL2)
            if self.DEBUG: print("pcdSelect(2) return={} uid={}".format(rtn,uid))
            if rtn == 0:
                return (self.ERR,[])
            if self.DEBUG: print("PcdSelect2() {}".format(uid))
            #now check again if uid[0] is 0x88
            if uid[0] == 0x88 :
                valid_uid.extend(uid[1:4])
                (status , uid) = self.anticoll(self.PICC_ANTICOLL3)
                #print("Select Tag 3:",self.tohexstring(uid))
                if status != self.OK:
                    return (self.ERR,[])
                if self.DEBUG: print("Anticol(3) {}".format(uid))
                if self.MFRC522_PcdSelect(uid,self.PICC_ANTICOLL3) == 0:
                    return (self.ERR,[])
                if self.DEBUG: print("PcdSelect(3) {}".format(uid))
        valid_uid.extend(uid[0:5])
        # if we are here than the uid is ok
        # let's remove the last BYTE whic is the XOR sum
        
        return (self.OK , valid_uid[:len(valid_uid)-1])
        #return (self.OK , valid_uid)
    
    
   
       
    

    def auth(self, mode, addr, sect, ser):
        return self._tocard(0x0E, [mode, addr] + sect + ser[:4])[0]
    
    def authKeys(self,uid,addr,keyA=None, keyB=None):
        status = self.ERR
        if keyA is not None:
            status = self.auth(self.AUTHENT1A, addr, keyA, uid)
        elif keyB is not None:
            status = self.auth(self.AUTHENT1B, addr, keyB, uid)
        return status
       

    def stop_crypto1(self):
        self._cflags(0x08, 0x08)

    def read(self, addr):

        data = [0x30, addr]
        data += self._crc(data)
        (stat, recv, _) = self._tocard(0x0C, data)
        return stat, recv

    def write(self, addr, data):

        buf = [0xA0, addr]
        buf += self._crc(buf)
        (stat, recv, bits) = self._tocard(0x0C, buf)

        if not (stat == self.OK) or not (bits == 4) or not ((recv[0] & 0x0F) == 0x0A):
            stat = self.ERR
        else:
            buf = []
            for i in range(16):
                buf.append(data[i])
            buf += self._crc(buf)
            (stat, recv, bits) = self._tocard(0x0C, buf)
            if not (stat == self.OK) or not (bits == 4) or not ((recv[0] & 0x0F) == 0x0A):
                stat = self.ERR
        return stat


    def writeSectorBlock(self,uid, sector, block, data, keyA=None, keyB = None):
        absoluteBlock =  sector * 4 + (block % 4)
        if absoluteBlock > 63 :
            return self.ERR
        if len(data) != 16:
            return self.ERR
        if self.authKeys(uid,absoluteBlock,keyA,keyB) != self.ERR :
            return self.write(absoluteBlock, data)
        return self.ERR

    def readSectorBlock(self,uid ,sector, block, keyA=None, keyB = None):
        absoluteBlock =  sector * 4 + (block % 4)
        if absoluteBlock > 63 :
            return self.ERR, None
        if self.authKeys(uid,absoluteBlock,keyA,keyB) != self.ERR :
            return self.read(absoluteBlock)
        return self.ERR, None

    def MFRC522_DumpClassic1K(self,uid, Start=0, End=64, keyA=None, keyB=None):
        for absoluteBlock in range(Start,End):
            status = self.authKeys(uid,absoluteBlock,keyA,keyB)
            # Check if authenticated
            print("{:02d} S{:02d} B{:1d}: ".format(absoluteBlock, absoluteBlock//4 , absoluteBlock % 4),end="")
            if status == self.OK:                    
                status, block = self.read(absoluteBlock)
                if status == self.ERR:
                    break
                else:
                    for value in block:
                        print("{:02X} ".format(value),end="")
                    print("  ",end="")
                    for value in block:
                        if (value > 0x20) and (value < 0x7f):
                            print(chr(value),end="")
                        else:
                            print('.',end="")
                    print("")
            else:
                break
        if status == self.ERR:
            print("Authentication error")
            return self.ERR
        return self.OK

RFID RC522 RGB LED Control

We will use Raspberry Pi Pico with it and show you a MicroPython project that will use different RFID cards to lighten an RGB LED in three different colours. One card will cause the LED to light up in green colour while another will light it up in blue colour. Any unknown card will set the RGB light to red colour. The user brings the RFID card/tags close to the RFID reader and the RGB light is set to the appropriate colour along with relevant messages in the Thonny Shell.

Raspberry Pi Pico MicroPython: Reading RFID Tags

Open your Thonny IDE and go to File > New to open a new file. Copy the following code in that file. This sketch will identify the RFID card/tag ID. When the user brings a RFID tag/card near RC522 module, it detects the tag and reads its value.

from mfrc522 import MFRC522
import utime

reader = MFRC522(spi_id=0,sck=2,miso=4,mosi=3,cs=1,rst=0)

print("Bring TAG closer...")
print("")


while True:
    reader.init()
    (stat, tag_type) = reader.request(reader.REQIDL)
    if stat == reader.OK:
        (stat, uid) = reader.SelectTagSN()
        if stat == reader.OK:
            card = int.from_bytes(bytes(uid),"little",False)
            print("CARD ID: "+str(card))
utime.sleep_ms(500) 

How the Code Works?

The first step is to include all the libraries that are necessary for this project. We will import utime module to generate the delay and the MFRC522 class from the mfrc522 module to work with the RC522 reader for this task.

from mfrc522 import MFRC522
import utime

Then we will define the RC522 RFID connection by creating an object ‘reader’. By using MFRC522() we specified the SPI channel number as the first parameter and the SPI pins as the rest of the parameters.

reader = MFRC522(spi_id=0,sck=2,miso=4,mosi=3,cs=1,rst=0)

The following message printed in the Thonny Shell indicates the user to bring their RFID card/tag closer to the RFID module.

print("Bring TAG closer...")
print("")

Inside the infinite loop, we will first initialize the RFID reader using the init() method on the reader object. Then we will obtain the status from the reader. If the status is valid then we will move ahead with our program. We will create another object ‘card’ that will contain the RFID card ID. We will obtain the unique tag ID associated with the tag whenever it gets detected. This gets printed in the Thonny shell console.

while True:
    reader.init()
    (stat, tag_type) = reader.request(reader.REQIDL)
    if stat == reader.OK:
        (stat, uid) = reader.SelectTagSN()
        if stat == reader.OK:
            card = int.from_bytes(bytes(uid),"little",False)
            print("CARD ID: "+str(card))
utime.sleep_ms(500) 

Demonstration

After you have copied the following code onto a new file, click the ‘Save’ icon to save your program code on your PC.

After you have saved the code press the Run button to upload the code to your Raspberry Pi Pico module. Before uploading code make sure the correct board is selected.

Now bring an RFID card/tag near the RC522 reader. Immediately its card ID will get printed in the shell terminal. Here we have scanned two different tags and obtained their IDs.

Raspberry Pi Pico with RC522 reader thonny shell terminal

We will use these two IDs to light up the RGB LED appropriately. If the first ID is scanned by the reader then the RGB LED will be set to green light and if the second ID is scanned then the RGB LED will be set to blue light. For any other RFID tag is scanned, will set the RGB LED to red.

Raspberry Pi Pico MicroPython: RFID RC522 RGB LED Control

When the user brings an RFID tag/card near RC522, it detects the tag and reads its value. If the value is same as defined in the code for green then ‘PASS: Green Light Activated’ message is shown in the shell terminal. If the value is same as defined in the code for blue then ‘PASS: Blue Light Activated’ message is shown in the shell terminal. Otherwise ‘UNKNOWN CARD! Red Light Activated’ message is shown instead. The RGB LED will be set to colours green, blue or red in this process. This process occurs every time the user brings an RFID tag closer to the module.

from machine import Pin
from mfrc522 import MFRC522
import utime
       
reader = MFRC522(spi_id=0,sck=2,miso=4,mosi=3,cs=1,rst=0)

red = Pin(13, Pin.OUT)
green = Pin(12, Pin.OUT)
blue = Pin(11, Pin.OUT)

print("Bring RFID TAG Closer...")
print("")


while True:
    reader.init()
    (stat, tag_type) = reader.request(reader.REQIDL)
    if stat == reader.OK:
        (stat, uid) = reader.SelectTagSN()
        if stat == reader.OK:
            card = int.from_bytes(bytes(uid),"little",False)
            
            if card == 612121286:
                print("Card ID: "+ str(card)+" PASS: Green Light Activated")
                red.value(0)
                green.value(1)
                blue.value(0)
                
                
            elif card == 1002696326:
                print("Card ID: "+ str(card)+" PASS: Blue Light Activated")
                red.value(0)
                green.value(0)
                blue.value(1)
                
            else:
                print("Card ID: "+ str(card)+" UNKNOWN CARD! Red Light Activated")
                red.value(1)
                green.value(0)
                blue.value(0)           

How the Code Works?

Most of the code is similar to the one above where we are obtaining the RFID tag IDs. After obtaining the card ID we will check if the ID is either of the two we have set up for a green and blue pass and then set the RGB LED to that particular colour.

As we are using common cathode RGB module, hence to set the colour to green we will have to make sure the GPIO connected to the green pin is in a high state and rest of the two are at a low state.


red.value(0)
green.value(1)
blue.value(0)

To set the color to blue we will have to make sure the GPIO connected to the blue pin is in a high state and rest of the two are at a low state.

red.value(0)
green.value(0)
blue.value(1)

Likewise, to set the color to red we will have to make sure the GPIO connected to the red pin is in a high state and the rest of the two are at a low state.

red.value(1)
green.value(0)
blue.value(0)

Demonstration

After you have copied the following code onto a new file, click the ‘Save’ icon to save your program code on your PC.

After you have saved the code press the Run button to upload the code to your Raspberry Pi Pico module.

Bring the RFID card/tags close to the RC522 reader and immediately the RGB LED will light up to either green, blue or red.

Raspberry Pi Pico with RC522 and RGB LED module demo

The Thonny Shell terminal will also print relevant messages as each tag gets scanned.

Raspberry Pi Pico with RC522 reader and RGB LED thonny shell terminal

Watch the video below for better insight:

You may also like to read:

5 thoughts on “RC522 RFID Reader Module with Raspberry Pi Pico”

  1. Hello,

    Thank you for the great tutorial. I’m using 144 byte NTAG213 NFC tags and having trouble reading data from these tags. I can read the IDs fine. Your code above always returns an “Authentication error”. My tags are not using any authentication and I’m able to read and write to them with my iPhone. Any ideas on how to resolve this issue?

    Reply
  2. Hi,
    I was wondering if instead of an infinite loop we could use the irq to trigger reading from cards. If this is possible how can we do it?
    Mike

    Reply

Leave a Comment