Before we get started with the reading and writing of the RFID tags using the Raspberry Pi, we will first look at some of the RFID basics so that we can fully use the technology. RFID is an acronym for Radio-Frequency IDentification. The name describes a technology with which we can read and write data on an RFID tag with an RFID reader that is connected to a computer.
Every RFID system always includes an RFID-reader and RFID tags. RFID tags come in various colors and sizes. This kit includes RFID cards and keychains but there are also small RFID stickers that can be utilized to implement the technology. Most RFID tags are quite similar to each other. The largest component is the antenna which is usually placed on the outside. The other components include the logic hardware of the chip, and the data storage components often found in the middle of the tag.
RFID tags fall under the category of passive tags. This means that they don’t have a battery and they get powered by the RFID reader. When the RFID reader is started, it creates an electromagnetic field. This field is the power supply for an RFID tag (obviously it needs to be close enough to the RFID reader). The RFID tag receives this energy with the antennas and then powers the logic on the tag. This is the first and crucial step for starting the communication. The included RFID tags can not only be read but can also be written with new information. In order for the transmission of data from the tag to the RFID reader to take place, the RFID tag manipulates the created field with their antennas, and uses this manipulation to transmit information. The advantage of this is that the transponder can be extremely small due to not needing a power supply. The disadvantage however is the small distance between the tag and the reader.
When discussing RFID it is beneficial to also discuss NFC in order to keep from getting confused by these two technologies. NFC, or Near Field Communication, is a type of RFID which uses 13.56 Mhz. This frequency is the reason why we can use some NFC technologies with the RFID reader. NFC is a rather new technology and also allows two different devices, such as smartphones, to communicate with each other. There are also digital payment solutions that utilize NFC technology.
RFID and the Raspberry Pi
Now that we have discussed the basics behind RFID, our next step is to integrate the RFID reader with the Raspberry Pi. We will use the SPI protocol to interface the Raspberry Pi with the RFID reader. We have an online how to guide for SPI located at http://cw42.de/spi. From your Raspberry Pi OS you can start spi from a terminal shell via the commands
sudo raspi-config -> 5 Interfacing Options -> P4 SPI -> Yes -> Ok
|RC522 Module||Raspberry Pi|
|1 - SDA||GPIO8 CE0|
|2 - SCK||GPIO11 SCKL|
|3 - MOSI||GPIO10 MOSI|
|4 - MISO||GPIO9 MISO|
|5 - IRQ|
|6 - GND||GND|
|7 - RST||3.3V|
|8 - 3.3V||3.3V|
Installing the library
Before we can actually get started with the RFID Reader, we first need to install the necessary Python library. As stated earlier, we are using the SPI protocol for communication, but because we are not only sending data but receiving as well(for reading the rfid tags), the programming is more complicated. Lucky for us, there is already a library for our needs which is quite easy to use. This library has a dependency (other programs which the library depends on) that will also need to be installed during this process. So let's get started. Execute the commands below from a terminal shell:
git clone https://github.com/lthiery/SPI-Py.git
sudo python setup.py install
And now the RFID-Reader library
git clone https://github.com/coding-world/MFRC522-python.git
You can see the results after executing the Read.py file and then touching the RFID reader with with an RFID card or keyring. You should see the following terminal output:
sudo python Read.py
Card detected Card read UID: 219,160,58,213 Size: 8
If you don’t see a similar terminal output (in the best case wait for a few seconds) you probably made a mistake connecting the RFID reader to the Pi or when activating the RFID reader library. Just repeat the steps above.
Working with the RFID Tags
Now that we can read data from a RFID tag, the next step is to write data, or rather, change the data on the tag. For this we will change the Write.py file.
Every RFID tag has a UUID (Universally Unique Identifier) which is different from all other RFID tags. It is important to note that though we can also write other information on the tags, they usually don’t have a lot of space for saving information. You have likely seen these used in public swimming pools or even in the workplace for time tracking reasons.
Our RFID tag has 16 sectors. In every sector we can save a number from 1 to 225. You can see the content of every sector with the Read.py . A new RFID tag usually has no data on it, so you should see the following output:
Sector 8 [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
16 sectors and they are all showing a 0. Working with computers can be very rewarding, but just having numbers can be quite a bit complicated for the human mind. It would be much easier if we could save letters. For example, 0 could be the letter A and 1 could be the letter B, and so on. Developing this system on our own would be a ĺot of work. Once again we are lucky enough to be in a time where people have already done this work for us. The standard to combat this problem is called ASCII which stands for American Standard Code for Information Interchange. This system already has all of the letters which we need for basic communication and Python already knows how to translate it. You can find additional information online.
So let's start with a small Python program with which we can use to translate a terminal input, into ASCII Code (we will use this for the RFID cards later).
name=raw_input("Input a card name: ") if len(name)>16: name=name[:16] data = [ord(x) for x in list(name)] print data
This actually looks more complicated than it is. On the first line we are getting the terminal input from the user. Everything that the user typed into the terminal is saved into the variable name.
raw_input(“question ”) allows us to ask a question in the terminal and then save this input. While the user is answering the question the program is on halt. This is good practice so that we can easily save and work with user inputs.
Because we only have 16 spaces available, on line 2 we are checking if the user entered more than 16 letters. To do this we are using an “if” clause.
if len(name)>16: means if the string inside the variable name has more than 16 characters then do the following task.
With the built in python function
len() we can count the length of an string. Here is a small example:
print len(“This is a test”)
The 3 lines of code are only executed when the string is longer than 16 characters. With
name=name[:16] we are only saving the first 16 characters into the variable name. With this code we can easily cut a string with NameOfTheVariable[startNumber:endNumber], and either print it or save it into the old(or new) variable.
In the next line of coding we are translating the string into ASCII
data = [ord(x) for x in name]
data is the variable in which we will save the ascii output. Next the focus is on
[ord(x) for x in list(name)] as we need to separate it into two parts:
for x in name. The first part is a Python function which we can always utilize:
print ord("A") (A is e.g. 97). The second part is a for-loop which allows us to check every part of the loop separately. With
x in we can execute a function for every part of the variable/string. This is also known as iterating. The x is only variable for a certain party (in this case letter) of the string. ['h', 'a', 'l', 'l', 'o'] would be ord(„h“) ord(“a“) ord(„l“) and so on. In the end it would be: [104, 97, 108, 108, 111]
Once we have successfully learned how to convert letters into numbers the next step is mastering saving the values on a RFID Tag.
To save energy for other coding programs we will use the Write.py as a basis and copy it into another file. We will then edit its coding to perform the functions we desire.
cp Write.py MyWrite.py
Now we can open the file in a text editor with the following command
nano MyWrite.py and edit it. The first step is to add our ASCII program in line 8.
#!/usr/bin/env python # -*- coding: utf8 -*- import RPi.GPIO as GPIO import MFRC522 import signal name=raw_input("Gib einen Kartennamen ein: ") if len(name)>16: name=name[:16] data = [ord(x) for x in list(name)] continue_reading = True
For this program to work you will also need to go to line 56 and 77 and comment out the data variable. You can do that by simply adding a “#” into the first character of the line. If we don’t comment out this line, the variables will be written over our data variable and the program won’t work. If you use nano for editing you can also search for the data variable with
Strg/Ctrl + w and the search term and Enter.
We have also made our version of the program available, you can download it here:
Next, execute the program
python MyWrite.py. Enter a new name when prompted and hold your RFID tag above the reader. After this, start Read.py and observe the new content:
Sector 8 looked like this: Sector 8 [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] Data written It now looks like this: Sector 8 [104, 97, 108, 108, 111, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255]
You can see in the text above that we used the term hallo . 255 is for the empty characters we did not use in the String.
With this knowledge you are now able to write your own words or code on RFID tags. You can rewrite the information to the tag several times with around 10,000 being the limit. So don’t hesitate to use this power.
Reading RFID Tags
We could already see the ASCII Output with the Read.py program but we are after an alphabetic representation rather than the numbers. For this purpose we not only need to modify the Read.py program, but also the MFRC522.py file. Open the MFRC522.py file in a text editor as we did earlier and add the following code in line 377:
It should look like this:
python if len(backData) == 16: print "Sector "+str(blockAddr)+" "+str(backData) return backData
We have also prepared a ready file for this:
The next step is to create our own reading program.
cp Read.py MyRead.py
Once created, change the following code:
# Check if authenticated if status == MIFAREReader.MI_OK: MIFAREReader.MFRC522_Read(8)
We need to add a variable in front of the
MIFAREReader.MFRC522_Read(8) so that we can access the content of the RFID tag for later usage. This was not the case in the previous coding of the program.
# Check if authenticated if status == MIFAREReader.MI_OK: data = MIFAREReader.MFRC522_Read(8)
So what did we do exactly?
.MFRC522_Read(8) is a function in the MFRC522.py program. This function normally only prints the content of the RFID tag sectors. We added the
return in the first change so that we could not only can see the output, but also work with it later. The next step was to make use of this return value and save the the output of
.MFRC522_Read(8) in the variable data. In the next step we will convert the ASCII content in the Variable into readable string. Add the lines of code below after
data = MIFAREReader.MFRC522_Read(8)
text = "".join(chr(x) for x in data) print text
This code is quite the opposite of what we used in the MyWrite.py. In this code we are using the functions
join() connects different strings together and
chr(x) for x in data makes a
chr(x) for every entry and converts every number back to a letter.
chr() is the direct opposite of
ord(). Normally it would output than "h", "a", "l", "l", "o", but due to our usage of the ‘join()’ function it is creating just one word.