سلام به همگی . تو این پست میخوایم اول به شما یاد بدیم که RFID چی هست و بعدا بریم سراغ راه اندازی ماژول RFID با آردوینو .
RFID چیست؟
کلمه RFID مخفف Radio Frequency Identification یعنی شناسایی بوسیله امواج رادیویی هست . که درواقع یک سامانهٔ شناسایی بیسیم قادر به تبادل دادهها بهوسیلهٔ برقراری اطلاعات بین یک Reader (بازخوان یا تگخوان) و یک Tag (شناسه یا تگ) که به یک کالا، شی، کارت و… متصل شدهاست میباشد.به عبارت دیگه سامانههای RFID از سیگنالهای الکترونیکی و الکترومغناطیسی برای خواندن و نوشتن دادهها بدون تماس استفاده میکنن.
تگ RFID چیست و چگونه کار میکند؟
تگ های RFID متشکل از یک چیپ سیلیکونی ، یک سیم پیچ مسی و یک خازن هست که میتونه داخل یک کارت ، کیف پول، جاسوئیچی و حتی دست شما باشه! تگ های RFID چند سالی هست که داخل دست کاشت میشن و میشه اطلاعاتی رو از جمله کارت های پرداخت و اطلاعات بیماری فرد رو در اونها ذخیره کرد . نمونش رومیتونید داخل عکس پایین ببینید:
این چیپ ا داخل مچ دست قرار میگیرن و میتونن اطلاعات مثلا بیمار رو ذخیره کنن . در نتیجه اگر مثلا فرد تصادف کنه یا با سطح هوشیاری پایین مراجعه کنه، پزشک با اسکن این تگ داخل دست فرد میتونه سابقه بیماری های زمینه ای و داروهاییکه فرد به اونا حساسه رو ببینه. یا فرد در مترو و اتوبوس با جلو بردن دستش جلوی RFID READER میتونه پول سفر رو پرداخت کنه . در کل خیلی کاربردی هست . جنس بدنه این تگ ها هم بوروسیلیکات هست تا توی دست باعث عفونت نشه . ولی خب یکم اذیت میکنه شما همش یه چیپ داخل دستت باشه . بهرحال با این تگ آشنا شدید .
ماژول RC522
این ماژول رو که میخرید ممکنه به شکل زیر براتون ارسال بشه:
یک ماژول و دو عدد تگ RFID و دو عدد پین هدر برای ما ارسال شد که پین هدر رو باید خودتون لحیم کنید روش.
ماژول های زیادی توی بازار برای خواندن و نوشتن کارت RFID توی بازار وجود دارن و ما کاربردی ترینشون رو انتخاب کردیم. ولتاژ این ماژول 3.3 ولت هست و از سه روش SPI و I2C و UART قابل راه اندازیه . این ماژولی که میبینید منحصرا برای روش SPIساخته شده و بطور فیزیکی نمیشه از روش دیگه یعنی I2C و UART راه اندازیش کرد. باید تغییری در سیم کشی برد انجام بدیم ولی هنوز کتابخونه درست درمونی واسه این کار پیدا نکردیم و اگر تونستیم حلش کنیم این پست به روزرسانی میشه. طبق تست ما این ماژول تا 2 سانتی متر تگ رو میخونه . میریم سراغ روش SPI:
اتصال پین ها:
نام پین روی ماژول | نام پین روی آردوینو |
SDA | DIGITAL 10 |
SCK | DIGITAL 13 |
MOSI | DIGITAL 11 |
MISO | DIGITAL 12 |
RQ | متصل نیست |
GND | GND |
RST | DIGITAL 9 |
3.3 | 3.3V |

حالا که سیم کشی رو انجام دادید میریم سراغ کد. قبلش باید کتابخونه MFRC522 رو نصب کنید که از منوی sketch>>include library>>manage libraries قابل نصب هست.حالا کد رو آپلود کنید و سریال مانیتور رو باز کنید و باودریت رو روی 9600 تنظیم کنید.
#include <SPI.h> #include <MFRC522.h> #define SS_PIN 10 #define RST_PIN 9 MFRC522 mfrc522(SS_PIN, RST_PIN); // Create MFRC522 instance. void setup() { Serial.begin(9600); // Initiate a serial communication SPI.begin(); // Initiate SPI bus mfrc522.PCD_Init(); // Initiate MFRC522 Serial.println("Approximate your card to the reader..."); Serial.println(); } void loop() { // Look for new cards if ( ! mfrc522.PICC_IsNewCardPresent()) { return; } // Select one of the cards if ( ! mfrc522.PICC_ReadCardSerial()) { return; } //Show UID on serial monitor Serial.print("UID tag :"); String content= ""; byte letter; for (byte i = 0; i < mfrc522.uid.size; i++) { Serial.print(mfrc522.uid.uidByte[i] < 0x10 ? " 0" : " "); Serial.print(mfrc522.uid.uidByte[i], HEX); content.concat(String(mfrc522.uid.uidByte[i] < 0x10 ? " 0" : " ")); content.concat(String(mfrc522.uid.uidByte[i], HEX)); } Serial.println(); Serial.print("Message : "); content.toUpperCase(); if (content.substring(1) == "D0 48 18 32") //change here the UID of the card/cards that you want to give access { Serial.println("Authorized access"); Serial.println(); delay(3000); } else { Serial.println(" Access denied"); delay(3000); } }
اگر همه چی درست پیش رفته باشه با نزدیک کردن تگ به ماژول همچین چیزی میبینید:

حالا بریم سراغ قسمت های مهم کد که نیازه بدونید:
اول کتابخونه های موردنیاز رو معرفی میکنیم:
#include <SPI.h> #include <MFRC522.h>
معرفی پایه های SDAو RST:
#define SS_PIN 10 #define RST_PIN 9 MFRC522 mfrc522(SS_PIN, RST_PIN); // Create MFRC522 instance.
ایجاد ارتباط سریال و تنظیم باودریت:
Serial.begin(9600);
راه اندازی ارتباط SPI:
SPI.begin();
اینجا هم میتونید UID کد رو تغییر بدید و UIDکارت خودتون رو وارد کنید . چندین تا UIDهم میتونید تعریف کنید براش:
if (content.substring(1) == "D0 48 18 32")
خب این کد فقط کارت رو میخونه و UID کارت رو به شما میگه . حالا اگر نیاز باشه اطلاعات داخل کارت روببینیم چی؟ اینجا کد زیر به کمک ما میاد:
این کد از منوی File>>examples>>MFRC522>>Dumpinfo در دسترسه .
/* * -------------------------------------------------------------------------------------------------------------------- * Example sketch/program showing how to read data from a PICC to serial. * -------------------------------------------------------------------------------------------------------------------- * This is a MFRC522 library example; for further details and other examples see: https://github.com/miguelbalboa/rfid * * Example sketch/program showing how to read data from a PICC (that is: a RFID Tag or Card) using a MFRC522 based RFID * Reader on the Arduino SPI interface. * * When the Arduino and the MFRC522 module are connected (see the pin layout below), load this sketch into Arduino IDE * then verify/compile and upload it. To see the output: use Tools, Serial Monitor of the IDE (hit Ctrl+Shft+M). When * you present a PICC (that is: a RFID Tag or Card) at reading distance of the MFRC522 Reader/PCD, the serial output * will show the ID/UID, type and any data blocks it can read. Note: you may see "Timeout in communication" messages * when removing the PICC from reading distance too early. * * If your reader supports it, this sketch/program will read all the PICCs presented (that is: multiple tag reading). * So if you stack two or more PICCs on top of each other and present them to the reader, it will first output all * details of the first and then the next PICC. Note that this may take some time as all data blocks are dumped, so * keep the PICCs at reading distance until complete. * * @license Released into the public domain. * * Typical pin layout used: * ----------------------------------------------------------------------------------------- * MFRC522 Arduino Arduino Arduino Arduino Arduino * Reader/PCD Uno/101 Mega Nano v3 Leonardo/Micro Pro Micro * Signal Pin Pin Pin Pin Pin Pin * ----------------------------------------------------------------------------------------- * RST/Reset RST 9 5 D9 RESET/ICSP-5 RST * SPI SS SDA(SS) 10 53 D10 10 10 * SPI MOSI MOSI 11 / ICSP-4 51 D11 ICSP-4 16 * SPI MISO MISO 12 / ICSP-1 50 D12 ICSP-1 14 * SPI SCK SCK 13 / ICSP-3 52 D13 ICSP-3 15 */ #include <SPI.h> #include <MFRC522.h> #define RST_PIN 9 // Configurable, see typical pin layout above #define SS_PIN 10 // Configurable, see typical pin layout above MFRC522 mfrc522(SS_PIN, RST_PIN); // Create MFRC522 instance void setup() { Serial.begin(9600); // Initialize serial communications with the PC while (!Serial); // Do nothing if no serial port is opened (added for Arduinos based on ATMEGA32U4) SPI.begin(); // Init SPI bus mfrc522.PCD_Init(); // Init MFRC522 delay(4); // Optional delay. Some board do need more time after init to be ready, see Readme mfrc522.PCD_DumpVersionToSerial(); // Show details of PCD - MFRC522 Card Reader details Serial.println(F("Scan PICC to see UID, SAK, type, and data blocks...")); } void loop() { // Reset the loop if no new card present on the sensor/reader. This saves the entire process when idle. if ( ! mfrc522.PICC_IsNewCardPresent()) { return; } // Select one of the cards if ( ! mfrc522.PICC_ReadCardSerial()) { return; } // Dump debug info about the card; PICC_HaltA() is automatically called mfrc522.PICC_DumpToSerial(&(mfrc522.uid)); }
کد رو که آپلود کردید سریال مانیتور رو باز کنید و باودریت 9600 رو انتخاب کنید و اگر همه چی درست باشه میتونید تصویری مشابه تصویر زیر رو بعد از نزدیک کردن کارت به ماژول ببینید:
حتما یادتون باشه کارت رو باید تا زمانیکه عدد سمت چپ به صفر میرسه نزدیک ماژول نگه دارید وگرنه تمام اطلاعات داخل کارت خونده نمیشه. حالا این جدول ها به چه معنا هستن؟
تگ های RFID در واقع 1KB حافظه دارن.این حافظه به 16 بخش تقسیم شده ( بخشهای 0 تا 15) و هر بخش دوباره خودش به 4 بلوک تقسیم شده ( بلوک 0 تا 3) و هرکدوم از این بلوک ها 16 بایت دیتا رو میتونن تو خودشون ذخیره کنن(از 0 تا 16 ).و اگر 16 بخش رو در 4 بلوک و 16 واحد حافظه ضرب کنیم عدد 1024 بایت که معادل 1 کیلوبایت هست بدست میاد .توی تصویر زیر میتونید بخشهای حافظه رو که رنگی مشخص شدن ببینید:


