Use RC522 RFID with Arduino and OLED – RFID lock

RFID is one of these technologies that change how we interact with other electronic devices and things in our environment. It is used in every application where some unique identifier is required, from retail to security and is also leading the path along several futuristic innovations with RFID based human implants among others. This wide range of applications makes RFID desirable and useful for several Arduino projects. For today’s tutorial, we will look on how to use RFID in Arduino based projects.

How it works

Before we dive into the project, it’s probably important to do an introduction on RFID. RFID stands for Radio Frequency Identification System. It comprises of two main parts; the reader (and ofteb writer) and the tags. The readers use electromagnetic field to automatically identify and track electronically stored, information contained in tags. Some of these readers also come with writing ability which enables them to change the information stored on compatible tags within their proximity.

The tags, on the other hand, carry pre-stored information from writers and send this info to the reader when requested. Each RFID tag has a small chip inside, which can usually be seen if a flashlight is placed under the tag.  All the information in the tag is stored on the chip, including a unique number (known as the UID) through which the tags are identified and differentiated from each other. RFID tags can either be passive or active. Passive tags are usually short range and have no power source embedded. They are powered via induction from the electromagnetic field of the reader when they are in range and information is transmitted to them. Active tags, however, are usually battery powered and are capable of communicating with readers over longer distances.

Different types of RFID tages

For today’s tutorials, we will  use the RC522 RFID reader to obtain the UID of tags placed near it and to create a simple prototype of an RFID based door lock system. The RC522 RFID reader is a  low cost, highly integrated, 13.56 MHz contactless communication enabled reader module. It is by far one of the most popular RFID readers among hobbyists and makers due to its low cost and ease of use with the Arduino. Some of the features of the RFID reader are described below:
  • MFRC522 chip based board
  • Operating frequency: 13.56MHz
  • Supply Voltage: 3.3V
  • Current: 13-26mA
  • Read Range: Approx 3cm
  • SPI Interface
  • Max Data Transfer Rate: 10Mbit / s
  • Dimensions: 60mm × 39mm

At the end of this tutorial, you will know how to build RFID based Arduino projects.

Required Components

The following components are required to build this project:

  1. Arduino Uno
  2. RFID module
  3. OLED display
  4. Small Breadboard
  5. Wires
  6. Power Bank


The schematic for this project is quite simple. The RFID module uses the SPI communication protocol, so it will be connected to the dedicated SPI pins on the Arduino. The OLED display, on the other hand, uses I2C protocol and will thus also be connected to the Arduino’s dedicated I2C lines. Connect the component as shown in the schematics below.


To make the schematics easier to follow, the pin connections between the Arduino and other components are described below.

RC522 – Arduino

SDA - D10
SCK - D13
MOSI - D11
MISO - D12
IRQ - Not connected
RST - D9
3.3V - 3.3V

OLED – Arduino

SCL - A5
SDA - A4
VCC - 5v 

The OLED display has been used in many tutorials on this website. You can check them out to learn more about using OLED displays.

Go over your connections once again to be sure everything is as it should be. The final setup after the connections should look like the image below.

Components connected with Arduino

The RC522 module may be damaged if connected to a voltage above 3.3v so ensure it is rightly connected.


To simplify and reduce the amount of code needed for this project, we will use the MFRC522 library, the Adafruit SD1306, and the Adafruit GFX libraries. For everyone running the latest version of the Arduino IDE, you can download these libraries via the library manager. Go to “Sketch -> Include Libraries -> Manage libraries” and enter the name of the libraries into the search bar and install them one after the other. With the libraries installed, go to your libraries folder and open the Adafruit_SSD1306.h using any code editor like notepad++. We will change the default screen resolution to match that of our display (128×64) by commenting out the default value (128×32) and un-commenting the line that matches our display as shown in the image below.

Set SSD1306 display resolution

With this done, save and relaunch the IDE. We are now ready for the code.

The code for this project is quite easy and as mentioned during the introduction, we will read tags and check if they match pre-stored UIDs. If there is a match, “unlocked” will be displayed on the OLED display and if there is no match, the OLED will display “locked”,  simulating the actions on an RFID based door lock system.

As usual, I will do a quick break down of the code and try as much as possible to explain all the key parts of the code. We start by including the libraries that will use as discussed above.

  1. //Written by Nick Koumaris
  2. //
  3. #include <MFRC522.h>
  4. #include <Adafruit_GFX.h>
  5. #include <Adafruit_SSD1306.h>
  6. #include <SPI.h>

