The RFID Basics
Types of Tags
There are 2 major types of tags available - Active & Passive.
Active Tags
Passive Tags
Passive Tags on the other hand get their power from the electromagnetic energy produced by the Reader (Electromagnetic Induction). These are cheap and are the most commonly used RFID tags (ID Cards, etc).
Interfacing an RFID reader with Induino R3 / Arduino
Software Serial
Its pretty annoying to remove the connection every time you have to upload a new program. This is required as the same pins are used both by our computer (for programming) and the RFID reader. We can overcome this by using Software Serial - The ability to use any 2 pins on an Arduino for Serial communication. This is made possible by the SoftwareSerial library in Arduino which programatically simulates Serial Communication. Now Lets change our connections and experiment with this.
Here's the modified Program
What is RFID?
RFID stands for Radio Frequency IDentification. RFID is a basic technology that allows the identification of a device (read tag / sticker / label) to be read wirelessly by a Reader(RFID reader) using Radio Frequnecy.
How does it work?
The Tag contains a small IC containing the Identity Information. The IC is attached to an antenna and transmits its identity to a Reader when it detects a Reader. It detects a Reader by detecting the electromagnetic energy produced by the Reader. The Identity information is transmitted as Radio Frequencies. The Reader then converts the received Radio Frequencies into the Identity Data.
Types of Tags
There are 2 major types of tags available - Active & Passive.
Active Tags
Active tags have an embedded power source and use it to transmit data. Owing to this reason they are expensive and are not viable for large scale deployments.
Passive Tags
Passive Tags on the other hand get their power from the electromagnetic energy produced by the Reader (Electromagnetic Induction). These are cheap and are the most commonly used RFID tags (ID Cards, etc).
Interfacing an RFID reader with Induino R3 / Arduino
Most RFID readers provide with a Serial Interface for connecting to a microcontroller. Some of the readers also provide another interface called the Weigand Intreface. However for the scope of our tutorial we will stick to the Serial Interface. We shall also use the EM 18 RFID Reader Module available on our site as the reference. This is a 125Khz module and comes with both Serial and Weigand interfaces.
Since there is only 1 way communication (Reader to Microcontroller) the reader has only a Tx Pin. Connect the Reader as follows
- Connect the +5V of the Reader to the +5V pin on the Induino R3
- Connect the GND of the Reader to the GND pin on the Induino R3
- Connect the Tx pin of the Reader to the Rx pin on the Induino R3 - Make this connection after uploading the program otherwise you will not be able to upload to the Induino R3 / Arduino board as the Rx / Tx pins are used for Programming the Induino R3 / Arduino. Remember to take this connection out every time you re-program your Induino R3 / Arduino
- Leave alone the DET pin for now, we will connect this later
Reading a TAG
Lets first write a Simple Program that would read the value of a Tag and display it on the Serial monitor. Make a note of the value as we would use this in our next program.
Here's the Program
/* Induino R3 User Guide - Program 16.0 - Reading a TAG Value using the RFID reader
This sketch Reads the Value of a RFID Tag and displays it on the Serial Monitor
*/
int count = 0; // A variable to count the length of the Tag DATA
void setup()
{
Serial.begin(9600); // Initialize Serial Communication - Both with the RFID reader & the Serial Monitor
}
void loop()
{
if(Serial.available()) // Check if there is Incoming Data in the Serial Buffer. This is data coming from the RFID reader
{
count = 0; // Reset count to zero
while(Serial.available()) // Keep reading Byte by Byte from the Buffer till the Buffer is empty
{
char input = Serial.read(); // Read 1 Byte of data and store it in a character variable
Serial.print(input); // Print the Byte
count++; // Increment the Byte count after every Byte Read
delay(5); // A small delay - Removing this might make the Program run faster and not respond properly as data from the reader could be slow
}
// Print Tag Length
Serial.println();
Serial.print("Tag Length : ");
Serial.print(count);
Serial.println(" Bytes");
}
}
Now open the Serial Monitor and Show the TAG onto the RFID reader (You have to hold it very close to the Central part of the Reader) and you will get the value of the TAG displayed. Note this value down. Later, We shall do some additional programs to identify a Tag and do specific tasks.
Software Serial
Its pretty annoying to remove the connection every time you have to upload a new program. This is required as the same pins are used both by our computer (for programming) and the RFID reader. We can overcome this by using Software Serial - The ability to use any 2 pins on an Arduino for Serial communication. This is made possible by the SoftwareSerial library in Arduino which programatically simulates Serial Communication. Now Lets change our connections and experiment with this.
- Connect the Tx pin of the Reader to the digital pin 7 on the Induino R3 - We will use this as our Rx Pin for Software Serial. We can use Pin 1 for Tx as we are not going to connect anything
Here's the modified Program
/* Induino R3 User Guide - Program 16.1 - Reading a TAG Value using the RFID reader using Software Serial
This sketch Reads the Value of a RFID Tag and displays it on the Serial Monitor
*/
#include <SoftwareSerial.h> // include the Software Serial Library
SoftwareSerial rfid_reader(7,1); // Creat a Software Serial Object Mapping it to 7th pin as Rx and 1st Pin as Tx
int count = 0; // A variable to count the length of the Tag DATA
void setup()
{
rfid_reader.begin(9600); // Initialise Serial Communication with the RFID reader
Serial.begin(9600); // Initialise Serial Communication with the Serial Monitor
}
void loop()
{
if(rfid_reader.available()) // Check if there is Incoming Data in the RFID Reader Serial Buffer.
{
count = 0; // Reset count to zero
while(rfid_reader.available()) // Keep reading Byte by Byte from the Buffer till the RFID Reader Buffer is empty
{
char input = rfid_reader.read(); // Read 1 Byte of data and store it in a character variable
Serial.print(input); // Print the Byte
count++; // Increment the Byte count after every Byte Read
delay(5); // A small delay - Removing this might make the Program run faster and not respond properly as data from the reader could be slow
}
// Print Tag Length
Serial.println();
Serial.print("Tag Length : ");
Serial.print(count);
Serial.println(" Bytes");
}
}
Now open the Serial Monitor and Show the TAG onto the RFID reader (You have to hold it very close to the Central part of the Reader) and you will get the value of the TAG displayed.
Read More on Software Serial Here -> http://arduino.cc/en/Reference/SoftwareSerial
Matching Tags
To Match a Tag with a specific action, we need to get the Tag ID using the above program (16.0 / 16.1) Once we have the ID, we can use it in our program and compare it to the ID of any tag being presented. So, Lets try to toggle the state of a LED using a specific Tag ID.
Here's the Program
/* Induino R3 User Guide - Program 16.2 - Toggling a LED based on a RFID Tag
This sketch toggles the state of a led everytime the correct tag is presented.
*/
#include <SoftwareSerial.h> // include the Software Serial Library
SoftwareSerial rfid_reader(7,1); // Creat a Software Serial Object Mapping it to 7th pin as Rx and 1st Pin as Tx
char tag[] ="4F006DD86A90"; // The Tag ID which we got from Program 16.0
char input[12]; // A Variable to store the ID of the Tag being presented
int count = 0; // A counter variable to navigate through the input[] character array
boolean flag = 0; // A variable to store the Tag match status
boolean state = 0; // A variable to store the state of the Led to be toggled
void setup()
{
rfid_reader.begin(9600); // Initialise Serial Communication with the RFID reader
Serial.begin(9600); // Initialise Serial Communication with the Serial Monitor
pinMode(13,OUTPUT); // LED output
}
void loop()
{
if(rfid_reader.available())// Check if there is Incoming Data in the RFID Reader Serial Buffer.
{
count = 0; // Reset the counter to zero
while(rfid_reader.available() && count < 12) // Keep reading Byte by Byte from the Buffer till the RFID Reader Buffer is empty or till 12 Bytes (the ID size of our Tag) is read
{
input[count] = rfid_reader.read(); // Read 1 Byte of data and store it in the input[] variable
count++; // increment counter
delay(5);
}
if(count == 12) // When the counter reaches 12 (the size of the ID) we stop and compare each value of the input[] to the corresponding stored value
{
count =0; // reset counter varibale to 0
flag = 1;
while(count<12 && flag !=0) // Iterate through each value and compare till either the 12 values are all matching or till the first mistmatch occurs
{
if(input[count]==tag[count])
flag = 1; // everytime the values match, we set the flag variable to 1
else
flag=0; // if the ID values don't match, set flag variable to 0 and stop comparing by exiting the while loop
count++; // increment i
}
}
if(flag == 1) // If flag variable is 1, then it means the tags match
{
Serial.println("Matched!");
state = !state; // Toggle state
digitalWrite(13,state); // Apply the new state to the LED
}
else
{
Serial.println("Wrong Tag"); // Incorrect Tag Message
}
for(count=0; count<12; count++) // Fill the input variable array with a fixed value 'F' to overwrite all values getting it empty for the next read cycle
{
input[count]= 'F';
}
count = 0; // Reset counter variable
}
}
Now this should control the state of the 13th pin LED on the Induino R3 everytime you show the correct tag to it.
Using Interrupts
Now we have managed to identify a tag and control accordingly. However, our program has a small drawback. We keep checking for the tag all the time. If we can optimize this to check only when a tag is being present, we should be done. The DET pin on the RFID Reader outputs a constant high signal and gives a short LOW pulse when a Tag is presented. We can use this signal as an interrupt trigger and check the RFID readers serial line only when an interrupt is triggered. To make it more interesting, we will let a simple blink program run and get interrupted by the RFID reader.
Make the following additional connection
- Connect the DET line of the RFID reader to the digital pin 2 (Interrupt 0)
Here's the Program
/* Induino R3 User Guide - Program 16.3 - Toggling a LED based on a RFID Tag using Interrupts
This sketch is a simple blink that uses interrupts to toggle the state of a led everytime the correct tag is presented
*/
#include <SoftwareSerial.h> // include the Software Serial Library
SoftwareSerial rfid_reader(7,1); // Creat a Software Serial Object Mapping it to 7th pin as Rx and 1st Pin as Tx
char tag[] ="4F006DD86A90"; // The Tag ID which we got from Program 16.0
char input[12]; // A Variable to store the ID of the Tag being presented
int count = 0; // A counter variable to navigate through the input[] character array
boolean flag = 0; // A variable to store the Tag match status
boolean state = 0; // A variable to store the state of the Led to be toggled
boolean tag_ready=0; // A variable that is set by the ISR when an interrupt occurs
void setup()
{
rfid_reader.begin(9600); // Initialise Serial Communication with the RFID reader
Serial.begin(9600); // Initialise Serial Communication with the Serial Monitor
pinMode(13,OUTPUT); // LED output
pinMode(12,OUTPUT); // A Normal LED output for LED Blink
pinMode(2,INPUT); // Interrupt Pin defined as Input
attachInterrupt(0, check, FALLING); // Enable the Interrupt to call the ISR check when a Falling Interrupt occurs
}
void check() // The Interrupt Service Routine
{
tag_ready = 1; // Set the tag_ready variable
}
void loop()
{
if(tag_ready) // Check if the variable is set
{
process_tag(); // if the variable is set, call the process_tag() function
}
// Regular Blink Operation
digitalWrite(12,HIGH);
delay(500);
digitalWrite(12,LOW);
delay(500);
}
/* Function to Process the TAG and Act */
void process_tag()
{
if(rfid_reader.available())// Check if there is Incoming Data in the RFID Reader Serial Buffer.
{
count = 0; // Reset the counter to zero
while(rfid_reader.available() && count < 12) // Keep reading Byte by Byte from the Buffer till the RFID Reader Buffer is empty or till 12 Bytes (the ID size of our Tag) is read
{
input[count] = rfid_reader.read(); // Read 1 Byte of data and store it in the input[] variable
count++; // increment counter
delay(5);
}
if(count == 12) // When the counter reaches 12 (the size of the ID) we stop and compare each value of the input[] to the corresponding stored value
{
count =0; // reset counter varibale to 0
flag = 1;
while(count<12 && flag !=0) // Iterate through each value and compare till either the 12 values are all matching or till the first mistmatch occurs
{
if(input[count]==tag[count])
flag = 1; // everytime the values match, we set the flag variable to 1
else
flag=0; // if the ID values don't match, set flag variable to 0 and stop comparing by exiting the while loop
count++; // increment i
}
}
if(flag == 1) // If flag variable is 1, then it means the tags match
{
Serial.println("Matched!");
state = !state; // Toggle state
digitalWrite(13,state); // Apply the new state to the LED
}
else
{
Serial.println("Wrong Tag"); // Incorrect Tag Message
}
for(count=0; count<12; count++) // Fill the input variable array with a fixed value 'F' to overwrite all values getting it empty for the next read cycle
{
input[count]= 'F';
}
count = 0; // Reset counter variable
}
tag_ready=0;
}
Now this should control the state of the 13th pin LED on the Induino R3 everytime you show the correct tag to it. The LED on the 12th pin should be blinking all the while
Thats It For This Part! Enjoy... and feel free to drop us an email with questions you might have -> info@simplelabs.co.in
Visit www.simplelabs.co.in for more interesting products
Do different RFID card have different ID ?? If so can multiple Tasks can be done using multiple cards...
ReplyDeleteyes. they all have unique ids and can be used for different tasks
DeleteThis comment has been removed by the author.
ReplyDeleteNice article. If i want to make use of my android phone with nfc, Is it possible to make my android phone to be treated like a rfid reader? or do i need to get a nfc reader?
ReplyDeleteYou can use your android phone as a reader however that would require a lot of android skills + arduino skills... easier would be to buy a separate reader
DeleteSir,
ReplyDeleteMy EM-18 has no ttl outputs. so i used rs232 to ttl converter. Reader module has a dc supply option. so is there any change in connection? ttl pinouts are tx,rx,5v,gnd. Should i use 5v adapter to power EM-18
well you can use your arduino / induino for the 5V supply. There should be a ttl output somewhere on the reader... try tracing it.. if not the converter should work as well...
DeleteHi prakash,
ReplyDeleteI need to receive the string continuously which ends by '\0'
How can i do it can u help me ...............?
what is the read range? and what is the write range?
ReplyDeleterange as in distance? Well its very short - 1 to 4 cms.
DeleteThis comment has been removed by the author.
ReplyDeleteCan i use Active RFID tags with EM-18 RFID Reader module?
ReplyDeleteWell if you have the tag try it. We don't have any active tags around and are unable to test this.
DeleteHey, thanks for the wonderful tutorial. I tried to implement the same interrupt driven concept in my project. But for some reason, my input array ends up empty, even though a tag is detected. Can you please let me know why.
ReplyDeleteThe link to my code:
https://db.tt/NXcRjLgv
You are trying to use string comparsion on a character array... Thats the clue... now find out the difference between a character array and a string :) and change your program accordingly.
Deletehey
ReplyDeletei have written the same code as in your software serial but im not getting anything being shown on the serial monitor.any help?
my code:
#include
SoftwareSerial rfid(7,1);
void setup()
{
Serial.begin(9600);
rfid.begin(9600);
Serial.println("scanning");
}
void loop()
{
if(Serial.available())
{
while(rfid.available())
{
char input=rfid.read();
Serial.print(input);
}
}
}
#include what?
DeleteCan you post a clear photo of your connections? Does the RFID reader blinks an led or sounds a buzzer when the card is detected?
its #include
ReplyDeletehey, i am using ATK_RF_ID EM-18 Reader Module, USB to RS232 Converter for RFID setup... and using HyperTerminal for receiving the RFID tags...
ReplyDeleteSo i wanna know is there any API in any programming language, or any application that i can use to receive the tags in plain format and send them to mysql database...
Also, i dont have to use Arduino, MicroController, ATMEGA... or anything like that..
You may found EM-18 datasheet at
ReplyDeletehttp://www.nrdcentre.com/image/data/RFID/EM-18 Datasheett.jpg
Hi Prakash,
ReplyDeleteI am using this EM-18 Reader Module and it seems to work fine with the Induino R3 board. But i haven't been able to get it to deliver the RFID tag data using any other Arduino board. I have tried Arduino Yun, Genuino MKR1000 and RedBear Duo. I also tried Raspberry Pi 3 but don't get any data on UART Pin
Any ideas why this would be happening.
Thank you for your excellent tutorial! Best yet. However, I have wired an Arduino Uno R3 to the Itead PN532 RFID Module, as described using Arduino Pin 1 (Rx) and Pin 1 (Tx) to appropriate Itead pins but nothing shows on the Arduino serial monitor. RFID module Mode is set to UART. No errors in code. Please advise. Thanks!
ReplyDeleteThese are photos of my wiring. See Itead for pin layout.
ReplyDeleteWhite is Tx. Purple is Rx. Mode pins set to UART (L/L).
Thanks.
https://1drv.ms/i/s!AuwYVXTmJ7BBjKcdb2DV_CXzm7xN9Q
https://1drv.ms/i/s!AuwYVXTmJ7BBjKccj-dLfUfwpeabtA
ReplyDeleteI love it when individuals come together and share opinions. Great website, keep it up! hotmail login
Yes i am totally agreed with this article and i just want say that this article is very nice and very informative article.I will make sure to be reading your blog more. You made a good point but I can't help but wonder, what about the other side? !!!!!!THANKS!!!!!! click here
ReplyDelete