ماژول کنترل دسترسی RFID RC522

سیستم کنترل تردد و مدیریت دسترسی با فناوری RFID پیشرفته

ماژول RFID RC522 یک سیستم کنترل دسترسی کامل بر اساس فناوری RFID 13.56MHz است که امکان شناسایی کارت‌ها و کلیدهای RFID، مدیریت کاربران، ثبت تردد و کنترل گیت‌ها/درها را فراهم می‌کند. این سیستم ایده‌آل برای کنترل دسترسی ساختمان‌ها، پارکینگ‌ها، محیط‌های اداری و سیستم‌های امنیتی است.


ویژگی‌های کلیدی

  • فناوری RFID پیشرفته: فرکانس 13.56MHz با پروتکل‌های ISO 14443A/MIFARE

  • برد خواندن: تا 5cm (بسته به آنتن و تگ)

  • پشتیبانی از چندین تگ: کارت‌های Mifare 1K, 4K, Ultralight, DESFire

  • امنیت بالا: احراز هویت 6 مرحله‌ای، ارتباط رمزنگاری شده

  • رابط‌های متنوع: SPI، I2C، UART (قابل انتخاب با جامپر)

  • خروجی‌های کنترلی: رله برای کنترل درب، بازکن درب (Door Strike)

  • نمایشگر: LCD 16×2 یا 20×4 برای نمایش اطلاعات

  • ورودی‌های کمکی: دکمه خروج اضطراری، سنسور درب باز

  • ذخیره‌سازی: کارت EEPROM داخلی برای ذخیره کاربران

  • اتصال به کامپیوتر: امکان اتصال USB برای مدیریت نرم‌افزاری


مشخصات فنی

  • تراشه RFID: NXP MFRC522

  • فرکانس کاری: 13.56MHz

  • پروتکل‌ها: ISO/IEC 14443 A/MIFARE

  • محدوده خواندن: 0 – 5cm (با آنتن استاندارد)

  • ولتاژ کاری: 3.3V (با رگولاتور 3.3V داخلی)

  • جریان مصرف: 13-26mA در حالت فعال

  • رابط ارتباطی: SPI (پیش‌فرض)، I2C، UART

  • نرخ انتقال داده: تا 848kBd

  • دمای کاری: -20°C تا +85°C

  • حافظه کاربران: تا 1000 کاربر در EEPROM داخلی

  • ابعاد ماژول: 40mm × 60mm


اجزای سیستم کامل

سخت‌افزار:

  1. ماژول RFID RC522 – برای خواندن کارت‌ها

  2. برد کنترل آردوینو Mega/Nano – پردازش مرکزی

  3. ماژول RTC DS3231 – ثبت زمان دقیق تردد

  4. ماژول SD Card – ذخیره لاگ ترددها

  5. ماژول رله 2 کاناله – کنترل درب و چراغ

  6. نمایشگر LCD 20×4 با I2C – نمایش اطلاعات

  7. بازکن درب الکترومکانیکی – Door Strike

  8. کارت‌های RFID – Mifare 1K (حداقل 10 عدد)

  9. کلید RFID – Key Fob (5 عدد)

  10. منبع تغذیه 12V/2A – تغذیه سیستم

نرم‌افزار:

  • سیستم مدیریت کاربران

  • ثبت تردد با زمان‌بندی

  • گزارش‌گیری از ترددها

  • تنظیم سطوح دسترسی

  • هشدارهای امنیتی


اتصال به آردوینو (پیکربندی SPI)

RC522 ← آردوینو Uno/Nano
-------------------------
SDA  (SS)   → D10
SCK         → D13
MOSI        → D11
MISO        → D12
IRQ         → (اختیاری) D9
GND         → GND
RST         → D9
3.3V        → 3.3V

کد پایه: خواندن UID کارت RFID

/*
 * خواندن UID کارت RFID با RC522
 * نیاز به کتابخانه MFRC522
 */

#include <SPI.h>
#include <MFRC522.h>