Next, we create an instance of the SSD1306 library for the OLED display, declare the pins of the Arduino to which the reader is connected and create an instance of the MFRC522 library.

  1. #define OLED_RESET 4
  2. Adafruit_SSD1306 display(OLED_RESET);
  3. #define SS_PIN 10
  4. #define RST_PIN 9
  5. MFRC522 rfid(SS_PIN, RST_PIN); // Instance of the class
  6. MFRC522::MIFARE_Key key;

Next, we declare the UID (an array of integers) of the RFID tag,  that we want the Arduino to recognize and other variables that will be used in the code.

  1. int code[] = {69,141,8,136}; //This is the stored UID
  2. int codeRead = 0;
  3. String uidString;

Next, we write the void setup function where we initialize the RFID reader and the display. Serial, SPI and I2C communications are also initiated and we set the system to start in lock mode, waiting for tags to be scanned.

  1. void setup() {
  2. Serial.begin(9600);
  3. SPI.begin(); // Init SPI bus
  4. rfid.PCD_Init(); // Init MFRC522
  5. display.begin(SSD1306_SWITCHCAPVCC, 0x3C); // initialize with the I2C addr 0x3D (for the 128×64)
  6. // Clear the buffer.
  7. display.clearDisplay();
  8. display.display();
  9. display.setTextColor(WHITE); // or BLACK);
  10. display.setTextSize(2);
  11. display.setCursor(10,0);
  12. display.print(“RFID Lock”);
  13. display.display();
  14. }

Next, is the void loop() function. The loop function simply calls the readrfid function whenever the RFID reader detects an RFID card with a delay of 100ms between calls to allow the information from the tags to be processed.

  1. void loop() {
  2. if( rfid.PICC_IsNewCardPresent())
  3. {
  4. readRFID();
  5. }
  6. delay(100);
  7. }

The readrfid function does all the heavy lifting associated with this project. The function is quite long but, it simply extracts the UID of the tag being scanned and checks if it matches the stored UID. If there is a match, the unlock message is printed, while if there is not a match, the system stays locked.

  1. void readRFID()
  2. {
  3. rfid.PICC_ReadCardSerial();
  4. Serial.print(F(“\nPICC type: “));
  5. MFRC522::PICC_Type piccType = rfid.PICC_GetType(rfid.uid.sak);
  6. Serial.println(rfid.PICC_GetTypeName(piccType));
  7. // Check is the PICC of Classic MIFARE type
  8. if (piccType != MFRC522::PICC_TYPE_MIFARE_MINI &&
  9. piccType != MFRC522::PICC_TYPE_MIFARE_1K &&
  10. piccType != MFRC522::PICC_TYPE_MIFARE_4K) {
  11. Serial.println(F(“Your tag is not of type MIFARE Classic.”));
  12. return;
  13. }
  14. clearUID();
  15. Serial.println(“Scanned PICC’s UID:”);
  16. printDec(rfid.uid.uidByte, rfid.uid.size);
  17. uidString = String(rfid.uid.uidByte[0])+” “+String(rfid.uid.uidByte[1])+” “+String(rfid.uid.uidByte[2])+ ” “+String(rfid.uid.uidByte[3]);
  18. printUID();
  19. int i = 0;
  20. boolean match = true;
  21. while(i<rfid.uid.size)
  22. {
  23. if(!(rfid.uid.uidByte[i] == code[i]))
  24. {
  25. match = false;
  26. }
  27. i++;
  28. }
  29. if(match)
  30. {
  31. Serial.println(“\nI know this card!”);
  32. printUnlockMessage();
  33. }else
  34. {
  35. Serial.println(“\nUnknown Card”);
  36. }
  37. // Halt PICC
  38. rfid.PICC_HaltA();
  39. // Stop encryption on PCD
  40. rfid.PCD_StopCrypto1();
  41. }

other functions used include the printUID() function and the printunlockmessage() function which should be easy to follow.

