ESP32 - Part 11 - RFID With RF522
ESP32 - Part 11 - RFID With RF522
-
RFID with RF522
Version: 2021-01-10
Basic Information
Through radio frequency identification or RFID (Radio Frequency Identification), it is possible to
identify a person or object.
The system works with a card, key chain or a tag that has a chip inside it. Through the
identification of the data on the chip, it is possible to do access control, a method widely used
in records of employee points, public transportation, libraries, among others.
Our goal, therefore, is to create a program in which we can either read an RFID card or tag, or
write the data to it. We use a ESP32 and an RFID-RC522 module.
It is important to note that we can store and retrieve data on these chips or cards remotely
through devices, as these can have up to 1k of memory.
An RFID system basically consists of a transceiver with a decoder and an antenna, as well as a
transponder, the card or tag. The transceiver constantly emits a RF signal. The card or tag has
also an antenna inside. When the card approachs the trnasceiver, the emitted RF energy is
captured by the card and converted to power (voltage and current). The energized card ot tag
modulates the information stored in its memory and sends that data to the reader. The RFID
reader receives the information sent by the tag, decodes and sends the data to the server
application.
As mentioned, we have 1k of memory inside this type of chip. And, the EEPROM memory is
organized as follows: there are 16 sectors of 4 blocks. Each block contains 16 bytes.
Remember that within the source code, you only reference the block number.
The RFID-RF522 module
The module can handle several interface protocols: serial (UART), I²C and SPI. The pins used
are shown in the picture.
We will use the SPI interface.
In our setup we have the ESP32 powered by USB and hence connected via serial comport to
the Arduino IDE, two leds to indicate whether the reading or writing was successful or not, and
the RFID reader, the RC522. We have a card or tag.
Our program will work as follows: after starting, the program will wait for a card or tag to be
identified. After that, a menu will appear for the user to choose between making a reading or
recording something. Then the operation will be performed.
#define SS_PIN 21
#define RST_PIN 22
#define SIZE_BUFFER 18
#define MAX_SIZE_BLOCK 16
#define LEDgreen 12
#define LEDred 32
//used in authentication
MFRC522::MIFARE_Key key;
//authentication return status
MFRC522::StatusCode status;
In the setup we initialize the pins, serial and SPI communication, LEDs and antenna service.
void setup()
{
Serial.begin(115200);
// Init MFRC522
mfrc522.PCD_Init();
delay(2000);
// display info
Serial.println("Approach your card or tag...");
Serial.println();
}
In the loop we wait for the card to approach and select the same one.
In the menu, we offer the options of reading or writing data. We instruct this part when the
device should leave the ACTIVE state for the STOP state. We have to use such a method to
enable new readings.
void loop()
{
//waiting the card approach
if ( ! mfrc522.PICC_IsNewCardPresent())
{
return;
}
// Select a card
if ( ! mfrc522.PICC_ReadCardSerial())
{
return;
}
if(op == 0)
{
readingData();
}
else
{
if(op == 1)
{
writingData();
}
else
{
if(op < 9)
{
Serial.println("Incorrect Option!");
}
else
{
Serial.println("Time out!");
}
}
}
Serial.println();
Serial.println();
Serial.println("Remove your card or tag...");
Serial.println();
delay(3000);
// display info
Serial.println();
Serial.println();
Serial.println("Approach your card or tag...");
Serial.println();
To write data to the card / tag we have to follow some steps. From the moment we choose the
recording option, we have 30 seconds to make the data entry via serial. Enter the data to be
written with the "#" character and prepare the key. You will need to clear the buffer and write
to block 1, since in block 0 we have saved the card number, which is already in the factory. So
we do not touch block 0.
We deal with the size of data and insert a command for authentication and enable secure
communication. We also put error messages equal to the part of the reading for display in case
of unauthenticated data. We recorded the data in the block due.
//void positions that are left in the buffer; filled with whitespace
for(byte i=dataSize; i < MAX_SIZE_BLOCK; i++)
{
buffer[i] = ' ';
}
Serial.println(str);
//authenticates the block to operate
//Authenticate is a command to hability a secure communication
status = mfrc522.PCD_Authenticate(MFRC522::PICC_CMD_MF_AUTH_KEY_A,
block, &key, &(mfrc522.uid));
if (status != MFRC522::STATUS_OK)
{
Serial.print("PCD_Authenticate() failed: ");
Serial.println(mfrc522.GetStatusCodeName(status));
digitalWrite(LEDred, HIGH);
delay(1000);
digitalWrite(LEDred, LOW);
return;
}
else
{
Serial.println("PCD_Authenticate() successful: ");
Serial.println(mfrc522.GetStatusCodeName(status));
digitalWrite(LEDgreen, HIGH);
delay(1000);
digitalWrite(LEDgreen, LOW);
}
Serial.println("\nChoose an option:");
Serial.println(" 0 - Reading data");
Serial.println(" 1 - Writing data\n");
//waits while the user does not start data
while(!Serial.available())
{
now = millis();
if(now - timestart > TIME_OUT)
{
return(9);
}
};
#define SS_PIN 21
#define RST_PIN 22
#define SIZE_BUFFER 18
#define MAX_SIZE_BLOCK 16
#define LEDgreen 12
#define LEDred 32
//used in authentication
MFRC522::MIFARE_Key key;
//authentication return status
MFRC522::StatusCode status;
void setup()
{
Serial.begin(115200);
// Init MFRC522
mfrc522.PCD_Init();
delay(2000);
// display info
Serial.println("Approach your card or tag...");
Serial.println();
}
void loop()
{
//waiting the card approach
if ( ! mfrc522.PICC_IsNewCardPresent())
{
return;
}
// Select a card
if ( ! mfrc522.PICC_ReadCardSerial())
{
return;
}
// display info
Serial.println();
Serial.println();
Serial.println("Approach your card or tag...");
Serial.println();
//void positions that are left in the buffer; filled with whitespace
for(byte i=dataSize; i < MAX_SIZE_BLOCK; i++)
{
buffer[i] = ' ';
}
Serial.println(str);
//authenticates the block to operate
//Authenticate is a command to hability a secure communication
status = mfrc522.PCD_Authenticate(MFRC522::PICC_CMD_MF_AUTH_KEY_A,
block, &key, &(mfrc522.uid));
if (status != MFRC522::STATUS_OK)
{
Serial.print("PCD_Authenticate() failed: ");
Serial.println(mfrc522.GetStatusCodeName(status));
digitalWrite(LEDred, HIGH);
delay(1000);
digitalWrite(LEDred, LOW);
return;
}
else
{
Serial.println("PCD_Authenticate() successful: ");
Serial.println(mfrc522.GetStatusCodeName(status));
digitalWrite(LEDgreen, HIGH);
delay(1000);
digitalWrite(LEDgreen, LOW);
}
Serial.println("\nChoose an option:");
Serial.println(" 0 - Reading data");
Serial.println(" 1 - Writing data\n");
//waits while the user does not start data
while(!Serial.available())
{
now = millis();
if(now - timestart > TIME_OUT)
{
return(9);
}
};