#define SS_PIN 10   // Slave Select
#define RST_PIN 9   // Reset

MFRC522 mfrc522(SS_PIN, RST_PIN); // ایجاد شیء RFID

// آرایه برای ذخیره UID کارت
byte uid[4];
String uidString = "";

// برای نمایش روی LCD
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 20, 4); // آدرس I2C و ابعاد LCD

void setup() {
  Serial.begin(9600);
  SPI.begin();
  mfrc522.PCD_Init();
  
  // راه‌اندازی LCD
  lcd.init();
  lcd.backlight();
  
  Serial.println("=========================================");
  Serial.println("   RFID Access Control System - RC522");
  Serial.println("=========================================");
  Serial.println("Scan RFID card/tag...");
  
  lcd.setCursor(0, 0);
  lcd.print("RFID Access Control");
  lcd.setCursor(0, 1);
  lcd.print("Scan your card...");
  
  delay(1000);
}

void loop() {
  // بررسی وجود کارت جدید
  if (!mfrc522.PICC_IsNewCardPresent()) {
    return;
  }
  
  // خواندن کارت
  if (!mfrc522.PICC_ReadCardSerial()) {
    return;
  }
  
  // دریافت UID
  uidString = "";
  for (byte i = 0; i < mfrc522.uid.size; i++) {
    uid[i] = mfrc522.uid.uidByte[i];
    if (uid[i] < 0x10) {
      uidString += "0";
    }
    uidString += String(uid[i], HEX);
    if (i < mfrc522.uid.size - 1) {
      uidString += ":";
    }
  }
  
  uidString.toUpperCase();
  
  // نمایش اطلاعات
  displayCardInfo();
  
  // بررسی مجوز دسترسی
  checkAccessPermission();
  
  // توقف ارتباط با کارت
  mfrc522.PICC_HaltA();
  
  delay(2000); // تأخیر بین خواندن‌ها
}

void displayCardInfo() {
  Serial.println("\n=== Card Detected ===");
  Serial.print("UID: ");
  Serial.println(uidString);
  Serial.print("Type: ");
  
  // تشخیص نوع تگ
  MFRC522::PICC_Type piccType = mfrc522.PICC_GetType(mfrc522.uid.sak);
  Serial.println(mfrc522.PICC_GetTypeName(piccType));
  
  // نمایش روی LCD
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("Card Detected!");
  
  lcd.setCursor(0, 1);
  lcd.print("UID: ");
  lcd.print(uidString.substring(0, 11));
  
  lcd.setCursor(0, 2);
  lcd.print("Type: ");
  lcd.print(mfrc522.PICC_GetTypeName(piccType));
}

void checkAccessPermission() {
  // لیست کارت‌های مجاز (در پروژه واقعی از EEPROM یا SD خوانده می‌شود)
  String authorizedCards[] = {
    "A1:B2:C3:D4",
    "11:22:33:44",
    "AA:BB:CC:DD"
  };
  
  int numCards = sizeof(authorizedCards) / sizeof(authorizedCards[0]);
  bool authorized = false;
  
  // جستجو در لیست کارت‌های مجاز
  for (int i = 0; i < numCards; i++) {
    if (uidString == authorizedCards[i]) {
      authorized = true;
      break;
    }
  }
  
  // نمایش نتیجه
  if (authorized) {
    Serial.println("Access: GRANTED");
    lcd.setCursor(0, 3);
    lcd.print("Access: GRANTED    ");
    
    // فعال کردن رله (باز کردن در)
    grantAccess();
  } else {
    Serial.println("Access: DENIED");
    lcd.setCursor(0, 3);
    lcd.print("Access: DENIED     ");
    
    // هشدار دسترسی غیرمجاز
    denyAccess();
  }
}

