3 گام برای استفاده از ماژول RFID RC522 با آردوینو

فهرست مطالب

مقدمه

در این آموزش با تکنولوژی RFID آشنا می‌شویم و چگونگی کار با ماژولRFID RC522  را می‌آموزیم. در ابتدا به معرفی  RFID و نحوه عملکرد آن می‌پردازیم. سپس نحوه راه اندازی و کار با ماژول آن را خواهیم دید. در نهایت نیز چند مثال کاربری را ارائه خواهیم داد.

آنچه در این آموزش یاد میگیرید

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

ماژول RC522 MH دارای 8 پایه است. کاربرد این پایه ها به شرح زیر است:

  •  VCC: تغذیه ماژول – 3.3V
  •  GND: زمین
  •  RST: ریست
  •  IRQ: وقفه
  •  MISO/TX/SCL: پایه های ارتباطی پروتکل SPI، سریال و I2C
  •  MOSI: پایه ارتباطی پروتکل SPI
  •  SCK: پایه ارتباطی پروتکل SPI
  •  SS/RX/SDA: پایه های ارتباطی پروتکل SPI، سریال و I2C

نحوه استفاده از ماژول RC522 با آردوینو

قطعات مورد نیاز

برد آردوینو Uno × 1
ماژول RFID RC522 × 1
سیم جامپر نری به نری × 1

نرم افزارهای مورد نیاز

Arduino IDE

خواندن اطلاعات تگ های RFID

در این مثال می‌خواهیم با استفاده از آردوینو اطلاعات روی تگ RFID را بخوانیم. برای اینکار از ارتباط SPI استفاده می‌کنیم. اطلاعات خوانده شده از تگ بافر شده و در پنجره ی Serial Monitor نمایش داده می‌شود. نحوه اتصال ماژول به آردوینو در شکل زیر آمده و کد‌های مربوطه را در ادامه می‌بینیم.

سیم بندی

کد

/* 
 *  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

برای نوشتن اطلاعات روی کارت ، ابتدا باید از قابلیت نوشتن کارت خود اطمینان حاصل کنید. کارت UHF نوعی کارت RFID است که با فرکانس بالا کار می کند و توانایی ذخیره اطلاعات را دارد ، بنابراین شما برای نوشتن اطلاعات مورد نظر خود روی کارت به این کارت های RFID احتیاج دارید. از مدار مشابه قبلی استفاده کنید و کد زیر را روی صفحه خود بارگذاری کنید. بارگیری کتابخانه MFRC522: 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

}
سپس سریال مانیتور نرم افزار آردوینو را باز کنید. متن مورد نظر خود را در پنجره سریال تایپ کرده و در انتهای متن کاراکتر # را وارد کنید و سپس کلید Send را بزنید.
اگر عملیات نوشتن روی کارت با موفقیت انجام شود، پیام زیر به شما نمایش داده خواهد شد.

از این مطلب خوشتان آمد؟

آخرین مطالت و آموزش ها را در ایمیلتان دریافت کنید:

مطالب بیشتر

Comments (10)

  • hafez.fld Reply

    سلام وقت بخیر.. این تیکه کد رو ( writeBlock(block, blockcontent);) ارور میده چرا؟؟
    ‘writeBlock’ was not declared in this scope

    جولای 10, 2021 at 11:49 ق.ظ
    • مهران ملکی Reply

      سلام. وقت شما هم بخیر
      ممنون بابت توجهتون. کد اصلاح شد.

      نوامبر 22, 2021 at 11:27 ق.ظ
  • Prog88 Reply

    سلام من از برد اردوینو MEGA2560 استفاده میکنم میشه پین هارو برای اتصال به این برد بگین؟

    جولای 9, 2022 at 8:31 ب.ظ
    • مهران ملکی Reply

      سلام.
      برای این کار کافیه پایه‌های SS و SCK و MOSI و MISO رو که در آردوینو Uno به پایه‌های 10 و 13 و 11 و 12 متصل شدند رو به ترتیب به پایه‌های 53 و 52 و 51 و 50 آردوینو Mega متصل کنید. بقیه اتصالات هم مشابه آردوینو Uno هست.

      جولای 10, 2022 at 3:17 ب.ظ
  • چواد Reply

    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);
    }

    فوریه 13, 2023 at 11:55 ق.ظ
    • علی عبدالملکی Reply

      سلام
      کلا ساختار شرط if مشکل داره
      چرا جهت برقراری شرط به این شکل نوشتید؟اصلا به این صورت کلا اشتباهه
      ضمنا در آکولاد ها هم دقت نکرده اید!!
      بفرمایید دقیقا چی میخوایید بنویسید؟

      فوریه 21, 2023 at 4:04 ب.ظ
  • امیررضا بهرامی Reply

    سلام و وقت بخیر خدمت شما. ببخشید در مورد کد مربوط به قسمت “شناسایی تگ های 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 شه. خیلی خیلی ممنون میشم سریع پاسخ بدید.

    فوریه 23, 2023 at 8:08 ب.ظ
    • علی عبدالملکی Reply

      سلام مجدد بله حق با شماست
      بنده کد رد اصلاح کردم
      حالا این چند خط کد رو شما میتونید در لوپ برنامه هر جا بشه قرار بدید، (داخل شرط های های دیگر قرار ندهید)
      data رو هم خودتون میتونید در ابتدای برنامه تعریف کنید، برای خواندن id کارت هم شما از همین قطعه کد میتونید استفاده کنید و به جای data از متغییر buffer1 استفاده کنید و شزط بررسی رو هم id کارت بزارید
      در واقع این قطعه کدی که قرار داده شده یه جور مثال کلی هست که شما خودتون میتونید متغییر ها رو همنطور که عرض کردم جایگزین کنید

      فوریه 27, 2023 at 11:25 ق.ظ
  • نظامی پور Reply

    سلام خسته نباشید.چه طور باید برای پروژه مستر کارت تعیین کنیم؟

    آوریل 12, 2023 at 3:27 ب.ظ
    • محمد دمیرچی Reply

      با سلام
      برای این کار شما باید با برنامه نویسی این کار را انجام بدهید.
      به عنوان مثال شما میخواهید کارت مستر برای اضافه کردن کارت جدید باشد. پس
      نوسط ریدر ID کارت را بخوانید در صورتی که این ID همان ID مستر شما بود منتظر کارت بعدی بشود و کارت دوم را بر روی ریدر بزنید ID دوم را بر روی حافظه ذخیره کند و کار های دیگری که میخواهید برای شما انجام بدهد.
      می توانید یک کارت دیگر به عنوان مستر حذف کن نیز درست کنید.

      آوریل 15, 2023 at 11:49 ق.ظ

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد.