RFID
Reading and Writing to RFID tags
Reading and Writing to RFID tags
What I wanted to learn, and why it interested me: I wanted to learn how RFID scanners work and see its applications. RFID scanners are everywhere in this world and play a huge part in security (credit cards, ID badges, ... etc), so I figured it would learn how they operate.
Final outcome: I built an RFID scanner system that detects if an RFID tag that is scanned is or is not an authorized user. If a user is authorized, a green LED blinks and the LCD screen displays "Authorized". If a user is not authorized, a red LED blinks and the LCD screen displays "Denied".
Images of final creative/exploratory output
Working LCD screen displaying "Authorized" when a correct RFID tag is presented, and "Denied" when an incorrect tag is presented.
Image showing wired RFID scanner on breadboard with LEDs. Also shown is the LCD display wired directly to the Arduino.
Process images from development towards creative/exploratory output
Soldered pins to RFID scanner and properly wired to Arduino..
Blinking LED when an authorized LED is detected.
Process and reflection:
The process of learning how to use the RFID tag went as expected. I started by reading a tutorial article that went over the basic connections and wiring for how to set up the system. I learned how to wire the system, what a MOSI, MISO, and RST pin is and how they interact with the Arduino. Once I learned how the wiring of the Arduino works, I tested out the system using a test module from the RFID library. The code for reading and writing to the RFID tags is very difficult to understand and honestly was the hardest part about this project. Thankfully, the library code worked well, and the functions were easy to modify for the specific system I designed. Overall, I think that this project was very fun and a good learning experience, however, I do think that there is limited applications to RFID technology outside of security/authorization purposes.
Technical details
/*
60-223 Intro to Physical Computing, fall 2025
Domain-specific Skill Building exercise: RFID Threat Detector
This code reads in an RFID tag ID from an RFID scanner. The helper
function readID() checks if new tag is detected and stores the tag
ID. The tag ID is then compared against the authorized tag ID. When
a tag ID matches the authorized tag, a signal is sent to the LCD
display saying "Authorized" or "Denied". Additonally, a signal
is sent to either an red or green LED based on whether it is an
authorized tag.
Pin mapping:
Arduino pin | role | details
------------------------------
10 input SS_PIN
9 input reset pin
8 output red LED
7 output green LED
Code by Cole Franklin, davidfra@andrew.cmu.edu
September 2025
*/
// Arduino RFID library initialization
#include <SPI.h>
#include <MFRC522.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
// Arduino RFID pin definitions for RC522
#define SS_PIN 10
#define RST_PIN 9
#define LED_red 8
#define LED_green 7
#define BUZZER 4
byte readCard[4];
String tag_UID = "83D443DD"; // Replace this with the UID of your tag!!!
String tagID = "";
// create LCD screen variable with sizing
LiquidCrystal_I2C screen(0x27, 16, 2);
// Create MFRC522 instance
MFRC522 mfrc522(SS_PIN, RST_PIN);
// counter variable for updating LCD screen
int quarterTimer = 0;
unsigned long LCD_reset_timer = 0;
void setup()
{
pinMode(LED_red, OUTPUT);// initialize digital pin LED_BUILTIN as an output.
pinMode(LED_green, OUTPUT);
digitalWrite(LED_red, LOW); // turn the LED off by making the voltage LOW
digitalWrite(LED_green, LOW);
Serial.begin(115200); // Initialize serial communications with the PC
SPI.begin(); // SPI bus
mfrc522.PCD_Init(); // Initialise MFRC522
// initialize the screen (only need to do this once)
screen.init();
screen.backlight();
screen.home();
screen.clear();
screen.setCursor(0, 0);
screen.print("RFID Ready");
screen.setCursor(0, 1);
screen.print("Scan a tag...");
}
void blinkLED(int pin, int times, int ms = 150) {
for (uint8_t i = 0; i < times; i++) {
digitalWrite(pin, HIGH);
delay(ms);
digitalWrite(pin, LOW);
delay(ms);
}
}
void reset_display()
{
// only update screen every 0.25s
if((millis()-LCD_reset_timer) >= 5000)
{
screen.home();
screen.clear();
screen.setCursor(0, 0);
screen.print("RFID Ready");
screen.setCursor(0, 1);
screen.print("Scan a tag...");
//update quarter timer to global clock timer
LCD_reset_timer = millis();
}
}
// function to update the LCD screen with values
void update_display(bool isValid){
// only update screen every 0.25s
if((millis()-quarterTimer) >= 250){
screen.home();
screen.clear();
if (isValid)
{
screen.print("AUTHORIZED ");
}
else {
screen.print("DENIED ");
}
//update quarter timer to global clock timer
quarterTimer = millis();
}
}
void loop()
{
//reset display after 3 seconds
reset_display();
//Wait until new tag is available
while (readID())
{
if (tagID == tag_UID)
{
blinkLED(LED_green, 3, 150);
update_display(true);
digitalWrite(BUZZER, LOW);
}
else
{
blinkLED(LED_red, 3, 150);
update_display(false);
digitalWrite(BUZZER, HIGH);
}
}
}
//Read new tag if available
//code from library example code
boolean readID()
{
//Check if a new tag is detected or not. If not return.
if ( ! mfrc522.PICC_IsNewCardPresent())
{
return false;
}
//Check if a new tag is readable or not. If not return.
if ( ! mfrc522.PICC_ReadCardSerial())
{
return false;
}
tagID = "";
// Read the 4 byte UID
for ( uint8_t i = 0; i < 4; i++)
{
//readCard[i] = mfrc522.uid.uidByte[i];
tagID.concat(String(mfrc522.uid.uidByte[i], HEX)); // Convert the UID to a single String
}
tagID.toUpperCase();
mfrc522.PICC_HaltA(); // Stop reading
return true;
}