void grantAccess() {
  // اینجا رله را برای باز کردن در فعال کنید
  // digitalWrite(relayPin, HIGH);
  
  // بوق تأیید
  tone(8, 1500, 200);
  
  // نمایش زمان باز بودن در
  unsigned long startTime = millis();
  while (millis() - startTime < 3000) { // 3 ثانیه
    lcd.setCursor(0, 3);
    lcd.print("Door open: ");
    lcd.print(3 - ((millis() - startTime) / 1000));
    lcd.print("s  ");
    delay(200);
  }
  
  // بستن در
  // digitalWrite(relayPin, LOW);
  
  Serial.println("Door closed");
}

void denyAccess() {
  // بوزر هشدار
  for (int i = 0; i < 3; i++) {
    tone(8, 800, 300);
    delay(400);
  }
  
  // چشمک زدن LCD
  for (int i = 0; i < 5; i++) {
    lcd.noBacklight();
    delay(200);
    lcd.backlight();
    delay(200);
  }
}

کد سیستم کامل مدیریت دسترسی

/*
 * سیستم کامل کنترل دسترسی RFID با ثبت زمان
 * با قابلیت ذخیره در SD Card و نمایش روی LCD
 */

#include <SPI.h>
#include <MFRC522.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <SD.h>
#include <RTClib.h>
#include <EEPROM.h>

// تعریف پایه‌ها
#define SS_PIN 53     // برای آردوینو Mega
#define RST_PIN 5
#define RELAY_PIN 7   // کنترل درب
#define BUZZER_PIN 8  // بوزر
#define DOOR_SENSOR_PIN 2 // سنسور وضعیت درب
#define BUTTON_PIN 3  // دکمه خروج اضطراری
#define SD_CS_PIN 4   // پایه ChipSelect کارت SD

// اشیاء
MFRC522 mfrc522(SS_PIN, RST_PIN);
LiquidCrystal_I2C lcd(0x27, 20, 4); // LCD با آدرس I2C
RTC_DS3231 rtc;                     // ماژول ساعت واقعی
File logFile;                       // فایل لاگ

// ساختار داده کاربر
struct User {
  char uid[12];      // UID کارت به صورت رشته
  char name[20];     // نام کاربر
  byte accessLevel;  // سطح دسترسی (0-3)
  bool enabled;      // فعال/غیرفعال
  unsigned long validUntil; // تاریخ انقضا
};

// متغیرهای سیستم
User currentUser;
bool systemArmed = true;
bool doorOpen = false;
unsigned long doorOpenTime = 0;
const unsigned long AUTO_CLOSE_TIME = 10000; // 10 ثانیه

// شماره آخرین کاربر ثبت شده در EEPROM
int lastUserAddress = 0;
const int EEPROM_SIZE = 1024;
const int USER_SIZE = sizeof(User);

void setup() {
  Serial.begin(9600);
  
  // راه‌اندازی LCD
  lcd.init();
  lcd.backlight();
  
  // راه‌اندازی RFID
  SPI.begin();
  mfrc522.PCD_Init();
  
  // راه‌اندازی RTC
  if (!rtc.begin()) {
    Serial.println("RTC not found!");
    lcdPrint("RTC Error!", 0, true);
    while (1);
  }
  
  // تنظیم زمان اگر تنظیم نشده
  if (rtc.lostPower()) {
    rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
  }
  
  // راه‌اندازی SD Card
  if (!SD.begin(SD_CS_PIN)) {
    Serial.println("SD Card failed!");
    lcdPrint("SD Card Error!", 0, true);
  } else {
    Serial.println("SD Card OK");
  }
  
  // راه‌اندازی پایه‌ها
  pinMode(RELAY_PIN, OUTPUT);
  pinMode(BUZZER_PIN, OUTPUT);
  pinMode(DOOR_SENSOR_PIN, INPUT_PULLUP);
  pinMode(BUTTON_PIN, INPUT_PULLUP);
  
  // حالت اولیه
  digitalWrite(RELAY_PIN, LOW);
  digitalWrite(BUZZER_PIN, LOW);
  
  // نمایش اطلاعات سیستم
  displaySystemInfo();
  
  // بارگذاری کاربران از EEPROM
  loadUsersFromEEPROM();
}

