Contents
1.Background
2. Tutorial Overview
3. Getting Started With RFID Reader Kit
4. C# Serial Client For Reading The Tag
5. Integrating RFID to Internet Of Things( IoT)
5.1 RFID Client: Connecting RFID to IoT
5.2 Fetching RFID Tag remotely
6. Conclusion
RFID or Radio Frequency Identification is one of the most popular smart objects in Internet of Things. Smart Tags with a unique number is available in all sorts of forms like cards to key rings. It can be used for personal identification in attendence systems, in bank locker opening and in smaller spplications like a replacement for keys in home and car locks. RFID tags are quite cheap, efficient and durable making them an attractive choice for several applications. RFID reader is an electronic device that can read the RFID tags and can send the read data through serial port. So from a serial client application this data can be consumed and used for futher logic or analysis purpose. Even though there are several serial communication software available along wit the option of coding through literally every programming languages, while browing the internet you would not get too many resources in RFID that actually works. That is because there are more to programming with RFID and using it than simple serial communications. There are many issues which might not even permit you to get started with the devices. In this tutorial we shall build a really efficient RFID client. Not only that we are going to integrate that into an IoT infrastructure so that the tag can be read by a remote Arduino hardware which could take appropriate decision based on the tag. The concept is elaborated in the next section.
Figure 2: Overall Concept of the Tutorial
Figure 2 Explains in detail what we are looking for in this tutorial. We want a RFID reader module to be connected over Internet of Things through a C# RFIDClient. The client app will real the Tag from RFID reader over serial communication and push to a cloud storage through our custom web service. This tag will be polled by a remote client which will be connected to Arduino device. Arduino must read the tag from Cloud with the help of C# RemoteClientForRFID, match the tag with a stored tag and trigger an hardware event based on authentication result.
RFID reader kit comes with a RS232 9 Pin port. With All possibility you would want to connect it to your laptop. So you need a RS232 to USB converter cable as shown in Figure 3.1.
Figure 3.1: RS232 to USB Cable ( Image Curtesy:snapdeal.com)
Once you get this, you might very well assume that all your job is over. But it is far from true. The cable needs a driver. Yes you will get a driver along with the cable and that driver does not work. No matter what you try, you would not be able to work with the cable. But there is a ray of hope.
We have a Windows Vista 32 Bit Driver from http://www.tri-plc.com/. Yes, no matter whether you run Windows 7/8 64/32 bit, the only driver that works fine with this cable is Vista 32 Driver for RS232/USB Converter Driver.
So install the driver.
You need a +9V Adapter to power up your RFID device. Power up the device, connect USB cable. In order to check that your device is properly working, you need to ensure that your cable and hence the reader is detected by your system. Open Device manager and check out COM and LPT Port. You will see USB to Serial Converter Detected at Specific Port as shown in Figure 3.2.
Figure 3.2: RFID device connection check through USB -To-Serial Com Port
Now, keep Couple of your RFID Card ready. Following is a figure depicting my arrangement with RFID cards, Reader, 9V Adapter and RS232/USB converter Cable.
Figure 3.3 Primary Setup for RFID
You may also connect RFID reader with a 9V battery pack. Once supply is given, reader buzzer will be on for some good two minutes time. I do not know why should a buzzer be active for that longer, especially if you are turning it on after some time. Once the buzzer is off along with the greeen LED, you can bring the card nearer to the device for reading as shown in figure 3.4. When the card's tag is read by the reader, there will be a buzzer sound and the LED will be on for some period of time( about half second).
Figure 3.4: Reading RFID Tag
In above figure you can the LED glowing soon as you bring the tag near to the reader. RFID is a short range radio technique. So you need not touch the card with reader.
Soon as the reader detects the tag, it sends the value to serial port. There is a inbuilt delay in the port in order to wait for some time before detecting another card. Therefore chances of same card being detected in quick succession is low.
Having successfully set up the device and it's driver, it's finally time now for some coding. Iassure you that working with RFID is much more than simply reading serial data as being made out by some blogs!
You need to check out my tutorial on Configuring Arduino as IoT node and especially the C# Serial Client Section to understand the essential of C# Serial communication with external devices.
In the case of Arduino, we can set the Serial communication baud rate and therefore in the client we can select the rate accordingly. But in case of RFID reader, though we can identify the Serial port number, question is how to identify the baud rate. A thumbrule for Serial devices is that if not otherwise specified, they communicate at 9600 baud rate. So while designing designing the we can simply select the appropriate serial port with 9600 Baud rate. Now we feel that we are done!
However there are few twists in the tale!
Let us first test how tag is sent by testing the reader with an Arduino Serial Monitor.
Figure 4.1: Reading RFID Tag through Arduino Serial Monitor
You see that 12 byte tag is being read but read without any new line. This is a significant point. Now let us see the serialPort DataReceived event handler in C# that we have used so far.
private void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
{
string s = serialPort1.ReadLine();
this.BeginInvoke(MyDlg, s);
}
The problem with above code is that it never completes reading the serial port data because there is no line ending here.
So let us use ReadExisting()
, instead of ReadLine()
. So our updated code is now:
private void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
{
string s = serialPort1.ReadExisting();
this.BeginInvoke(MyDlg, s);
}
Also in our Display method, we would simply handle the string and put it in list box.
void Display(string s)
{
listBox1.Items.Add(s);
textBox1.Text = s;
}
Let's now test the application!
Figure 4.2: Reading RFID Tag in C# Serial Client
This is where the design gets trickey. And this is the exact reason you don't find too many working examples of RFID in net.
Now we see that for the first time, the tag is read correctly. Then onwards it gets unpredictable. That is because the reader module keeps on sending read bytes to the port.
So what if we store the tag length in a variable, and always read serial port upto that length? Bellow is the implementation of the logic of "reading upto the size of tag".
int tagSize = -1;
private void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
{
if (tagSize == -1)
{tagSize=serialPort1.BytesToRead;
}
char[]buff=new char[serialPort1.BytesToRead];
serialPort1.Read(buff,0,serialPort1.BytesToRead);
String tmpS = new String(buff);
if (tmpS.Length == tagSize)
{
s = "";
this.BeginInvoke(MyDlg, tmpS);
return;
}
if (s.Length < tagSize)
{
s = s + tmpS;
}
else
{
tmpS = s;
s = "";
this.BeginInvoke(MyDlg, tmpS);
}
}
From the onset of the program, it looks as though it should work, right?
Well, it does better than the first attempt, but not good enough to be trusted as seen in the result in figure 4.3.
Figure 4.3: Reading Tag through Modified logic
This problem literally drove me crazy and is one of the reasons for me to opt to write this tutorial. As an Embedded programmer, you always look for robustness and efficiency. So can't gem of a language like C# provide a real solution to such a problem?
After hours of trials and errors and plenty of caffeine intake, I finally got the solution.
Observing the pattern carefully reveals that tag data will be present serially in order. So if we club whole data into a single string and somehow knew the first character, then we can scan from that character. Unfortunately we do not know the first or last or for that matter any characters. But what we know is the exact length of the tag, because for the first time it is read as a whole( a big thank for that to whomsoever it may concern)!
So I put the characters into a textbox as and when they arrive. In the textbox text change property I keep checking for the length. If the length is same as the tag size, then we take the text box contains and put it in list box, freeing the text box.
So, here is how our SerialPort DataReceived event handler, TextChanged of textBox1 event handler and Display method invoked by the delegate are shaped up.
string s = "";
string mydata = "";
int tagSize = -1;
private void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
{
if (tagSize == -1)
{
tagSize = serialPort1.BytesToRead;
}
char[] buff = new char[serialPort1.BytesToRead];
serialPort1.Read(buff, 0, serialPort1.BytesToRead);
String tmpS = new String(buff);
this.BeginInvoke(MyDlg, tmpS);
}
void Display(string s)
{
textBox1.Text = textBox1.Text+s;
}
private void textBox1_TextChanged(object sender, EventArgs e)
{
if (textBox1.Text.Length >= tagSize)
{
listBox1.Items.Add(textBox1.Text);
textBox1.Text = "";
}
}
That's it! And when you test, you would be more than happy to see a consistent result. Figure 4.4 demonstrates the process of testing and figure 4.5 shows the screen dump showing consistant data reading of RFID tags.
Figure 4.4 Testing RFID
Figure 4.5: Perfect RFID Tag Reading using our Approch
We will also change the projId
so that the tag is handled independently.
We have already built our own infrastructure middleware for IoT in this tutorial of integrating Arduino as an IoT Node. We have developed and hosted the live WebService at:
We will use this custom Service to bind our RFID module with IoT and then demonstrate an action with associated with it.
string projId = "RFIDIoT";
Now we need to work on two different modules: First RFIDClient, which would be Connected to RFID device and secondly the remote client which will be connected to Arduino board.
Figure 5.1: RFIDClient Module Design
Figure 5.1 Reveals the design of RFIDClient. As I am running both the peers of module in the same system, both are bound to have same IP address. User needs to enter the IP address of the remote computer on the txtRemoteIp TextBox
. As data ( RFID Tag) is read from the RFID reader module, textBox1
's TextChanged
event will be triggered. All we need to do here is check if user wants the data to be sent through the service or not, if so, the data will be sent using ServiceReference
of the web service called iotClient
.
BackgroundWorker bw = null;
string remoteIP = "";
string tag = "";
private void textBox1_TextChanged(object sender, EventArgs e)
{
if (textBox1.Text.Length >= tagSize)
{
tag = textBox1.Text;
listBox1.Items.Add(textBox1.Text);
textBox1.Text = "";
if (checkBox1.Checked)
{
remoteIP = txtRemoteIP.Text;
bw = new BackgroundWorker();
bw.DoWork += new DoWorkEventHandler(bw_DoWork);
bw.RunWorkerAsync();
}
}
}
void bw_DoWork(object sender, DoWorkEventArgs e)
{
try
{
iotClient.InsertCommand(projId, remoteIP, "LED ON", "TAG:" + tag, DateTime.Now, "EXECUTE");
}
catch
{
}
}
We shall use a BackgroundWorker
so that the remote call does not block the UI thread.
Having sent the RFID tag remotely, our next task is to build a RemoteClient for RFID reader which will consume the tag Data. I call this module RemoteClientForRFID
.
This is the machine whose IP address was provided in RFIDClient. This module should be connected to Arduino. Arduino should read the tag serially. If the Tag matches to a prestored tag, It sends a Serial Command called "Matched", else it sends a Serial Command called "Failed".
The Arduino device also turns on the PIN 13 LED for a period of 5 Sec, if the Tag matched. This concept can be used to develop security extensions where you can drive a relay associated with pin 13 in order to switch on certain doors or bank lockers so on.
The device also shows the incoming tag in a LCD with Info OK or BAD depending upon whether the tag matched or not respectively. You can obviously use the matching logic even in C# code if you want to integrate a database with the App. I wanted to show the comparision in Arduino, so I have decided to use the matching at the hardwarew level itself.
In the mean time to understand how LED can be controlled and how you can connect LCD with Arduino please refer to my beginner's tutorial on connecting hardware with Arduino.
Here is the Arduino sketch, which reads data from Serial Port, compares the tag and glows LED if matched.
#include <LiquidCrystal.h>
LiquidCrystal lcd(9,8,7,6,5,4);
void setup()
{
pinMode(13,OUTPUT);
digitalWrite(13,LOW);
lcd.clear(); lcd.begin(16,2); Serial.begin(9600);
}
void loop() {
lcd.print("RFID Tag:");
String content = "";
char character;
char data [13];
int number_of_bytes_received;
if(Serial.available() )
{
number_of_bytes_received = Serial.readBytesUntil (13,data,12);
data[number_of_bytes_received] = 0;
lcd.setCursor(0,1);
lcd.print(data);
if(strcmp (data, "510074C3AC4A")==0)
{
Serial.println("Matched");
lcd.setCursor(13,1);
lcd.print("OK");
digitalWrite(13,HIGH);
delay(5000);
digitalWrite(13,LOW);
}
else
{
Serial.println("Failed");
Serial.println(strcmp (data, "510074C3AC4A"));
lcd.setCursor(13,1);
lcd.print("BAD");
}
}
delay(2000);
lcd.home(); }
Finally we need a C# Client which we call RemoteClientForRFID
to poll the command from IoT middleware and push to Arduino device.
Figure 5.2 Shows the screenshot of this client.
Figure 5.2 RemoteClientForRFID
The core of this client is a timer that keeps polling the commands being sent for this client. It also reads the Serial data and logs in the ListBox as local data.
private void timerPoll_Tick(object sender, EventArgs e)
{
timerPoll.Enabled = false;
try
{
string s = iotClient.CommandToExecute(projId, labIp.Text);
if (s.Length > 0)
{
string tag=s.Split(new char[]{'#',':'})[2];
listBox1.Items.Add(tag);
serialPort1.WriteLine(tag);
iotClient.DeleteCommand(projId, labIp.Text);
}
}
catch
{
}
timerPoll.Enabled = true;
}
Recall from our Arduino as IoT node tutorial that CommandToExecute()
returns the result as a String that contains Command ( the Tag), sender's IP, Time of the generation of the command and the status of the command. Here we are deleting the command as it is processed so as to reduce the database storage.
So you need to run this client first. Connect with Arduino, it keeps checking for Tag through remote web service. The IP address of this client needs to be entered in RFIDClient's Remote Ip Address TextBox and "Send To Remote" CheckBox must be checked. Once you provide the tag, it will read the tag and will send the information remotely which will be fetched by remote client connected to Arduino and will be processed.
Figure 5.3 Shows a Successfull Tag Authentication.
Figure 5.3: Successfull RFID Tag Authentication
Figure 5.4 Shows the Wrong Authentication Result in LCD and 5.5 Shows the Correct Authentication.
Figure 5.4: Wrong Authentication
Figure 5.5: Correct Authentication
RFID is one of the smart objects over IoT. This is no new device and embedded programmers are being using it for long. But when you look for a decent tutorial that shows RFID working with C# you wouldn't find too many. Further I could not find a detail tutorial that elaborates how to use smart tags over internet of things and how to access them remotely. This tutorial is an effort to guide you through using RFID with Internet of things. You can develop your own services and application extensions over the foundation provided in this tutorial to build real cool stuff. I hope you enjoyed this tutorial which is the last in the series of my beginner's tutorial series for Internet of Things with Arduino.
gasshopper.iics is a group of like minded programmers and learners in codeproject. The basic objective is to keep in touch and be notified while a member contributes an article, to check out with technology and share what we know. We are the "students" of codeproject.
This group is managed by Rupam Das, an active author here. Other Notable members include Ranjan who extends his helping hands to invaluable number of authors in their articles and writes some great articles himself.
Rupam Das is mentor of Grasshopper Network,founder and CEO of Integrated Ideas Consultancy Services, a research consultancy firm in India. He has been part of projects in several technologies including Matlab, C#, Android, OpenCV, Drupal, Omnet++, legacy C, vb, gcc, NS-2, Arduino, Raspberry-PI. Off late he has made peace with the fact that he loves C# more than anything else but is still struck in legacy style of coding.
Rupam loves algorithm and prefers Image processing, Artificial Intelligence and Bio-medical Engineering over other technologies.
He is frustrated with his poor writing and "grammer" skills but happy that coding polishes these frustrations.