34. Chapter RFID
In this chapter, we will learn how to use RFID.
34.1. Project RFID
In this project, we will use RC522 RFID card reader to read and write the M1-S50 card.
|
RC522 module x1 |
Jumper Wires x7 |
|
Mifare1 S50 Standard card x1 |
Mifare1 S50 Non-standard card x1 |
34.1.1. Component Knowledge
34.1.1.1. RFID
RFID(Radio Frequency Identification)is a form of wireless communication technology. A complete RFID system is generally composed of a transponder and a reader. Generally, the transponder may be known as a tag, and each tag has a unique code, which is attached to an object to identify the target object. The reader is a device that reads (or writes) information in the tag.
Products derived from RFID technology can be divided into three categories: passive RFID products, active RFID products and semi active RFID products, among which, Passive RFID products are the earliest, the most mature and most widely used products in the market. It can be seen everywhere in our daily life such as, the bus card, dining card, bank card, hotel access cards, etc., and all of them are classified as close-range contact recognition. The main operating frequency of Passive RFID products are: 125KHZ (low frequency), 13.56MHZ (high frequency), 433MHZ (ultrahigh frequency), 915MHZ (ultrahigh frequency). Active and semi active RFID products work at higher frequencies.
The RFID module we use is a passive RFID product with the operating frequency of 13.56MHz.
34.1.1.2. MFRC522
The MFRC522 is a highly integrated reader/writer IC for contactless communication at 13.56MHz.
The MFRC522’s internal transmitter is able to drive a reader/writer antenna designed to communicate with ISO/IEC 14443 A/MIFARE cards and transponders without additional active circuitry. The receiver module provides a robust and efficient implementation for demodulating and decoding signals from ISO/IEC 14443 A/MIFARE compatible cards and transponders. The digital module manages the complete ISO/IEC 14443A framing and error detection (parity and CRC) functionality
This RFID Module uses MFRC522 as the control chip, and SPI (Peripheral Interface Serial) as the reserved interface.
Technical specs:
Operating Voltage |
13-26mA(DC)3.3V |
Idle current |
10-13mA(DC)3.3V |
Sleep current in the |
<80uA |
Peak current |
<30mA |
Operating frequency |
13.56MHz |
Supported card type |
Mifare1 S50、Mifare1 S70、Mifare Ultralight、Mifare Pro、Mifare Desfire |
Size |
40mmX60mm |
Operation temperature |
20-80 degrees(Celsius) |
Storage temperature |
40-85 degrees (Celsius) |
Operation humidity |
5%-95%(Relative humidity) |
34.1.1.3. Mifare1 S50 Card
Mifare S50 is often called Mifare Standard with the capacity of 1K bytes. And each card has a 4-bytes global unique identifier number (USN/UID), which can be rewritten 100 thousand times and read infinite times. Its storage period can last for 10 years.
The Mifare S50 capacity (1K byte) is divided into 16 sectors (Sector0-Sector15). Each sector contains 4 data block (Block0-Block3. 64 blocks of 16 sectors will be numbered according absolute address, from 0 to 63).
And each block contains 16 bytes (Byte0-Byte15), 64*16=1024. As is shown in the following table:
Sector No. |
Block No. |
Storage area |
Block type |
Absolute block No. |
|---|---|---|---|---|
sector 0 |
block 0 |
vendor code |
vendor block |
0 |
block 1 |
data block |
1 |
||
block 2 |
data block |
2 |
||
block 3 |
Password A-access control-password B |
control block |
3 |
|
sector 1 |
block 0 |
data block |
4 |
|
block 1 |
data block |
5 |
||
block 2 |
data block |
6 |
||
block 3 |
Password A-access control-password B |
control block |
7 |
|
...... |
...... |
...... |
...... |
...... |
sector 15 |
block 0 |
data block |
60 |
|
block 0 |
data block |
61 |
||
block 0 |
data block |
62 |
||
block 3 |
Password A-access control-password B |
control block |
63 |
Each sector has a set of independent password and access control put in its last block, that is, Block 3, which is also known as sector trailer. Sector 0, block 0 (namely absolute address 0) of S50 is used to store the card serial number and vendor code, which has been solidified and can’t be changed. Except the manufacturer and the control block, the rest of the cards are data blocks, which can be used to store data. Data block can be used for two kinds of applications:
used as general data storage and can be operated for reading and writing data.
used as data value, and can be operated for initializing, adding, subtracting and reading the value.
The sector trailer block in each sector is the control block, including a 6-byte password A, a 4-byte access control and a 6-byte password B. For example, the control block of a brand new card is as follows:
A0 A1 A2 A3 A4 A5 |
FF 07 80 69 |
B0 B1 B2 B3 B4 B5 |
password A |
access control |
password B |
The default password of a brand new card is generally 0A1A2A3A4A5 for password A and B0B1B2B3B4B5 for password B, or both the password A and password B are 6 FF. Access control is used to set the access conditions for each block (including the control block itself) in a sector.
For more details about how to set data blocks and control blocks, please refer to Datasheet.
By default, after verifying password A or password B, we can do reading or writing operation to data blocks. And after verifying password A, we can do reading or writing operation to control blocks. But password A can never be read, so if you choose to verify password A but forget the password A, the block will never be able to read again.
Hint
If you have any concerns, please contact us via: support@freenove.com
For Mifare1 S50 card equipped in Freenove RFID Kit, the default password A and B are both FFFFFFFFFFFF.
Schematic diagram
|
Hardware connection. If you need any support,please feel free to contact us via:
|
34.1.2. Configure SPI
34.1.2.1. Enable SPI
The SPI interface of raspberry pi is closed by default. You need to open it manually. You can enable the SPI interface in the following way.
Type the following command in the terminal:
$ sudo raspi-config
Then open the following dialog box:
Choose “5 Interfacing Options” -> “P4 SPI” -> “Yes” -> “Finish” in order and then restart your RPi. Then the SPI module is started.
Type the following command to check whether the module SPI is loaded successfully:
$ ls /dev/sp*
The following result indicates that the module SPI has been loaded successfully:
34.1.3. Code
The project code uses human-computer interaction command line mode to read and write the M1-S50 card.
34.1.3.1. Python Code RFID
There are two code files for this project. They are respectively under Python2 folder and Python3 folder. Their functions are the same, but they are not compatible. Code under Python2 folder can only run on Python2. And code under Python3 folder can only run on Python3.
First observe the project result, and then learn about the code in detail.
Hint
If you have any concerns, please contact us via: support@freenove.com
Use cd command to enter RFID directory of Python code.
$ cd ~/Freenove_Kit/Code/Python_GPIOZero_Code/34.1.1_RFID
Use python command to execute code “RFID.py”.
$ python RFID.py
After the program is executed, the following contents will be displayed in the terminal:
Here, type the command “quit” to exit the program.
Type command “scan”, then the program begins to detect whether there is a card close to the sensing area of MFRC522 reader. Place a M1-S50 card in the sensing area. The following results indicate that the M1-S50 card has been detected, the UID of which is E6CF5C8EFB (HEX).
When the Card is placed in the sensing area, you can read and write the card with the following command.
In the command read<blockstart>, the parameter blockstart is the address of the data block, and the range is 0-63. As is shown below:
In the command read<blockstart>, the parameter blockstart is the address of the data block, and the range is 0-63. This command is used to read the data of data block with address “blockstart”. For example, using command “read 0” can display the content of data block 0. Using the command “read 1” can display the content of data block 1. As is shown below:
Command “dump” is used to display the content of all data blocks in all sectors.
Command <address> <data> is used to write “data” to data block with address “address”, where the address range is 0-63 and the data length is 0-16. In the process of writing data to the data block, both the contents of data block before written and after written will be displayed. For example, if you want to write the string “Freenove” to the data block with address “1”, you can type the following command.
$ write 1 Freenove
Command “clean <address>” is used remove the contents of the data block with address “address”. For example, if you want to clear the contents of the data block 1 that has just been written, you can type the following command.
$ clean 1
Command “halt” is used to quit the selection state of the card.
The following is the program code :
1#!/usr/bin/env python3
2########################################################################
3# Filename : RFID.py
4# Description : Use MFRC522 read and write Mifare Card.
5# auther : www.freenove.com
6# modification: 2021/1/1
7########################################################################
8from gpiozero import OutputDevice
9import MFRC522
10import sys
11import os
12
13# Create an object of the class MFRC522
14mfrc = MFRC522.MFRC522()
15
16
17def dis_ConmandLine():
18 print ("RC522>",end="")
19def dis_CardID(cardID):
20 print ("%2X%2X%2X%2X%2X>"%(cardID[0],cardID[1],cardID[2],cardID[3],cardID[4]),end="")
21def setup():
22 print ("Program is starting ... " )
23 print ("Press Ctrl-C to exit.")
24 pass
25
26def loop():
27 global mfrc3s
28 while(True):
29 dis_ConmandLine()
30 inCmd = input()
31 print (inCmd)
32 if (inCmd == "scan"):
33 print ("Scanning ... ")
34 mfrc = MFRC522.MFRC522()
35 isScan = True
36 while isScan:
37 # Scan for cards
38 (status,TagType) = mfrc.MFRC522_Request(mfrc.PICC_REQIDL)
39 # If a card is found
40 if status == mfrc.MI_OK:
41 print ("Card detected")
42 # Get the UID of the card
43 (status,uid) = mfrc.MFRC522_Anticoll()
44 # If we have the UID, continue
45 if status == mfrc.MI_OK:
46 print ("Card UID: "+ str(map(hex,uid)))
47 # Select the scanned tag
48 if mfrc.MFRC522_SelectTag(uid) == 0:
49 print ("MFRC522_SelectTag Failed!")
50 if cmdloop(uid) < 1 :
51 isScan = False
52
53 elif inCmd == "quit":
54 destroy()
55 exit(0)
56 else :
57 print ("\tUnknown command\n"+"\tscan:scan card and dump\n"+"\tquit:exit program\n")
58
59def cmdloop(cardID):
60 pass
61 while(True):
62 dis_ConmandLine()
63 dis_CardID(cardID)
64 inCmd = input()
65 cmd = inCmd.split(" ")
66 print (cmd)
67 if(cmd[0] == "read"):
68 blockAddr = int(cmd[1])
69 if((blockAddr<0) or (blockAddr>63)):
70 print ("Invalid Address!")
71 # This is the default key for authentication
72 key = [0xFF,0xFF,0xFF,0xFF,0xFF,0xFF]
73 # Authenticate
74 status = mfrc.MFRC522_Auth(mfrc.PICC_AUTHENT1A, blockAddr, key, cardID)
75 # Check if authenticated
76 if status == mfrc.MI_OK:
77 mfrc.MFRC522_Readstr(blockAddr)
78 else:
79 print ("Authentication error")
80 return 0
81
82 elif cmd[0] == "dump":
83 # This is the default key for authentication
84 key = [0xFF,0xFF,0xFF,0xFF,0xFF,0xFF]
85 mfrc.MFRC522_Dump_Str(key,cardID)
86
87 elif cmd[0] == "write":
88 blockAddr = int(cmd[1])
89 if((blockAddr<0) or (blockAddr>63)):
90 print ("Invalid Address!")
91 data = [0]*16
92 if(len(cmd)<2):
93 data = [0]*16
94 else:
95 data = cmd[2][0:17]
96 data = map(ord,data)
97 data = list(data)
98 lenData = len(list(data))
99 if lenData<16:
100 data+=[0]*(16-lenData)
101 # This is the default key for authentication
102 key = [0xFF,0xFF,0xFF,0xFF,0xFF,0xFF]
103 # Authenticate
104 status = mfrc.MFRC522_Auth(mfrc.PICC_AUTHENT1A, blockAddr, key, cardID)
105 # Check if authenticated
106 if status == mfrc.MI_OK:
107 print ("Before writing , The data in block %d is: "%(blockAddr))
108 mfrc.MFRC522_Readstr(blockAddr)
109 mfrc.MFRC522_Write(blockAddr, data)
110 print ("After written , The data in block %d is: "%(blockAddr))
111 mfrc.MFRC522_Readstr(blockAddr)
112 else:
113 print ("Authentication error")
114 return 0
115
116 elif cmd[0] == "clean":
117 blockAddr = int(cmd[1])
118 if((blockAddr<0) or (blockAddr>63)):
119 print ("Invalid Address!")
120 data = [0]*16
121 # This is the default key for authentication
122 key = [0xFF,0xFF,0xFF,0xFF,0xFF,0xFF]
123 # Authenticate
124 status = mfrc.MFRC522_Auth(mfrc.PICC_AUTHENT1A, blockAddr, key, cardID)
125 # Check if authenticated
126 if status == mfrc.MI_OK:
127 print ("Before cleaning , The data in block %d is: "%(blockAddr))
128 mfrc.MFRC522_Readstr(blockAddr)
129 mfrc.MFRC522_Write(blockAddr, data)
130 print ("After cleaned , The data in block %d is: "%(blockAddr))
131 mfrc.MFRC522_Readstr(blockAddr)
132 else:
133 print ("Authentication error")
134 return 0
135 elif cmd[0] == "halt":
136 return 0
137 else :
138 print ("Usage:\r\n" "\tread <blockstart>\r\n" "\tdump\r\n" "\thalt\r\n" "\tclean <blockaddr>\r\n" "\twrite <blockaddr> <data>\r\n")
139
140def destroy():
141 print("Ending program")
142
143if __name__ == "__main__":
144 setup()
145 try:
146 loop()
147 except KeyboardInterrupt: # Ctrl+C captured, exit
148 destroy()
149
150
In the code, first create an MFRC522 class object.
1mfrc = MFRC522.MFRC522()
In the function loop, wait for the command input. If command “scan” is received, the function will begin to detect whether there is a card close to the sensing area. If a card is detected, the card will be selected and card UID will be acquired. Then enter the function scan_loop (). If command “quit” or “exit” is received, the program will exit.
1if (inCmd == "scan"):
2 print ("Scanning ... ")
3 mfrc = MFRC522.MFRC522()
4 isScan = True
5 while isScan:
6 # Scan for cards
7 (status,TagType) = mfrc.MFRC522_Request(mfrc.PICC_REQIDL)
8 # If a card is found
9 if status == mfrc.MI_OK:
10 print ("Card detected")
11 # Get the UID of the card
12 (status,uid) = mfrc.MFRC522_Anticoll()
13 # If we have the UID, continue
14 if status == mfrc.MI_OK:
15 print ("Card UID: "+ str(map(hex,uid)))
16 # Select the scanned tag
17 if mfrc.MFRC522_SelectTag(uid) == 0:
18 print ("MFRC522_SelectTag Failed!")
19 if cmdloop(uid) < 1 :
20 isScan = False
21
22elif inCmd == "quit":
23 destroy()
24 exit(0)
25else :
26 print ("\tUnknown command\n"+"\tscan:scan card and dump\n"+"\tquit:exit program\n")
The function cmdloop() will detect command read, write, clean, halt, dump and do the corresponding processing to each command. The functions of each command and the method have been introduced before.
1def cmdloop(cardID):
2 pass
3 while(True):
4 dis_ConmandLine()
5 dis_CardID(cardID)
6 inCmd = input()
7 cmd = inCmd.split(" ")
8 print (cmd)
9 if(cmd[0] == "read"):
10 blockAddr = int(cmd[1])
11 if((blockAddr<0) or (blockAddr>63)):
12 print ("Invalid Address!")
13 # This is the default key for authentication
14 key = [0xFF,0xFF,0xFF,0xFF,0xFF,0xFF]
15 # Authenticate
16 status = mfrc.MFRC522_Auth(mfrc.PICC_AUTHENT1A, blockAddr, key, cardID)
17 # Check if authenticated
18 if status == mfrc.MI_OK:
19 mfrc.MFRC522_Readstr(blockAddr)
20 else:
21 print ("Authentication error")
22 return 0
23
24 elif cmd[0] == "dump":
25 # This is the default key for authentication
26 key = [0xFF,0xFF,0xFF,0xFF,0xFF,0xFF]
27 mfrc.MFRC522_Dump_Str(key,cardID)
28
29 elif cmd[0] == "write":
30 blockAddr = int(cmd[1])
31 if((blockAddr<0) or (blockAddr>63)):
32 print ("Invalid Address!")
33 data = [0]*16
34 if(len(cmd)<2):
35 data = [0]*16
36 else:
37 data = cmd[2][0:17]
38 data = map(ord,data)
39 data = list(data)
40 lenData = len(list(data))
41 if lenData<16:
42 data+=[0]*(16-lenData)
43 # This is the default key for authentication
44 key = [0xFF,0xFF,0xFF,0xFF,0xFF,0xFF]
45 # Authenticate
46 status = mfrc.MFRC522_Auth(mfrc.PICC_AUTHENT1A, blockAddr, key, cardID)
47 # Check if authenticated
48 if status == mfrc.MI_OK:
49 print ("Before writing , The data in block %d is: "%(blockAddr))
50 mfrc.MFRC522_Readstr(blockAddr)
51 mfrc.MFRC522_Write(blockAddr, data)
52 print ("After written , The data in block %d is: "%(blockAddr))
53 mfrc.MFRC522_Readstr(blockAddr)
54 else:
55 print ("Authentication error")
56 return 0
57
58 elif cmd[0] == "clean":
59 blockAddr = int(cmd[1])
60 if((blockAddr<0) or (blockAddr>63)):
61 print ("Invalid Address!")
62 data = [0]*16
63 # This is the default key for authentication
64 key = [0xFF,0xFF,0xFF,0xFF,0xFF,0xFF]
65 # Authenticate
66 status = mfrc.MFRC522_Auth(mfrc.PICC_AUTHENT1A, blockAddr, key, cardID)
67 # Check if authenticated
68 if status == mfrc.MI_OK:
69 print ("Before cleaning , The data in block %d is: "%(blockAddr))
70 mfrc.MFRC522_Readstr(blockAddr)
71 mfrc.MFRC522_Write(blockAddr, data)
72 print ("After cleaned , The data in block %d is: "%(blockAddr))
73 mfrc.MFRC522_Readstr(blockAddr)
74 else:
75 print ("Authentication error")
76 return 0
77 elif cmd[0] == "halt":
78 return 0
79 else :
80 print ("Usage:\r\n" "\tread <blockstart>\r\n" "\tdump\r\n" "\thalt\r\n" "\tclean <blockaddr>\r\n" "\twrite <blockaddr> <data>\r\n")
The file “MFRC522.py” contains the associated operation method for the MFRC522. You can open the file to view all the definitions and functions.