void loop() {
  // بررسی وضعیت درب
  checkDoorStatus();
  
  // بررسی دکمه خروج اضطراری
  checkEmergencyButton();
  
  // بررسی کارت RFID
  checkRFID();
  
  // مدیریت باز بودن خودکار درب
  manageDoorAutoClose();
  
  // نمایش وضعیت سیستم هر 5 ثانیه
  static unsigned long lastStatusDisplay = 0;
  if (millis() - lastStatusDisplay > 5000) {
    displaySystemStatus();
    lastStatusDisplay = millis();
  }
  
  delay(100);
}

void checkRFID() {
  // بررسی وجود کارت جدید
  if (!mfrc522.PICC_IsNewCardPresent()) {
    return;
  }
  
  // خواندن کارت
  if (!mfrc522.PICC_ReadCardSerial()) {
    return;
  }
  
  // خواندن UID
  String uid = readCardUID();
  
  // جستجوی کاربر در پایگاه داده
  if (findUser(uid, currentUser)) {
    // بررسی اعتبار کاربر
    if (checkUserValidity(currentUser)) {
      // دسترسی مجاز
      grantAccess(currentUser);
    } else {
      // کاربر معتبر نیست
      denyAccess("User invalid/expired");
    }
  } else {
    // کاربر ناشناس
    denyAccess("Unauthorized card");
  }
  
  // توقف ارتباط با کارت
  mfrc522.PICC_HaltA();
}

String readCardUID() {
  String uid = "";
  for (byte i = 0; i < mfrc522.uid.size; i++) {
    if (mfrc522.uid.uidByte[i] < 0x10) {
      uid += "0";
    }
    uid += String(mfrc522.uid.uidByte[i], HEX);
    if (i < mfrc522.uid.size - 1) {
      uid += ":";
    }
  }
  uid.toUpperCase();
  return uid;
}

bool findUser(String uid, User &user) {
  // جستجو در EEPROM
  for (int addr = 0; addr < lastUserAddress; addr += USER_SIZE) {
    EEPROM.get(addr, user);
    
    // مقایسه UID
    if (String(user.uid) == uid) {
      return true;
    }
  }
  return false;
}

bool checkUserValidity(User user) {
  // بررسی فعال بودن
  if (!user.enabled) {
    return false;
  }
  
  // بررسی تاریخ انقضا
  DateTime now = rtc.now();
  unsigned long nowUnix = now.unixtime();
  
  if (user.validUntil > 0 && nowUnix > user.validUntil) {
    return false;
  }
  
  // بررسی محدودیت زمانی دسترسی
  if (!checkTimeRestrictions(user)) {
    return false;
  }
  
  return true;
}

bool checkTimeRestrictions(User user) {
  DateTime now = rtc.now();
  int currentHour = now.hour();
  
  // مثال: سطح دسترسی 0 = 24 ساعته، 1 = فقط روز، 2 = فقط شب
  switch (user.accessLevel) {
    case 0: // دسترسی کامل
      return true;
    case 1: // فقط روز (8 صبح تا 8 شب)
      return (currentHour >= 8 && currentHour < 20);
    case 2: // فقط شب (8 شب تا 8 صبح)
      return (currentHour < 8 || currentHour >= 20);
    default:
      return false;
  }
}

void grantAccess(User user) {
  // نمایش اطلاعات
  lcdClear();
  lcdPrint("ACCESS GRANTED", 0);
  lcdPrint(user.name, 1);
  
  // نمایش سطح دسترسی
  String accessLevelStr = "Level: ";
  accessLevelStr += user.accessLevel;
  lcdPrint(accessLevelStr, 2);
  
  // نمایش زمان
  DateTime now = rtc.now();
  String timeStr = formatTime(now);
  lcdPrint(timeStr, 3);
  
  // بوق تأیید
  beep(1500, 200);
  delay(100);
  beep(2000, 200);
  
  // باز کردن درب
  openDoor();
  
  // ثبت لاگ
  logAccess(user.name, user.uid, "GRANTED");
  
  // ارسال به سریال
  Serial.print("Access granted for: ");
  Serial.print(user.name);
  Serial.print(" (");
  Serial.print(user.uid);
  Serial.println(")");
}

