See our full project Here and visit BreakoutBros.com for more.
Today we will be delving into some of the parts from the Elegoo Uno R3 Starter Kit. Specifically the RFID RC522 module and the 1602A LCD. If you aren't familiar with RFID it stands for Radio Frequency Identification. It is a way to read information wirelessly. The benefit is that the RFID ID cards are cheap, and don't require being powered, the RFID transceiver powers it using an electromagnetic field. This is the same technology used for many badges and ID cards that are scanned. Recently even credit cards have taken up a subset of RFID known as Near Field Communication (NFC). Now that you know a little about RFID, let's get to it.
The goal of today's tutorial will be to assign a name to a Key Fob or Key Card and display this name on the LCD when it is scanned. The code will be written in C using the Arduino IDE. We will construct the code in a way so that there is one data array for the valid key cards and another lookup array with the name to associate with these IDs.
SetupLets first go over setup:
As pictured above you will need:
- RFID RC522 Module
- RFID RC522 Key Fob
- RFID RC522 Key Card(Not Pictured)
- Arduino Uno or equivalent
- 10k Potentiometer
- USB Standard A-B(To program Arduino)
- 1602A LCD
- Wires
- External Arduino Power Supply(Optional)
- Bread Board
The first step will be to setup the 1602A LCD. There is a very thorough 1602A LCD tutorial located here.
You should use the demo example to print something to the LCD. Once you have this working it is time to get the RC522 RFID module working.
Addicore has developed some libraries and a demo tutorial to easily use the RC522 RFID module. Please follow along to the Addicore RC522 RFID module tutorial here. You will need to remove some of the pins you have plugged in for the LCD. This is OK, remove them and follow along to the RFID tutorial.
Make sure to take note of your Key Fob and Key Card IDs from this tutorial. Write them down and save these somewhere.
In the case for my Key Fob it was [134][224][134][141].
WiringNow that you've completed the Addicore RFID tutorial, you probably noticed the LCD and the RFID are using similar pins. This means we will have to change those pins and make the same changes in the software for the LCD to get both to work together. Before integrating both the LCD and RFID module you will need to move some of the LCD pins on the Arduino.
- Move the LCD wire going to Arduino Pin 10 to Pin 6
- Move the LCD wire going to Arduino Pin 11 to Pin 4
- Move the LCD wire going to Arduino Pin 12 to Pin 7
You will also need to change the code in order to get this to work. Change the LiquidCrystal example code by switching the numbers in the LiquidCrystal.lcd() line.
CodeThe new code will read:
#include <LiquidCrystal.h>
LiquidCrystal lcd(7, 8, 9, 6, 4 , 3);
void setup() {
lcd.begin(16, 2);
lcd.setCursor(0,0);
lcd.write(" BreakoutBros");
lcd.setCursor(0,1);
lcd.write(" Tutorials");
} void loop() { }
Go ahead and run this code to make sure everything is working. You should see something similar to:
Now you should have the LCD and RC522 RFID module wired up. In case you missed something here are the Arduino pinouts:
- Pin 0 -
- Pin 1 -
- Pin 2 -
- Pin 3 - LCD D7
- Pin 4 - LCD D6
- Pin 5 - RFID RST
- Pin 6 - LCD D5
- Pin 7 - LCD RS
- Pin 8 - LCD E
- Pin 9 - LCD D4
- Pin 10 - RFID SDA
- Pin 11 - RFID MOSI
- Pin 12 - RFID MISO
- Pin 13 - RFID SCK
You will now want to start a new sketch and integrate all the setup information from the RFID and the LCD tutorials.
This should look like this:
#include <AddicoreRFID.h>
#include <SPI.h>
//LCD Setup
#include <LiquidCrystal.h>
LiquidCrystal lcd(7, 8, 9, 6, 4, 3); //(RS,E,D4,D5,D6,D7)
#define uchar unsigned char
#define uint unsigned int
uchar fifobytes;
uchar fifoValue;
AddicoreRFID myRFID; // create AddicoreRFID object to control the RFID module
//set the pins
const int chipSelectPin = 10;
const int NRSTPD = 5;
//Maximum length of the array
#define MAX_LEN 16
For the next step we want to setup a table that will be used with an ID and a Name to display. As you can see the Josh ID[134][224][134][141] is the same as what was above. I am associating this number to Josh's ID. Whatever your key ID from the Addicore RC522 RFID module tutorial was go ahead and replace it with the first 4 bytes below. Then change "Josh" to whomever you want associated with that ID.
// Define All Key Codes
uchar keys[16] = {
134 , 224, 134, 141, //Josh ID - These 4 digits are your 1st users ID Bytes
000 , 000, 000, 000, //Dummy 0 - These 4 digits are your 2nd users ID Bytes
111 , 111, 111, 111, // Dummy 1 ID - These 4 digits are your 3rd users ID Bytes
222 , 222, 222, 222 // Dummy 2 ID - These 4 digits are your 4th users ID Bytes };
String Names[4] = {
"Josh", // 1st User- what will be printed to LCD
"Dummy0", // 2nd User- what will be printed to LCD
"Dummy1", // 3rd User- what will be printed to LCD
"Dummy2" // 4th User- what will be printed to LCD };
This structure only supports 4 IDs, if you want more IDs please contact us at brad@breakoutbros.com, it will require a few changes to the code. If there are enough requests I'll make a followup tutorial!
We will also need to store the name we want to display on the LCD as a variable. I've created a global variable to do this:
// Variable to Store Tag User Name to show on screen
String Tag_Name = "i"; // default value for the name will be "i"
Simple commandsNow we will need to start writing some functions to handle some simple commands. Below the main loop of the program we will write a couple LCD functions and a sorting functions.
The first LCD function is used to display a Main Screen - This will be "The Breakout Bros" "Scan Your Card." This is the screen that will be shown if the reader has nothing present.
void lcdprintmain(){
lcd.clear();
lcd.setCursor(0,0);
lcd.write("The BreakoutBros");
lcd.setCursor(0,1);
lcd.write(" Scan Your Card");
}
The Second LCD Function will be what is displayed if the tag read is not an approved RFID tag:
void lcdaccessdenied(){
lcd.clear();
lcd.setCursor(0,0);
lcd.write(" Access Denied "); // print Access denied
}
The Third LCD Function will be a function will be used for the approved tag ID - this will print the name of whoever's tag is associated with the ID along with a greeting message.
void lcdprintwelcome(String Name){
lcd.clear();
lcd.setCursor(0,0);
lcd.print(" Welcome Home ");
lcd.setCursor(5,1);
lcd.print(Name);
}
The final function is our sorting function. The first input to the function is the ID that is read from the scanned RFID card. The second is our approved Keys Table. The third is our Names associated to those keys. This function will return the Name associated to the key if the ID read is one of these keys. If it is not, the function will return "i". We will use the "i" string to display the "access denied" message.
String testkey(uchar Read_ID[4], uchar Stored_ID[16], String Stored_Name[4]){
int n = 0; // Variable for Overall ID loop
int test = 0; //Variable for testing each Byte
int i = 0; // Variable for Read Byte Loop
int g = 0; // Variable for Stored Byte Loop
for(n=0; n < 4; n++) // Loop for each Name test
{
for(i=0; i<4; i++) //Loop for each ID test
{
if(Read_ID[i] == Stored_ID[g]) // test bytes 0-3 of each ID
{
test = test+1; // if a test passes increase test by 1
}
g = g + 1; // Counter or stored ID indexing
}
if( test == 4) // if all 4 bytes pass
{
return Stored_Name[n]; // return the place in the loop that passed
}
else
{
test = 0; // if not all loops pass
i = 0;
}
}
return "i"; // Return "i" for a failure - this is what we will use for access denied
}
Now we will get to the Main Loop. We will be keeping the setup information from the Addicore RC522 RFID module tutorial here and expanding on it to generate our Main Loop. Just keep the initial setup information and the checksum calculation, along with the Status Loop. Currently your main loop should look like:
void loop()
{
uchar i, tmp, checksum1;
uchar status;
uchar str[MAX_LEN];
uchar RC_size;
uchar blockAddr; //Selection operation block address 0 to 63
String mynum = "";
str[1] = 0x4400;
//Find tags, return tag type
status = myRFID.AddicoreRFID_Request(PICC_REQIDL, str);
//Anti-collision, return tag serial number 4 bytes
status = myRFID.AddicoreRFID_Anticoll(str);
if (status == MI_OK)
{
checksum1 = str[0] ^ str[1] ^ str[2] ^ str[3]; // Calculate a checksum to make sure there is no error
myRFID.AddicoreRFID_Halt(); //Command tag into hibernation
}
}
This is looking for a read tag and if the status = MI_OK the the checksum is caclulated the the RFID tag is sent back to hibernation. We want to add to the if(Status ==MI_OK) loop. The first thing we will add to this loop is a checksum check. The checksum is basically used to make sure there was no error in recording the data from the tag. The RFID tag sends its checksum to the reader. The Addicore commands save this checksum to str[4] so we can compare a calculated checksum to the read checksum from the tag. The checksum is nothing more than the 4 bytes of the ID added. If the checksum is OK we know to continue through our logic to display something on the LCD, if it is not correct, we know there was an error, so we display "Tag Error" "Try Again", on the display.
if (status == MI_OK)
{
checksum1 = str[0] ^ str[1] ^ str[2] ^ str[3]; // Calculate a checksum to make sure there is no error
if(checksum1 == str[4])
{
}
else
{
lcd.setCursor(0,0);
lcd.write(" Tag Error ");
lcd.setCursor(0,1);
lcd.write(" Try Again! ");
delay(2000);
}
myRFID.AddicoreRFID_Halt(); //Command tag into hibernation }
If the Checksum checks out, it is time to use our testkey() function that we wrote earlier. As long as the name returned does not equal "i" we know it is a valid key and the name associated will be returned with the testkey() function. However, if an "i" is returned we know to display "Access Denied". Here is how the Checksum Loop will look now:
if(checksum1 == str[4])
{
Tag_Name = testkey(str,keys,Names);
if(Tag_Name != "i")
{
lcdprintwelcome(Tag_Name);
delay(2000);
lcdprintmain();
}
else
{
lcdaccessdenied(); //If the read tag isnt in our data base, we will print an Access Denied message
delay(2000);
lcdprintmain(); // refresh to home screen
}
}
Displaying names in the LCDThere you have it, now you have code that based on approved keys and names associated to that key, will display these names on the LCD. You can download* the full code for this RFID LCD tutorial here.
Let's go ahead and test it out.
Awesome! It works. When I scan the key Fob it notices that Josh was the owner associated to this Key Fob.
Now what if I try the Key Card?
"Access Denied" - Just as expected. The Key Card's key was never put into the table so the Arduino is behaving correctly and displaying the correct message.
What good in having one key? Next I'll run the Addicore RC522 RFID module tutorial test code to get the ID off the Key Card. It is [19] [89] [111][ 133]. I'll go ahead and edit the code to accept this Key and associate the name to this key ID as "Brad".
// Define All Key Codes
uchar keys[16] = {
134 , 224, 134, 141, //Josh ID - These 4 digits are your 1st users ID Bytes
19 , 89, 111, 133, //Brad ID- These 4 digits are your 2nd users ID Bytes
111 , 111, 111, 111, // Dummy 1 ID - These 4 digits are your 3rd users ID Bytes
222 , 222, 222, 222 // Dummy 2 ID - These 4 digits are your 4th users ID Bytes };
String Names[4] = {
"Josh", // 1st User- what will be printed to LCD
"Brad", // 2nd User- what will be printed to LCD
"Dummy1", // 3rd User- what will be printed to LCD
"Dummy2" // 4th User- what will be printed to LCD };
Then I will scan the card again:
Look at that, now the Key Card works and displays "Brad".
You can easily expand on this to add a relay driving a solenoid to lock/unlock a front door, open/close a garage door or even turn on or off a radio. Keep your eyes out for a future tutorial that I will go over how to control this relay. I'll even integrate it into this RFID LCD demo.
Go ahead and download* the full code for this RFID LCD tutorial here. Make sure you change your Key IDs otherwise my keys will work on your project!
Comments