آردوینومتوسط۸ دقیقه مطالعهArduino IDE 2.x / Uno R3

ماژول خوانندهٔ RFID RC522

ماژول RC522 با تراشهٔ MFRC522 را از طریق SPI به آردوینو وصل می‌کنید، شناسهٔ یکتای کارت‌ها و تگ‌ها را می‌خوانید و با مقایسهٔ UID، نخستین قفل کنترل دسترسی را می‌سازید.

آنچه در این درس می‌آموزید

  • اصول کار RFID با فرکانس ۱۳٫۵۶ مگاهرتز و تگ‌های غیرفعال را توضیح دهید
  • RC522 را روی گذرگاه SPI سیم‌کشی و کتابخانهٔ MFRC522 را نصب کنید
  • شناسهٔ یکتا (UID) کارت را بخوانید و بر اساس آن دسترسی را بدهید یا بگیرید
نویسنده: تیم داکنامه · بازبینی: ۲۰۲۶-۱۰-۳۱
فهرست مطالب

کارت‌های پارکینگ، کارت‌های بانکی بی‌تماس و کلیدهای ساختمان‌ها همه یک تکنولوژی مشترک دارند: RFID — شناسایی با فرکانس رادیویی (Radio Frequency Identification). شما کارت را نزدیک خواننده می‌گیرید، بدون تماس و بدون باتری، هویت کارت خوانده می‌شود. ماژول RC522 رایج‌ترین خوانندهٔ آموزشی این خانواده است و با آردوینو، قفل درب الکترونیکی، سیستم حضور و غیاب یا صندوق امن می‌سازد. در این درس می‌فهمید کارت بدون باتری چطور جواب می‌دهد، RC522 را با SPI سیم‌کشی می‌کنید و شناسهٔ یکتای کارت‌ها را می‌خوانید.

اصول کار: خواننده و تگ غیرفعال

سیستم RFID دو بخش دارد: خواننده (Reader) و تگ (Tag). RC522 روی فرکانس ۱۳٫۵۶ مگاهرتز کار می‌کند و استاندارد آن ISO/IEC 14443A است — همان استاندارد کارت‌های MIFARE شرکت NXP.

جادوی «کارت بدون باتری» به القای الکترومغناطیسی برمی‌گردد: خواننده یک میدان مغناطیسی متغیر می‌سازد؛ کویل کوچک داخل کارت از همین میدان انرژی می‌گیرد و با همان انرژی، تراشهٔ خودش را بیدار و شناسه‌اش را رادیویی برمی‌گرداند. به چنین تگی تگ غیرفعال (Passive Tag) می‌گویند: بی‌باتری، بی‌دست‌ساز، با عمر عملاً نامحدود — اما فقط در برد کوتاه چند سانتی‌متری.

داخل کارت دو چیز مهم هست: UID — شناسهٔ یکتا (Unique Identifier) — که هنگام ساخت کارخانه‌ای ثبت شده و در کارت‌های ساده تغییرناپذیر است؛ و حافظهٔ بخش‌بندی‌شده (Sectors) که می‌توانید دادهٔ دلخواه در آن بنویسید و با کلید محافظت کنید. در این درس فقط UID را می‌خوانیم؛ نوشتن روی حافظهٔ کارت مبحث درس‌های بعدی است.

رابط SPI

RC522 با آردوینو روی گذرگاه SPI حرف می‌زند. اگر با SPI و نقش پین‌های MOSI و MISO و SS کار نکرده‌اید، اول درس پروتکل SPI را ببینید و برگردید؛ آنجا می‌بینید که روی Uno این خطوط پین‌های ۱۱ تا ۱۳ هستند و هر دستگاه به یک خط انتخاب جداگانه (SS) نیاز دارد.

پین‌ها و سیم‌کشی

پین ماژول نقش
SDA (SS) انتخاب دستگاه در SPI
SCK ساعت SPI
MOSI داده از آردوینو به ماژول
MISO داده از ماژول به آردوینو
IRQ خروجی وقفه (در این درس بلااستفاده)
GND زمین
RST ریست ماژول
3.3V تغذیه
آردوینو Uno ماژول RC522
D10 SDA (SS)
D13 SCK
D11 MOSI
D12 MISO
D9 RST
GND GND
3.3V 3.3V