void denyAccess(String reason) {
  lcdClear();
  lcdPrint("ACCESS DENIED", 0);
  lcdPrint(reason, 1);
  
  // هشدار صوتی
  for (int i = 0; i < 3; i++) {
    beep(800, 300);
    delay(400);
  }
  
  // ثبت لاگ دسترسی غیرمجاز
  DateTime now = rtc.now();
  String timeStr = formatTime(now);
  logAccess("UNAUTHORIZED", "UNKNOWN", "DENIED: " + reason);
  
  Serial.print("Access denied: ");
  Serial.println(reason);
  
  delay(3000);
  displaySystemInfo();
}

void openDoor() {
  if (!doorOpen) {
    digitalWrite(RELAY_PIN, HIGH);
    doorOpen = true;
    doorOpenTime = millis();
    
    Serial.println("Door opened");
  }
}

void closeDoor() {
  if (doorOpen) {
    digitalWrite(RELAY_PIN, LOW);
    doorOpen = false;
    
    Serial.println("Door closed");
  }
}

void checkDoorStatus() {
  bool sensorState = digitalRead(DOOR_SENSOR_PIN);
  static bool lastState = HIGH;
  
  if (sensorState != lastState) {
    if (sensorState == LOW) {
      // درب باز شده
      doorOpen = true;
      logEvent("DOOR OPENED MANUALLY");
      lcdPrintCenter("Door forced open!", 2);
      beep(1000, 500);
    } else {
      // درب بسته شده
      doorOpen = false;
      logEvent("DOOR CLOSED");
    }
    lastState = sensorState;
  }
}

void checkEmergencyButton() {
  if (digitalRead(BUTTON_PIN) == LOW) {
    delay(50); // Debouncing
    if (digitalRead(BUTTON_PIN) == LOW) {
      // باز کردن درب در حالت اضطراری
      openDoor();
      logEvent("EMERGENCY BUTTON PRESSED");
      
      lcdClear();
      lcdPrint("EMERGENCY EXIT", 0);
      lcdPrint("Door unlocked", 1);
      
      // بوق هشدار
      for (int i = 0; i < 5; i++) {
        beep(1200, 200);
        delay(200);
      }
      
      delay(10000); // 10 ثانیه باز می‌ماند
      closeDoor();
      displaySystemInfo();
    }
  }
}

void manageDoorAutoClose() {
  if (doorOpen && (millis() - doorOpenTime > AUTO_CLOSE_TIME)) {
    closeDoor();
    lcdPrintCenter("Door auto-closed", 3);
    logEvent("DOOR AUTO-CLOSED");
  }
}

void logAccess(String name, String uid, String status) {
  DateTime now = rtc.now();
  
  // در سریال
  Serial.print(formatDateTime(now));
  Serial.print(" - ");
  Serial.print(name);
  Serial.print(" (");
  Serial.print(uid);
  Serial.print(") - ");
  Serial.println(status);
  
  // در SD Card
  if (SD.begin(SD_CS_PIN)) {
    logFile = SD.open("access.log", FILE_WRITE);
    if (logFile) {
      logFile.print(formatDateTime(now));
      logFile.print(",");
      logFile.print(name);
      logFile.print(",");
      logFile.print(uid);
      logFile.print(",");
      logFile.println(status);
      logFile.close();
    }
  }
}

void logEvent(String event) {
  DateTime now = rtc.now();
  String logEntry = formatDateTime(now) + " - " + event;
  
  Serial.println(logEntry);
  
  if (SD.begin(SD_CS_PIN)) {
    logFile = SD.open("events.log", FILE_WRITE);
    if (logFile) {
      logFile.println(logEntry);
      logFile.close();
    }
  }
}

String formatDateTime(DateTime dt) {
  char buffer[20];
  sprintf(buffer, "%04d-%02d-%02d %02d:%02d:%02d",
          dt.year(), dt.month(), dt.day(),
          dt.hour(), dt.minute(), dt.second());
  return String(buffer);
}