The complete code for the project is shown below.

  1. //Written by Nick Koumaris
  2. //
  3. #include <MFRC522.h>
  4. #include <Adafruit_GFX.h>
  5. #include <Adafruit_SSD1306.h>
  6. #include <SPI.h>
  7. #define OLED_RESET 4
  8. Adafruit_SSD1306 display(OLED_RESET);
  9. #define SS_PIN 10
  10. #define RST_PIN 9
  11. MFRC522 rfid(SS_PIN, RST_PIN); // Instance of the class
  12. MFRC522::MIFARE_Key key;
  13. int code[] = {69,141,8,136}; //This is the stored UID
  14. int codeRead = 0;
  15. String uidString;
  16. void setup() {
  17. Serial.begin(9600);
  18. SPI.begin(); // Init SPI bus
  19. rfid.PCD_Init(); // Init MFRC522
  20. display.begin(SSD1306_SWITCHCAPVCC, 0x3C); // initialize with the I2C addr 0x3D (for the 128×64)
  21. // Clear the buffer.
  22. display.clearDisplay();
  23. display.display();
  24. display.setTextColor(WHITE); // or BLACK);
  25. display.setTextSize(2);
  26. display.setCursor(10,0);
  27. display.print(“RFID Lock”);
  28. display.display();
  29. }
  30. void loop() {
  31. if( rfid.PICC_IsNewCardPresent())
  32. {
  33. readRFID();
  34. }
  35. delay(100);
  36. }
  37. void readRFID()
  38. {
  39. rfid.PICC_ReadCardSerial();
  40. Serial.print(F(“\nPICC type: “));
  41. MFRC522::PICC_Type piccType = rfid.PICC_GetType(rfid.uid.sak);
  42. Serial.println(rfid.PICC_GetTypeName(piccType));
  43. // Check is the PICC of Classic MIFARE type
  44. if (piccType != MFRC522::PICC_TYPE_MIFARE_MINI &&
  45. piccType != MFRC522::PICC_TYPE_MIFARE_1K &&
  46. piccType != MFRC522::PICC_TYPE_MIFARE_4K) {
  47. Serial.println(F(“Your tag is not of type MIFARE Classic.”));
  48. return;
  49. }
  50. clearUID();
  51. Serial.println(“Scanned PICC’s UID:”);
  52. printDec(rfid.uid.uidByte, rfid.uid.size);
  53. uidString = String(rfid.uid.uidByte[0])+” “+String(rfid.uid.uidByte[1])+” “+String(rfid.uid.uidByte[2])+ ” “+String(rfid.uid.uidByte[3]);
  54. printUID();
  55. int i = 0;
  56. boolean match = true;
  57. while(i<rfid.uid.size)
  58. {
  59. if(!(rfid.uid.uidByte[i] == code[i]))
  60. {
  61. match = false;
  62. }
  63. i++;
  64. }
  65. if(match)
  66. {
  67. Serial.println(“\nI know this card!”);
  68. printUnlockMessage();
  69. }else
  70. {
  71. Serial.println(“\nUnknown Card”);
  72. }
  73. // Halt PICC
  74. rfid.PICC_HaltA();
  75. // Stop encryption on PCD
  76. rfid.PCD_StopCrypto1();
  77. }
  78. void printDec(byte *buffer, byte bufferSize) {
  79. for (byte i = 0; i < bufferSize; i++) {
  80. Serial.print(buffer[i] < 0x10 ? ” 0″ : ” “);
  81. Serial.print(buffer[i], DEC);
  82. }
  83. }
  84. void clearUID()
  85. {
  86. display.setTextColor(BLACK); // or BLACK);
  87. display.setTextSize(1);
  88. display.setCursor(30,20);
  89. display.print(uidString);
  90. display.display();
  91. }
  92. void printUID()
  93. {
  94. display.setTextColor(WHITE); // or BLACK);
  95. display.setTextSize(1);
  96. display.setCursor(0,20);
  97. display.print(“UID: “);
  98. display.setCursor(30,20);
  99. display.print(uidString);
  100. display.display();
  101. }
  102. void printUnlockMessage()
  103. {
  104. display.display();
  105. display.setTextColor(BLACK); // or BLACK);
  106. display.setTextSize(2);
  107. display.setCursor(10,0);
  108. display.print(“RFID Lock”);
  109. display.display();
  110. display.setTextColor(WHITE); // or BLACK);
  111. display.setTextSize(2);
  112. display.setCursor(10,0);
  113. display.print(“Unlocked”);
  114. display.display();
  115. delay(2000);
  116. display.setTextColor(BLACK); // or BLACK);
  117. display.setTextSize(2);
  118. display.setCursor(10,0);
  119. display.print(“Unlocked”);
  120. display.setTextColor(WHITE); // or BLACK);
  121. display.setTextSize(2);
  122. display.setCursor(10,0);
  123. display.print(“RFID Lock”);
  124. display.display();
  125. }


Go over the schematics and ensure the components are properly connected, then upload the code to the Arduino board. Ensure the libraries have been installed as described and the modifications to the SD1306 library has been made as described. After Uploading, you should see the OLED come up as shown below.


Put the card with the known UID across the RFID reader and you should see the screen indicate “Unlocked”. After a few minutes, It will go back to “locked” and you can then scan an unknown tag and see the outcome.


That’s it for this tutorial guys. As simple as it may seem, RFIDs have applications in diverse industries from security to retail and the example we just built, could serve as building block for an RFID based door lock system or a retail solution. What RFID application are you most interested in? do share via the comment section along with questions and other comments.

Leave a Reply

Your email address will not be published. Required fields are marked *