نصب کتابخانه

  1. در Arduino IDE به Tools ← Manage Libraries بروید (یا آیکن کتابخانه در نوار کناری).
  2. عبارت MFRC522 را جست‌وجو کنید.
  3. بستهٔ MFRC522 از GithubCommunity (مخزن miguelbalboa) را نصب کنید. اگر پنجرهٔ وابستگی‌ها باز شد، Install all بزنید.
  4. برای تأیید، منوی File > Examples باید مثال‌های MFRC522 را نشان دهد.

اسکچ کامل: خواندن UID کارت

rc522-read-uid.ino
#include <SPI.h>
#include <MFRC522.h>

#define SS_PIN 10
#define RST_PIN 9

MFRC522 rfid(SS_PIN, RST_PIN);

void setup() {
  Serial.begin(9600);
  SPI.begin();
  rfid.PCD_Init();
  Serial.println("Place your card near the reader");
}

void loop() {
  // Wait for a new card
  if (!rfid.PICC_IsNewCardPresent()) return;
  if (!rfid.PICC_ReadCardSerial()) return;

  Serial.print("Card UID:");
  for (byte i = 0; i < rfid.uid.size; i++) {
    Serial.print(" ");
    if (rfid.uid.uidByte[i] < 0x10) Serial.print("0");
    Serial.print(rfid.uid.uidByte[i], HEX);
  }
  Serial.println();

  rfid.PICC_HaltA();
}

توضیح نکته‌های تازه:

  1. rfid.PCD_Init() — خود خواننده راه‌اندازی می‌شود؛ PCD نام استانداردِ «خواننده» و PICC نام استانداردِ «کارت» در ISO 14443 است.
  2. دو بررسی اول در loop — اگر کارت تازه‌ای جلوی خواننده نیست، بقیهٔ حلقه اجرا نمی‌شود؛ این الگوی «زود برگرد» برنامه را پاسخگو نگه می‌دارد.
  3. rfid.uid.size و uidByte[i] — شناسه معمولاً ۴ بایت است؛ حلقه تک‌تک بایت‌ها را می‌گیرد و با آرگومان HEX در Serial.print به شکل شانزده‌دهی چاپ می‌کند.
  4. if (uidByte[i] < 0x10) Serial.print("0"); — بایت‌های کوچک‌تر از ۱۶ با یک صفر ابتدایی چاپ می‌شوند تا عرض ستون‌ها یکنواخت بماند (مثلاً 0A به‌جای A).
  5. PICC_HaltA() — کارت را برای این خواننده ساکت می‌کند تا هر کارت در هر دور حلقه فقط یک‌بار خوانده شود.

کارت را نزدیک خواننده بگیرید. خروجی سریال مانیتور چنین است (UID هر کارت یکتاست؛ این نمونه است):

خروجی کد

Place your card near the reader Card UID: A1 B2 C3 D4 Card UID: A1 B2 C3 D4

هر کارت UID مخصوص خودش را دارد؛ همان رشتهٔ چاپ‌شدهٔ کارت‌تان را یادداشت کنید — در تمرین بعدی به آن نیاز دارید.

قفل کنترل دسترسی با UID

قلب هر سیستم دسترسی، مقایسهٔ UID خوانده‌شده با فهرست مجاز است:

rc522-access-control.ino
// Allowed card UIDs
byte allowedUIDs[][4] = {
  {0xA1, 0xB2, 0xC3, 0xD4},
  {0x12, 0x34, 0x56, 0x78}
};

bool isAllowed(byte *uid) {
  for (int c = 0; c < 2; c++) {
    bool match = true;
    for (byte i = 0; i < 4; i++) {
      if (allowedUIDs[c][i] != uid[i]) { match = false; break; }
    }
    if (match) return true;
  }
  return false;
}