String formatTime(DateTime dt) {
  char buffer[9];
  sprintf(buffer, "%02d:%02d:%02d",
          dt.hour(), dt.minute(), dt.second());
  return String(buffer);
}

void beep(int frequency, int duration) {
  tone(BUZZER_PIN, frequency, duration);
  delay(duration);
  noTone(BUZZER_PIN);
}

void lcdPrint(String text, int row, bool clear = false) {
  if (clear) lcd.clear();
  lcd.setCursor(0, row);
  lcd.print(text);
}

void lcdPrintCenter(String text, int row) {
  lcd.setCursor((20 - text.length()) / 2, row);
  lcd.print(text);
}

void lcdClear() {
  lcd.clear();
}

void displaySystemInfo() {
  lcdClear();
  lcdPrint("RFID Access Control", 0);
  lcdPrint("System Ready", 1);
  
  DateTime now = rtc.now();
  String dateStr = formatDateTime(now);
  lcdPrint(dateStr.substring(0, 10), 2);
  lcdPrint(dateStr.substring(11), 3);
}

void displaySystemStatus() {
  lcd.setCursor(0, 3);
  String status = "D:";
  status += doorOpen ? "OPEN " : "CLOSE";
  status += " U:";
  status += lastUserAddress / USER_SIZE;
  status += " ";
  status += systemArmed ? "ARMED" : "DISARM";
  
  lcd.print(status);
}

void loadUsersFromEEPROM() {
  // خواندن تعداد کاربران از EEPROM
  lastUserAddress = EEPROM.read(0) * USER_SIZE;
  
  if (lastUserAddress == 0 || lastUserAddress > EEPROM_SIZE) {
    // پایگاه داده خالی یا خراب - ایجاد کاربر ادمین پیش‌فرض
    createDefaultAdmin();
  }
  
  Serial.print("Loaded ");
  Serial.print(lastUserAddress / USER_SIZE);
  Serial.println(" users from EEPROM");
}

void createDefaultAdmin() {
  User admin;
  strcpy(admin.uid, "A1:B2:C3:D4");
  strcpy(admin.name, "ADMIN");
  admin.accessLevel = 0; // دسترسی کامل
  admin.enabled = true;
  admin.validUntil = 0; // بدون انقضا
  
  // ذخیره در EEPROM
  EEPROM.put(USER_SIZE, admin); // آدرس 0 برای تعداد کاربران رزرو شده
  EEPROM.write(0, 1); // تعداد کاربران = 1
  
  lastUserAddress = USER_SIZE;
  
  Serial.println("Default admin created");
}

کد نرم‌افزار مدیریت کاربران (PC)

/*
 * نرم‌افزار مدیریت کاربران برای کامپیوتر
 * ارتباط از طریق سریال با آردوینو
 */

#include <SoftwareSerial.h>

SoftwareSerial pcSerial(10, 11); // RX, TX برای ارتباط با PC

enum Command {
  CMD_ADD_USER = 1,
  CMD_REMOVE_USER,
  CMD_LIST_USERS,
  CMD_SET_TIME,
  CMD_GET_LOGS,
  CMD_SYSTEM_STATUS,
  CMD_ARM_SYSTEM,
  CMD_DISARM_SYSTEM
};

void setup() {
  Serial.begin(9600);
  pcSerial.begin(9600);
  
  Serial.println("Access Control Management Ready");
  pcSerial.println("Access Control Management Ready");
}

void loop() {
  if (pcSerial.available()) {
    char cmd = pcSerial.read();
    handleCommand(cmd);
  }
  
  delay(100);
}

