ماژول RC522 RFID Reader با ایجاد یک میدان الکترومغناطیسی 13.56MHz طراحی شده است که از آن برای برقراری ارتباط با تگ های RFID (تگ های ISO 14443A) استفاده می کند.
ماژول می تواند با یک میکروکنترلر از طریق رابط سریال 4 پین سریال (SPI) با حداکثر سرعت داده 10Mbps ارتباط برقرار کند.
برای ارتباط با این ماژول میتوان از طریق پروتکل های I2C و UART نیز استفاده کند.
حد اکثر فاصله تشخیص تگ این ماژول حدود 5 سانتیمتر است.
این ماژول با ولتاژ 2.5 تا 3.3 ولت کار میکند اما خبر خوب این است که پایه های منطقی آن تحمل ولتاژ 5 ولت را دارند بنابراین ما می توانیم بدون استفاده از مبدل سطح منطقی ، آن را به راحتی به یک میکروکنترلر Arduino با ولتاژ 5 ولت متصل کنیم ولی فراموش نکنیم که پین تغذیه ماژول را باید به 3.3 ولت متصل کنید.
ماژول دارای پین اینتراپت است IRQ و با کمک این پین به جای اینکه دائماً از ماژول RFID بپرسید آیا هنوز تگی را دریافتنکرده ای، ماژول هنگام تشخیص تگ به ما اطلاع می دهد.
پین ریست RST برای خاموش و روشن کردن ماژول میباشد.
اگر این پین 5 ولت باشد ماژول فعال است و اگر صغر شود ماژول به طور کامل خاموش می شود.
ما با پین هایی که برای ارتباط SPI استفاده می شوند کار داریم زیرا ماژول RC522 به انتقال اطلاعات زیادی نیاز دارد و اتصال به پایه های سخت افزاری SPI در میکروکنترلر، بهترین عملکرد را خواهند داشت.
توجه داشته باشید که بردهای مختلف آردوینو دارای پین های SPI با ترتیب های مختلفی است که باید با ترتیب صحیح متصل شوند.
در این مورد به جدول زیر مراجعه کنید.
Ardoino Uno: 11=MOSI , 12=MISO , 13=SCK , 10=CS
Arduino Nano: 11=MOSI , 12=MISO , 13=SCK , 10=CS
Ardoino Mega: 51=MOSI , 50=MISO , 52=SCK , 53=CS
این ماژول خوشبختانه دارای یک کتابخانه آماده میباشد و کار را آسان میکند.
کامپایلر آردواینو را باز کنید و با مراجعه به منوی tools/Manage libraries رفته و MFRC522 را دانلود کنید.
سپس از منوی file/examples گزینه MFR522 را پیدا کرده و آنها را بارگزاری کنید و به سادگی با ماژول کار کنید و نتیجه را بر روی مانیتور سریال ببینید.
#include
#include
#define SS_PIN 10 //slave select pin
#define RST_PIN 5 //reset pin
MFRC522 mfrc522(SS_PIN, RST_PIN); // instatiate a MFRC522 reader object.
MFRC522::MIFARE_Key key; //create a MIFARE_Key struct named 'key', which will hold the card information
//this is the block number we will write into and then read.
int block=2;
byte blockcontent[16] = {"Last-Minute-Engg"}; //an array with 16 bytes to be written into one of the 64 card blocks is defined
//byte blockcontent[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; //all zeros. This can be used to delete a block.
//This array is used for reading out a block.
byte readbackblock[18];
void setup()
{
Serial.begin(9600); // Initialize serial communications with the PC
SPI.begin(); // Init SPI bus
mfrc522.PCD_Init(); // Init MFRC522 card (in case you wonder what PCD means: proximity coupling device)
Serial.println("Scan a MIFARE Classic card");
// Prepare the security key for the read and write functions.
for (byte i = 0; i < 6; i++) {
key.keyByte[i] = 0xFF; //keyByte is defined in the "MIFARE_Key" 'struct' definition in the .h file of the library
}
}
void loop()
{
// Look for new cards
if ( ! mfrc522.PICC_IsNewCardPresent()) {
return;
}
// Select one of the cards
if ( ! mfrc522.PICC_ReadCardSerial())
{
return;
}
Serial.println("card selected");
//the blockcontent array is written into the card block
writeBlock(block, blockcontent);
//read the block back
readBlock(block, readbackblock);
//uncomment below line if you want to see the entire 1k memory with the block written into it.
//mfrc522.PICC_DumpToSerial(&(mfrc522.uid));
//print the block contents
Serial.print("read block: ");
for (int j=0 ; j<16 ; j++)
{
Serial.write (readbackblock[j]);
}
Serial.println("");
}
//Write specific block
int writeBlock(int blockNumber, byte arrayAddress[])
{
//this makes sure that we only write into data blocks. Every 4th block is a trailer block for the access/security info.
int largestModulo4Number=blockNumber/4*4;
int trailerBlock=largestModulo4Number+3;//determine trailer block for the sector
if (blockNumber > 2 && (blockNumber+1)%4 == 0){Serial.print(blockNumber);Serial.println(" is a trailer block:");return 2;}
Serial.print(blockNumber);
Serial.println(" is a data block:");
//authentication of the desired block for access
byte status = mfrc522.PCD_Authenticate(MFRC522::PICC_CMD_MF_AUTH_KEY_A, trailerBlock, &key, &(mfrc522.uid));
if (status != MFRC522::STATUS_OK) {
Serial.print("PCD_Authenticate() failed: ");
Serial.println(mfrc522.GetStatusCodeName(status));
return 3;//return "3" as error message
}
//writing the block
status = mfrc522.MIFARE_Write(blockNumber, arrayAddress, 16);
//status = mfrc522.MIFARE_Write(9, value1Block, 16);
if (status != MFRC522::STATUS_OK) {
Serial.print("MIFARE_Write() failed: ");
Serial.println(mfrc522.GetStatusCodeName(status));
return 4;//return "4" as error message
}
Serial.println("block was written");
}
//Read specific block
int readBlock(int blockNumber, byte arrayAddress[])
{
int largestModulo4Number=blockNumber/4*4;
int trailerBlock=largestModulo4Number+3;//determine trailer block for the sector
//authentication of the desired block for access
byte status = mfrc522.PCD_Authenticate(MFRC522::PICC_CMD_MF_AUTH_KEY_A, trailerBlock, &key, &(mfrc522.uid));
if (status != MFRC522::STATUS_OK) {
Serial.print("PCD_Authenticate() failed (read): ");
Serial.println(mfrc522.GetStatusCodeName(status));
return 3;//return "3" as error message
}
//reading a block
byte buffersize = 18;//we need to define a variable with the read buffer size, since the MIFARE_Read method below needs a pointer to the variable that contains the size...
status = mfrc522.MIFARE_Read(blockNumber, arrayAddress, &buffersize);//&buffersize is a pointer to the buffersize variable; MIFARE_Read requires a pointer instead of just a number
if (status != MFRC522::STATUS_OK) {
Serial.print("MIFARE_read() failed: ");
Serial.println(mfrc522.GetStatusCodeName(status));
return 4;//return "4" as error message
}
Serial.println("block was read");
}