در loop پس از خواندن UID، به‌جای چاپ ساده این را صدا بزنید: اگر true شد پیام Access granted و در غیر این صورت Access denied چاپ شود، و خروجی یک LED یا رله را هم بدهید. حواستان باشد UID «رمز» نیست و از کارت‌های خام قابل جعل است؛ این طرح برای آموزش و قفل‌های کم‌ریسک مناسب است، نه ورود به گاوصندوق.

اشتباهات رایج و عیب‌یابی

نشانه علت رایج راه‌حل
هیچ کارتی خوانده نمی‌شود تغذیه با ۵ ولت، آسیب ماژول یا جابه‌جایی SPI VCC را به 3.3V بدهید؛ پین‌های D9 تا D13 را با جدول تطبیق دهید
ماژول پاسخ می‌دهد ولی برد خواندن تقریباً صفر است تغذیهٔ ناپایدار یا کارت پشت جسم فلزی از تغذیهٔ تمیز ۳٫۳ ولت مطمئن شوید؛ کارت را روی سطح فلزی نگیرید
UID هر بار دو یا چند بار چاپ می‌شود نبود PICC_HaltA در پایان دور حلقه rfid.PICC_HaltA() را بعد از پردازش صدا بزنید
UID خالی یا طول غلط نوع تگ متفاوت (مثلاً تگ‌های ۷ بایتی) طول را از rfid.uid.size بگیرید، نه ۴ ثابت
در آپلود خطای ارتباط SPI SS روی پین دیگری تعریف شده پین SS را روی Uno همان D10 نگه دارید؛ D10 خروجی باید باشد وگرنه SPI نقش می‌بندد

تمرین‌ها

تمرین

تمرین ۱ — تعیین مجوز با LED

اسکچ کنترل دسترسی را کامل کنید: کارت مجاز پیام Access granted و روشن‌شدن LED روی پین ۶ برای ۲ ثانیه؛ کارت ناشناس پیام Access denied و سه چشمک سریع همان LED. UID کارت خودتان را در آرایهٔ مجاز بگذارید.

نمایش راه‌حل

دو حالت خروجی را بعد از isAllowed می‌چینید؛ LED با digitalWrite و تأخیرها کنترل می‌شود:

cpp
const int ledPin = 6;
pinMode(ledPin, OUTPUT);  // in setup()

// in loop(), after reading the UID:
if (isAllowed(rfid.uid.uidByte)) {
  Serial.println("Access granted");
  digitalWrite(ledPin, HIGH);
  delay(2000);
  digitalWrite(ledPin, LOW);
} else {
  Serial.println("Access denied");
  for (int i = 0; i < 3; i++) {
    digitalWrite(ledPin, HIGH);
    delay(150);
    digitalWrite(ledPin, LOW);
    delay(150);
  }
}

با کارت مجاز، خروجی سریال مانیتور چنین است:

خروجی کد

Place your card near the reader Card UID: A1 B2 C3 D4 Access granted

::: :::

خلاصه

  • RFID با میدان ۱۳٫۵۶ مگاهرتز و استاندارد ISO/IEC 14443A کار می‌کند؛ تگ غیرفعال انرژی‌اش را القایی از خواننده می‌گیرد و بی‌باتری است.
  • RC522 با تراشهٔ MFRC522 روی SPI حرف می‌زند و تغذیه‌اش فقط ۳٫۳ ولت است — ۵ ولت آن را می‌سوزاند.
  • کتابخانهٔ MFRC522 از GithubCommunity در Library Manager نصب می‌شود.
  • UID شناسهٔ یکتای هر کارت است؛ خواندنش با PICC_IsNewCardPresent و PICC_ReadCardSerial و چاپش با آرگومان HEX انجام می‌شود.
  • کنترل دسترسی یعنی مقایسهٔ UID با فهرست مجاز؛ UID رمز نیست و برای امنیت جدی کافی نیست.

کارتی که مجاز است حالا شناخته می‌شود؛ در درس بعدی با DS3231 به پروژه‌تان حافظهٔ زمان می‌دهید تا بداند «چه ساعتی» کدام کارت خوانده شده است.

منابع و ارجاع‌ها