void handleCommand(char cmd) {
  switch (cmd) {
    case '1': // افزودن کاربر
      addUser();
      break;
    case '2': // حذف کاربر
      removeUser();
      break;
    case '3': // لیست کاربران
      listUsers();
      break;
    case '4': // تنظیم زمان
      setTime();
      break;
    case '5': // دریافت لاگ‌ها
      getLogs();
      break;
    case '6': // وضعیت سیستم
      getSystemStatus();
      break;
    case '7': // فعال‌سازی سیستم
      armSystem();
      break;
    case '8': // غیرفعال‌سازی سیستم
      disarmSystem();
      break;
    case '?': // راهنما
      showHelp();
      break;
  }
}

void addUser() {
  pcSerial.println("=== Add New User ===");
  
  // دریافت اطلاعات از کاربر
  pcSerial.println("Enter card UID (format: XX:XX:XX:XX):");
  String uid = readSerialString();
  
  pcSerial.println("Enter user name:");
  String name = readSerialString();
  
  pcSerial.println("Enter access level (0-3):");
  int level = readSerialInt();
  
  pcSerial.println("Enable user? (Y/N):");
  String enabledStr = readSerialString();
  bool enabled = (enabledStr == "Y" || enabledStr == "y");
  
  // ارسال به آردوینو
  Serial.print("ADD:");
  Serial.print(uid);
  Serial.print(",");
  Serial.print(name);
  Serial.print(",");
  Serial.print(level);
  Serial.print(",");
  Serial.println(enabled ? "1" : "0");
  
  pcSerial.println("User added successfully!");
}

void listUsers() {
  pcSerial.println("=== User List ===");
  
  // درخواست لیست از آردوینو
  Serial.println("LIST_USERS");
  
  // دریافت و نمایش لیست
  // (در آردوینو باید تابع ارسال لیست پیاده‌سازی شود)
}

String readSerialString() {
  String input = "";
  while (pcSerial.available() == 0) {
    delay(10);
  }
  
  while (pcSerial.available() > 0) {
    char c = pcSerial.read();
    if (c == '\n') break;
    input += c;
    delay(10);
  }
  
  return input;
}

int readSerialInt() {
  String input = readSerialString();
  return input.toInt();
}

void showHelp() {
  pcSerial.println("=== Access Control Commands ===");
  pcSerial.println("1 - Add new user");
  pcSerial.println("2 - Remove user");
  pcSerial.println("3 - List all users");
  pcSerial.println("4 - Set system time");
  pcSerial.println("5 - Download access logs");
  pcSerial.println("6 - System status");
  pcSerial.println("7 - Arm system");
  pcSerial.println("8 - Disarm system");
  pcSerial.println("? - Show this help");
  pcSerial.println("===============================");
}

نکات نصب و راه‌اندازی

نصب فیزیکی:

  1. محل نصب: دور از فلزات بزرگ که ممکن است بر سیگنال RFID تأثیر بگذارند

  2. ارتفاع: 120-140cm از زمین برای دسترسی راحت

  3. محافظت: استفاده از محفظه ضد آب برای محیط‌های بیرونی

  4. سیم‌کشی: استفاده از کابل‌های شیلددار برای کاهش نویز

تنظیمات آنتن:

// تنظیم قدرت آنتن RFID (0-7)
void setAntennaGain(byte gain) {
  if (gain > 7) gain = 7;
  mfrc522.PCD_SetAntennaGain(gain * 0x10);
}

افزایش امنیت:

// احراز هویت دو مرحله‌ای
bool authenticateCard(byte sector, byte keyType, byte key[6]) {
  MFRC522::StatusCode status;
  byte trailerBlock = sector * 4 + 3;
  
  status = mfrc522.PCD_Authenticate(keyType, trailerBlock, key, &(mfrc522.uid));
  return (status == MFRC522::STATUS_OK);
}

پشتیبان‌گیری از داده‌ها:

void backupToSD() {
  File backup = SD.open("backup.dat", FILE_WRITE);
  
  for (int i = 0; i < EEPROM_SIZE; i++) {
    backup.write(EEPROM.read(i));
  }
  
  backup.close();
  Serial.println("Backup completed");
}

پروژه‌های توسعه‌پذیر

1. سیستم حضور و غیاب کارکنان

