مقدمه
آنچه در این آموزش یاد میگیرید
- RFID چیست و چگونه کار میکند
- آشنایی با ماژول RFID RC522
- خواندن اطلاعات روی تگها
- نوشتن اطلاعات روی تگها
RFID چیست؟
سامانه شناسایی با امواج رادیویی (Radio Frequency Identification) یا به اختصار RFID یک سامانه انتقال داده بی سیم بین یک تگ و یک دستگاه خوانندهی آن است. حتما با کاربرد این سامانه در فروشگاهها مواجه شدهاید؛ در این موارد معمولا یک تگ RFID نازک که شامل یک مدار الکتریکی است به صورت برچسب به هر کالا متصل است. زمانی که این تگ در معرض میدان مغناطیسی ایجاد شده توسط دستگاه بارکدخوان قرار میگیرد، فعال میشود و اقدام به ارسال داده از طریق پالسهای رادیویی میکند. سپس با توجه به امواجی که از خود ساطع میکند شناسایی شده و از سیستم خارج میشود. این ماژول ها با فرکانس های مختلفی کار می کنند و فرکانس های متدوال برای تکنولوژی RFID سه فرکانس 125kHz، 13.56MHz و یا UHF می باشد.
ماژولهای RFID مانند RC522 به منظور خواندن و نوشتن کارتها یا تگهای RFID مورد استفاده قرار میگیرند. این ماژول در محدوده فرکانسی 13.56Mhz کار کرده و علاوه بر خواندن اطلاعات میتواند اطلاعات جدیدی را بر روی حافظهی کارت ذخیره نماید. برخی از ویژگیهای این ماژول عبات است از:
- ارتباط با میکروکنترلر از طریق پروتکل SPI و I2C و سریال
- سرعت انتقال اطلاعات تا 10Mbit/s
- ولتاژ کاری 3.3 ولت
- ابعاد بسیار کوچک 4 در 6 سانتی متر
دیتاشیت تراشه RC522 را می توانید از اینجا دانلود کنید.
RC522 MH RFID Module Datasheet
معرفی پایه های ماژول RC522 MH RFID
ماژول RC522 MH دارای 8 پایه است. کاربرد این پایه ها به شرح زیر است:
- VCC: تغذیه ماژول – 3.3V
- GND: زمین
- RST: ریست
- IRQ: وقفه
- MISO/TX/SCL: پایه های ارتباطی پروتکل SPI، سریال و I2C
- MOSI: پایه ارتباطی پروتکل SPI
- SCK: پایه ارتباطی پروتکل SPI
- SS/RX/SDA: پایه های ارتباطی پروتکل SPI، سریال و I2C
نحوه استفاده از ماژول RC522 با آردوینو
قطعات مورد نیاز
نرم افزارهای مورد نیاز
خواندن اطلاعات تگ های RFID
سیم بندی
کد
/*
* RFID , read tags
* by Hanie kiani
* https://electropeak.com/learn/
*/
#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
SPI.begin(); // Init SPI bus
mfrc522.PCD_Init(); // Init MFRC522 card
Serial.println(F("Read personal data on a MIFARE PICC:")); //shows in serial that it is ready to read
}
//*****************************************************************************************//
void loop() {
// Prepare key - all keys are set to FFFFFFFFFFFFh at chip delivery from the factory.
MFRC522::MIFARE_Key key;
for (byte i = 0; i < 6; i++) key.keyByte[i] = 0xFF;
//some variables we need
byte block;
byte len;
MFRC522::StatusCode status;
//-------------------------------------------
// 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;
}
Serial.println(F("**Card Detected:**"));
//-------------------------------------------
mfrc522.PICC_DumpDetailsToSerial(&(mfrc522.uid)); //dump some details about the card
//mfrc522.PICC_DumpToSerial(&(mfrc522.uid)); //uncomment this to see all blocks in hex
//-------------------------------------------
Serial.print(F("Name: "));
byte buffer1[18];
block = 4;
len = 18;
//------------------------------------------- GET FIRST NAME
status = mfrc522.PCD_Authenticate(MFRC522::PICC_CMD_MF_AUTH_KEY_A, 4, &key, &(mfrc522.uid)); //line 834 of MFRC522.cpp file
if (status != MFRC522::STATUS_OK) {
Serial.print(F("Authentication failed: "));
Serial.println(mfrc522.GetStatusCodeName(status));
return;
}
status = mfrc522.MIFARE_Read(block, buffer1, &len);
if (status != MFRC522::STATUS_OK) {
Serial.print(F("Reading failed: "));
Serial.println(mfrc522.GetStatusCodeName(status));
return;
}
//PRINT FIRST NAME
for (uint8_t i = 0; i < 16; i++)
{
if (buffer1[i] != 32)
{
Serial.write(buffer1[i]);
}
}
Serial.print(" ");
//---------------------------------------- GET LAST NAME
byte buffer2[18];
block = 1;
status = mfrc522.PCD_Authenticate(MFRC522::PICC_CMD_MF_AUTH_KEY_A, 1, &key, &(mfrc522.uid)); //line 834
if (status != MFRC522::STATUS_OK) {
Serial.print(F("Authentication failed: "));
Serial.println(mfrc522.GetStatusCodeName(status));
return;
}
status = mfrc522.MIFARE_Read(block, buffer2, &len);
if (status != MFRC522::STATUS_OK) {
Serial.print(F("Reading failed: "));
Serial.println(mfrc522.GetStatusCodeName(status));
return;
}
//PRINT LAST NAME
for (uint8_t i = 0; i < 16; i++) {
Serial.write(buffer2[i] );
}
//----------------------------------------
Serial.println(F("\n**End Reading**\n"));
delay(1000); //change value if you want to read cards faster
mfrc522.PICC_HaltA();
mfrc522.PCD_StopCrypto1();
}
شناسایی تگ های RFID
میتوان با اضافه کردن قطعه کد زیر، بارکد مشخصی را تعیین کرد و آن را به عنوان داده معیار به آردینو معرفی کرد (در خط اول جایگزین identified tag شود). با اتصال دو LED سبز و قرمز به پینهای 7 و 8 مدار ، در صورتی که تگ با داده مورد نظر مقایل ماژول قرار گیرد، LED سبز روشن شده که نشان میدهد بارکد تگ مورد نظر مورد تایید است. و اگر LED قرمز روشن شود به این معناست که بارکد شناخته شده نیست.
با گسترش دادن این قطعه کد ساده میتوان از آن در پروژههای پیچیده تر مانند قفل الکترونیک (قفل در RFID) استفاده کرد.
سیم بندی
کد
if(data == (" ...identified tag... "))
{
digitalWrite(8, HIGH);
delay(3000);
digitalWrite(8, LOW);
}
else
{
digitalWrite(7, HIGH);
delay(3000);
digitalWrite(7, LOW);
}
نوشتن اطلاعات روی تگ های RFID
MFRC522 Library
کد
این کد پس از شناسایی کارت و نمایش UDI کارت، از شما اطلاعاتی میخواهد که شما میخواهید روی کارت ذخیره کنید. این اطلاعات میتواند شامل حروف، اعداد یا رشتههای دیگر باشد.
سپس این اطلاعات در بلوک 1 کارت ذخیره میشود. با تغییر متغیر بلوک در کد، میتوانید هر بار یک بلوک متفاوت بنویسید.
ابتدا کد زیر را بر روی آردوینو خود آپلود کنید.
/*
* RFID , read tags
* by Hanie kiani
* https://electropeak.com/learn/
*/
#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
SPI.begin(); // Init SPI bus
mfrc522.PCD_Init(); // Init MFRC522 card
Serial.println(F("Write personal data on a MIFARE PICC "));
}
void loop() {
// Prepare key - all keys are set to FFFFFFFFFFFFh at chip delivery from the factory.
MFRC522::MIFARE_Key key;
for (byte i = 0; i < 6; i++) key.keyByte[i] = 0xFF;
// 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;
}
Serial.print(F("Card UID:")); //Dump UID
for (byte i = 0; i < mfrc522.uid.size; i++) {
Serial.print(mfrc522.uid.uidByte[i] < 0x10 ? " 0" : " ");
Serial.print(mfrc522.uid.uidByte[i], HEX);
}
Serial.print(F(" PICC type: ")); // Dump PICC type
MFRC522::PICC_Type piccType = mfrc522.PICC_GetType(mfrc522.uid.sak);
Serial.println(mfrc522.PICC_GetTypeName(piccType));
byte buffer[34];
byte block;
MFRC522::StatusCode status;
byte len;
Serial.setTimeout(20000L) ; // wait until 20 seconds for input from serial
// Ask personal data: Family name
Serial.println(F("Type Family name, ending with #"));
len = Serial.readBytesUntil('#', (char *) buffer, 30) ; // read family name from serial
for (byte i = len; i < 30; i++) buffer[i] = ' '; // pad with spaces
block = 1;
//Serial.println(F("Authenticating using key A..."));
status = mfrc522.PCD_Authenticate(MFRC522::PICC_CMD_MF_AUTH_KEY_A, block, &key, &(mfrc522.uid));
if (status != MFRC522::STATUS_OK) {
Serial.print(F("PCD_Authenticate() failed: "));
Serial.println(mfrc522.GetStatusCodeName(status));
return;
}
else Serial.println(F("PCD_Authenticate() success: "));
// Write block
status = mfrc522.MIFARE_Write(block, buffer, 16);
if (status != MFRC522::STATUS_OK) {
Serial.print(F("MIFARE_Write() failed: "));
Serial.println(mfrc522.GetStatusCodeName(status));
return;
}
else Serial.println(F("MIFARE_Write() success: "));
block = 2;
//Serial.println(F("Authenticating using key A..."));
status = mfrc522.PCD_Authenticate(MFRC522::PICC_CMD_MF_AUTH_KEY_A, block, &key, &(mfrc522.uid));
if (status != MFRC522::STATUS_OK) {
Serial.print(F("PCD_Authenticate() failed: "));
Serial.println(mfrc522.GetStatusCodeName(status));
return;
}
// Write block
status = mfrc522.MIFARE_Write(block, &buffer[16], 16);
if (status != MFRC522::STATUS_OK) {
Serial.print(F("MIFARE_Write() failed: "));
Serial.println(mfrc522.GetStatusCodeName(status));
return;
}
else Serial.println(F("MIFARE_Write() success: "));
// Ask personal data: First name
Serial.println(F("Type First name, ending with #"));
len = Serial.readBytesUntil('#', (char *) buffer, 20) ; // read first name from serial
for (byte i = len; i < 20; i++) buffer[i] = ' '; // pad with spaces
block = 4;
//Serial.println(F("Authenticating using key A..."));
status = mfrc522.MIFARE_Write(block, &buffer[16], 16);
if (status != MFRC522::STATUS_OK) {
Serial.print(F("PCD_Authenticate() failed: "));
Serial.println(mfrc522.GetStatusCodeName(status));
return;
}
// Write block
status = mfrc522.MIFARE_Write(block, buffer, 16);
if (status != MFRC522::STATUS_OK) {
Serial.print(F("MIFARE_Write() failed: "));
Serial.println(mfrc522.GetStatusCodeName(status));
return;
}
else Serial.println(F("MIFARE_Write() success: "));
block = 5;
//Serial.println(F("Authenticating using key A..."));
status = mfrc522.PCD_Authenticate(MFRC522::PICC_CMD_MF_AUTH_KEY_A, block, &key, &(mfrc522.uid));
if (status != MFRC522::STATUS_OK) {
Serial.print(F("PCD_Authenticate() failed: "));
Serial.println(mfrc522.GetStatusCodeName(status));
return;
}
// Write block
status = mfrc522.MIFARE_Write(block, &buffer[16], 16);
if (status != MFRC522::STATUS_OK) {
Serial.print(F("MIFARE_Write() failed: "));
Serial.println(mfrc522.GetStatusCodeName(status));
return;
}
else Serial.println(F("MIFARE_Write() success: "));
Serial.println(" ");
mfrc522.PICC_HaltA(); // Halt PICC
mfrc522.PCD_StopCrypto1(); // Stop encryption on PCD
}
Comments (10)
سلام وقت بخیر.. این تیکه کد رو ( writeBlock(block, blockcontent);) ارور میده چرا؟؟
‘writeBlock’ was not declared in this scope
سلام. وقت شما هم بخیر
ممنون بابت توجهتون. کد اصلاح شد.
سلام من از برد اردوینو MEGA2560 استفاده میکنم میشه پین هارو برای اتصال به این برد بگین؟
سلام.
برای این کار کافیه پایههای SS و SCK و MOSI و MISO رو که در آردوینو Uno به پایههای 10 و 13 و 11 و 12 متصل شدند رو به ترتیب به پایههای 53 و 52 و 51 و 50 آردوینو Mega متصل کنید. بقیه اتصالات هم مشابه آردوینو Uno هست.
if(data == (” …identified tag… “)}
digitalWrite(8, HIGH);
delay(3000);
digitalWrite(8, LOW);
{else}
digitalWrite(7, HIGH);
delay(3000);
digitalWrite(7, LOW);
}
سلام ببخشید این کد رو کجای برنامه باید بزارم هر جا مینویسم ارور میده
digitalWrite(8, HIGH);
delay(3000);
digitalWrite(8, LOW);
{else}
digitalWrite(7, HIGH);
delay(3000);
digitalWrite(7, LOW);
}
سلام
کلا ساختار شرط if مشکل داره
چرا جهت برقراری شرط به این شکل نوشتید؟اصلا به این صورت کلا اشتباهه
ضمنا در آکولاد ها هم دقت نکرده اید!!
بفرمایید دقیقا چی میخوایید بنویسید؟
سلام و وقت بخیر خدمت شما. ببخشید در مورد کد مربوط به قسمت “شناسایی تگ های RFID” این آموزش که این:
if(data == (” …identified tag… “)}
digitalWrite(8, HIGH);
delay(3000);
digitalWrite(8, LOW);
{else}
digitalWrite(7, HIGH);
delay(3000);
digitalWrite(7, LOW);
}
هست:
1_ ساختار if کلا مشکل داره که خودم درستش کردم.
2_ من روی تگ اطلاعات رو با روش خودتون نوشتم ولی میخوام وقتی ماژول اطلاعات مربوط به این تگ رو خوند پایه 8 رو 3 ثانیه HIGH کنه، اما وقتی کدی که بارگزاری کردید رو روی برد آپلود کردم و قسمت های مربوط به ساختار if رو درست کردم به شناخته نشدن کلمه data ارور داد. البته بنده خدا حق داره چون data رو شما به چیزی انتصاب ندادید. میخواستم لطف کنید بگید که data رو به چی منتصب کنم تا وقتی تگی با اطلاعات وارد شده خونده شد پین 8 3 ثانیه HIGH شه. خیلی خیلی ممنون میشم سریع پاسخ بدید.
سلام مجدد بله حق با شماست
بنده کد رد اصلاح کردم
حالا این چند خط کد رو شما میتونید در لوپ برنامه هر جا بشه قرار بدید، (داخل شرط های های دیگر قرار ندهید)
data رو هم خودتون میتونید در ابتدای برنامه تعریف کنید، برای خواندن id کارت هم شما از همین قطعه کد میتونید استفاده کنید و به جای data از متغییر buffer1 استفاده کنید و شزط بررسی رو هم id کارت بزارید
در واقع این قطعه کدی که قرار داده شده یه جور مثال کلی هست که شما خودتون میتونید متغییر ها رو همنطور که عرض کردم جایگزین کنید
سلام خسته نباشید.چه طور باید برای پروژه مستر کارت تعیین کنیم؟
با سلام
برای این کار شما باید با برنامه نویسی این کار را انجام بدهید.
به عنوان مثال شما میخواهید کارت مستر برای اضافه کردن کارت جدید باشد. پس
نوسط ریدر ID کارت را بخوانید در صورتی که این ID همان ID مستر شما بود منتظر کارت بعدی بشود و کارت دوم را بر روی ریدر بزنید ID دوم را بر روی حافظه ذخیره کند و کار های دیگری که میخواهید برای شما انجام بدهد.
می توانید یک کارت دیگر به عنوان مستر حذف کن نیز درست کنید.