بلوک سوم هر بخش هم SECTOR TRAILER نام داره و داخلش اطلاعات دسترسی یا Access Bits قرار داره و قابلیت دسترسی نوشتن روی هر بلوک رو ایجاد میکنه(قسمت سبز رنگ عکس پایین) . یعنی فقط سه بلوک از هر بخش قابل ذخیره سازی دیتا هست (بلوک های 0و1و2). بلوک 0 بخش 0 هم اطلاعات شرکت سازنده و ایدی کارت رو ذخیره میکنه (قسمت قرمز رنگ توی عکس زیر):

بوسیله کد زیر هم میتونید نوشته های داخل تگ رو تغییر بدید . البته دقت کنید که این کار خیلی ریسک داره و ممکنه تگ کلا بسته بشه و دیگه نتونید بخونیدش.یادتون نره تا زمانیکه عملیات خوندن و یا نوشتن انجام میشه کارت رو نزدیک ماژول نگه دارید.
#include <SPI.h> //include the SPI bus library #include <MFRC522.h> //include the RFID reader library #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] = {"clooner.ir"}; //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"); }
توی کد زیر بلوکی که میخواید اطلاعات در اون وارد بشه رو انتخاب میکنید.یادتون باشه به هیچ وجه داخل بلوک 3 چیزی ننویسید چون کلا این بخش رو غیر قابل استفاده میکنه .
//this is the block number we will write into and then read. int block=2;
اینجا یه آرایه 16 بیتی میسازیم تا اطلاعاتی که میخوایم رو تگ بنویسه. اگر داخل آرایه صفر قرار بدیم اون بلوک رو پاک میکنه:
byte blockcontent[16] = {"clooner.ir"}; //byte blockcontent[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
بعد یک آرایه 18 بیتی برای نوشتن و خواندن دیتا تعریف میکنیم . چرا 18 مگه نباید 16 باشه؟ خب بخاطر این 18 استفاده میکنیم چون توی روش MIFARE_Read در کتابخانه MFRC522 به یک بافر حداقل 18 بیتی برای ذخیره 16 بایت یک بلوک نیاز داریم:
byte readbackblock[18];
اگر کارتتون نو هست باید رمز عبور براش تعریف کنید که 0xFF تعیین شده. حتما خودتون رمز بزارید براش مخصوصا اگر پروژه مهمی دارید.اگر هم کارتی که قبلا پروگرام شده رو در اختیار دارید باید رمزش رو بدونید و داخل key قرارش بدید.
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 }
به اینصورت شما تونستید دیتایی داخل تگ بنویسید.
امیدوارم از خوندن این پست لذت برده باشید . اگر سوالی داشتید از قسمت نظرات بپرسید .
موفق باشید.