// با قابلیت محاسبه اضافه کار و گزارش ماهانه

2. کنترل دسترسی پارکینگ هوشمند

// مدیریت ظرفیت پارکینگ با شناسایی پلاک خودرو

3. سیستم امانت‌دهی کتابخانه

// مدیریت امانت کتاب با کارت RFID

4. گاوصندوق الکترونیکی

// دسترسی به محفظه‌های مختلف با سطوح دسترسی متفاوت

5. سیستم رزرو اتاق‌های جلسه

// رزرو و دسترسی به اتاق‌های کنفرانس

جدول سطوح دسترسی پیشنهادی

سطح دسترسی توضیح
0 مدیریت کامل افزودن/حذف کاربر، تنظیمات سیستم
1 دسترسی نامحدود ورود/خروج در تمام ساعات
2 دسترسی روزانه فقط 8 صبح تا 8 شب
3 دسترسی محدود فقط ساعات اداری (9-17)
4 دسترسی موقت فقط تاریخ‌های مشخص شده
5 فقط گزارش امکان ورود ندارد، فقط می‌تواند گزارش بگیرد

پکیج خرید

پکیج استاندارد:

  • 1x ماژول RFID RC522

  • 1x آردوینو Mega 2560

  • 1x ماژول RTC DS3231

  • 1x ماژول کارت حافظه SD

  • 1x نمایشگر LCD 20×4 با I2C

  • 1x ماژول رله 2 کاناله

  • 10x کارت RFID Mifare 1K

  • 5x کلید RFID Key Fob

  • 1x منبع تغذیه 12V/3A

  • 1x محفظه فلزی ضد آب

پکیج نصب کامل:

  • همه موارد پکیج استاندارد

  • 1x بازکن درب الکترومکانیکی (Door Strike)

  • 1x سنسور وضعیت درب مگنتی

  • 1x دکمه خروج اضطراری

  • 10m کابل 4 زوج شیلددار

  • 1x نرم‌افزار مدیریت تحت ویندوز

  • نصب و راه‌اندازی توسط کارشناس

پکیج سازمانی (تا 4 درب):

  • 4x همه موارد پکیج استاندارد

  • 1x سرور مرکزی Raspberry Pi

  • 1x نرم‌افزار تحت وب کامل

  • 1x اپلیکیشن موبایل Android/iOS

  • 50x کارت RFID

  • 20x کلید RFID

  • 1 سال پشتیبانی کامل


گارانتی و پشتیبانی

  • گارانتی: 24 ماه تعویض سخت‌افزار

  • پشتیبانی نرم‌افزاری: 1 سال رایگان

  • آموزش: نصب‌کنندگان و اپراتورها

  • بروزرسانی: دسترسی مادام‌العمر به آپدیت‌ها

  • پشتیبانی اضطراری: 24/7 برای سازمان‌های حیاتی


سؤالات متداول

Q1: حداکثر تعداد کاربر چقدر است؟
با EEPROM داخلی: 100 کاربر | با SD Card: نامحدود

Q2: آیا می‌توان از روی کارت کپی گرفت؟
کارت‌های Mifare Classic قابل کپی‌گیری هستند. برای امنیت بالاتر از کارت‌های Ultralight یا DESFire استفاده کنید.

Q3: در صورت قطع برق چه اتفاقی می‌افتد؟
سیستم دارای باتری پشتیبان برای RTC است. لاگ‌ها روی SD Card ذخیره می‌شوند.

Q4: آیا می‌توان از طریق اینترنت کنترل کرد؟
بله، با اضافه کردن ماژول ESP8266 یا Ethernet Shield.

Q5: تفاوت این سیستم با اثرانگشت چیست؟
RFID سریع‌تر و بهداشتی‌تر است، اما اثرانگشت امنیت بیومتریک دارد.


توجه: این سیستم قابلیت توسعه به سیستم‌های چند دربی، اتصال به نرم‌افزارهای مدیریت منابع انسانی و یکپارچه‌سازی با دوربین‌های مداربسته را دارد. برای مشاوره