Cách hoạt động của RFID và cách tạo khóa cửa dựa trên Arduino

Trong hướng dẫn này, chúng ta sẽ tìm hiểu RFID là gì, cách thức hoạt động và cách tạo khóa cửa dựa trên Arduino. Bạn có thể xem video sau hoặc đọc hướng dẫn dưới đây để biết thêm chi tiết.

Tổng quan

RFID là chữ viết tắt của Radio Tần số Nhận dạng và đây là công nghệ tự động được sử dụng rộng rãi trong nhiều ngành cho các nhiệm vụ như theo dõi nhân sự, kiểm soát truy cập, quản lý chuỗi cung ứng, theo dõi sách trong thư viện, hệ thống trạm thu phí, v.v.

Ứng dụng và sử dụng RFID

Cách thức hoạt động của RFID

Một hệ thống RFID bao gồm hai linh kiện chính, thẻ được đặt trên đối tượng mà chúng ta muốn xác định và bộ thu phát hoặc đầu đọc.

Cách thức hoạt động của RFID

Đầu đọc RFID bao gồm một mô-đun tần số vô tuyến, bộ điều khiển và cuộn ăng ten tạo ra trường điện từ tần số cao. Mặt khác, thẻ thường là một linh kiện thụ động, chỉ bao gồm ăng-ten và vi mạch điện tử, do đó, khi nó ở gần trường điện từ của bộ thu phát, do cảm ứng, một điện áp được tạo ra trong cuộn ăng ten của nó và điện áp phục vụ như là nguồn điện cho vi mạch.

Nguyên tắc làm việc của RFID

Bây giờ khi thẻ được cấp nguồn, nó có thể trích xuất thông tin được truyền từ đầu đọc và gửi tin nhắn trở lại đầu đọc, nó sử dụng một kỹ thuật gọi là thao tác tải. Bật và tắt tải ở ăng-ten của thẻ sẽ ảnh hưởng đến mức tiêu thụ điện của ăng-ten của bộ đọc có thể được đo là sụt áp. Sự thay đổi điện áp này sẽ được ghi lại dưới dạng 0 và 1 và đó là cách dữ liệu được truyền từ thẻ đến đầu đọc.

Ngoài ra còn có một cách truyền dữ liệu khác giữa đầu đọc và thẻ, được gọi là khớp nối tán xạ ngược. Trong trường hợp này, thẻ sử dụng một phần năng lượng nhận được để tạo ra một trường điện từ khác sẽ được chọn bởi ăng ten của bộ đọc.

RFID và Arduino

Đó là nguyên tắc làm việc cơ bản và bây giờ hãy xem cách chúng ta có thể sử dụng RFID với Arduino và xây dựng khóa cửa RFID của riêng mình. Chúng tôi sẽ sử dụng các thẻ dựa trên giao thức MIFARE và đầu đọc RFID MFRC522, chỉ tốn một vài đô la.

Các thẻ này có 1kb bộ nhớ và có một vi mạch có thể thực hiện các phép toán số học. Tần số hoạt động của chúng là 13,56 MHz và khoảng cách hoạt động lên tới 10 cm tùy thuộc vào hình dạng của ăng ten. Nếu chúng ta mang một trong những thẻ này trước một nguồn sáng, chúng ta có thể nhận thấy ăng-ten và vi mạch mà chúng ta đã nói trước đây.

Thẻ RFID bên trong chứa ăng-ten và vi mạch

Đối với mô-đun đọc RFID, nó sử dụng giao thức SPI để liên lạc với board Arduino và đây là cách chúng ta cần kết nối chúng. Xin lưu ý rằng chúng ta phải kết nối VCC của mô-đun với 3,3V và đối với các chân khác, chúng ta không phải lo lắng vì chúng có thể chịu được 5V.

Khi chúng tôi kết nối mô-đun, chúng tôi cần tải xuống thư viện MFRC522 từ GitHub. Thư viện đi kèm với một số ví dụ hay từ đó chúng ta có thể tìm hiểu cách sử dụng mô-đun.

Trước tiên, chúng tôi có thể tải lên ví dụ về DumpInfo và kiểm tra xem hệ thống có hoạt động tốt không. Bây giờ nếu chúng ta chạy Trình giám sát nối tiếp và mang thẻ đến gần mô-đun, trình đọc sẽ bắt đầu đọc thẻ và tất cả thông tin từ thẻ sẽ được hiển thị trên màn hình nối tiếp.

Ví dụ thư viện Arduino MFRC522 Dumpinfo

Ở đây chúng ta có thể nhận thấy số UID của thẻ cũng như bộ nhớ 1 KB thực sự được chia thành 16 cung, mỗi khu vực thành 4 khối và mỗi khối có thể lưu trữ 2 byte dữ liệu. Đối với hướng dẫn này, chúng tôi sẽ không sử dụng bất kỳ bộ nhớ nào của thẻ, chúng tôi sẽ chỉ sử dụng số UID của thẻ.

Dự án kiểm soát truy cập khóa cửa Arduino

Trước khi chúng ta tìm hiểu code của dự án khóa cửa RFID, chúng ta hãy xem các linh kiện và sơ đồ mạch của dự án này.

Dự án kiểm soát truy cập khóa cửa Arduino

Ngoài mô-đun RFID, chúng tôi sẽ sử dụng cảm biến tiệm cận để kiểm tra xem cửa đóng hay mở, mô tơ servo cho cơ chế khóa và hiển thị thông tin.

Các linh kiện cần thiết:

  • Mô-đun RFID MFRC522
  • Động cơ Servo
  • Màn hình LCD
  • Board Arduino
  • Breadboard và dây cắm
  • Cảm biến tiệm cận CNY70

Dự án có quy trình làm việc như sau: Đầu tiên chúng ta phải đặt thẻ chính và sau đó hệ thống sẽ chuyển sang chế độ bình thường. Nếu chúng tôi quét một thẻ không xác định, quyền truy cập sẽ bị từ chối, nhưng nếu chúng tôi quét đúng thẻ, chúng tôi sẽ vào chế độ chương trình từ đó chúng tôi có thể thêm và ủy quyền cho thẻ không xác định. Vì vậy, bây giờ nếu chúng ta quét thẻ một lần nữa, quyền truy cập sẽ được cấp để chúng ta có thể mở cửa.

Dự án kiểm soát truy cập khóa cửa Arduino

Cửa sẽ tự động khóa sau khi chúng ta đóng cửa. Nếu chúng ta muốn xóa một thẻ khỏi hệ thống, chúng ta chỉ cần quay lại chế độ chương trình, quét thẻ và nó sẽ bị xóa.

Code Arduino

Bây giờ chúng ta hãy phân tích code cho chương trình.  Vì vậy, trước tiên chúng ta cần bao gồm các thư viện cho mô-đun RFID, màn hình hiển thị và mô tơ servo, xác định một số biến cần thiết cho chương trình bên dưới cũng như tạo các phiên bản của các thư viện.

#include <MFRC522.h>
#include <LiquidCrystal.h>
#include <Servo.h>

#define RST_PIN   9
#define SS_PIN    10

byte readCard[4];
char* myTags[100] = {};
int tagsCount = 0;
String tagID = "";
boolean successRead = false;
boolean correctTag = false;
int proximitySensor;
boolean doorOpened = false;

// Create instances
MFRC522 mfrc522(SS_PIN, RST_PIN);
LiquidCrystal lcd(2, 3, 4, 5, 6, 7); //Parameters: (rs, enable, d4, d5, d6, d7)
Servo myServo; // Servo motor

Trong phần thiết lập, trước tiên, chúng tôi khởi tạo các mô-đun và đặt giá trị ban đầu của mô tơ servo vào vị trí khóa. Sau đó, chúng tôi in thông báo ban đầu lên màn hình và với vòng lặp sau khi chờ cho đến khi quét thẻ chính. Hàm tùy chỉnh getID () cho thẻ UID và chúng tôi đặt nó vào vị trí đầu tiên của mảng myTags [0].

void setup() {
  // Initiating
  SPI.begin();        // SPI bus
  mfrc522.PCD_Init(); //  MFRC522
  lcd.begin(16, 2);   // LCD screen
  myServo.attach(8);  // Servo motor

  myServo.write(10); // Initial lock position of the servo motor
  // Prints the initial message
  lcd.print("-No Master Tag!-");
  lcd.setCursor(0, 1);
  lcd.print("    SCAN NOW");
  // Waits until a master card is scanned
  while (!successRead) {
    successRead = getID();
    if ( successRead == true) {
      myTags[tagsCount] = strdup(tagID.c_str()); // Sets the master tag into position 0 in the array
      lcd.clear();
      lcd.setCursor(0, 0);
      lcd.print("Master Tag Set!");
      tagsCount++;
    }
  }
  successRead = false;
  printNormalModeMessage();
}

Chúng ta hãy xem hàm tùy chỉnh getID (). Đầu tiên, nó sẽ kiểm tra xem có một thẻ mới nào được đặt gần đầu đọc hay không và nếu vậy chúng ta sẽ tiếp tục với vòng lặp for vì nó sẽ nhận được UID của thẻ. Các thẻ mà chúng ta đang sử dụng có số UID 4 byte, vì vậy đó là lý do tại sao chúng ta cần thực hiện 4 lần lặp với vòng lặp này và sử dụng hàm concat (), chúng ta thêm 4 byte vào một biến String. Chúng tôi cũng đặt tất cả các ký tự của chuỗi thành chữ hoa và dừng đọc.

uint8_t getID() {
  // Getting ready for Reading PICCs
  if ( ! mfrc522.PICC_IsNewCardPresent()) { //If a new PICC placed to RFID reader continue
    return 0;
  }
  if ( ! mfrc522.PICC_ReadCardSerial()) {   //Since a PICC placed get Serial and continue
    return 0;
  }
  tagID = "";
  for ( uint8_t i = 0; i < 4; i++) {  // The MIFARE PICCs that we use have 4 byte UID
    readCard[i] = mfrc522.uid.uidByte[i];
    tagID.concat(String(mfrc522.uid.uidByte[i], HEX)); // Adds the 4 bytes in a single String variable
  }
  tagID.toUpperCase();
  mfrc522.PICC_HaltA(); // Stop reading
  return 1;
}

Trước khi chúng ta vào vòng lặp chính, ở phần cuối của phần thiết lập, chúng ta cũng gọi hàm tùy chỉnh printNormalModeMessage () để in thông báo của Access Control trên màn hình.

void printNormalModeMessage() {
  delay(1500);
  lcd.clear();
  lcd.print("-Access Control-");
  lcd.setCursor(0, 1);
  lcd.print(" Scan Your Tag!");
}

Trong vòng lặp chính, chúng ta bắt đầu với việc đọc giá trị của cảm biến tiệm cận, cho chúng ta biết cửa có bị đóng hay không.

int proximitySensor = analogRead(A0);

Vì vậy, nếu cánh cửa được đóng lại, sử dụng cùng một dòng như chúng tôi đã mô tả trong hàm tùy chỉnh getID (), chúng tôi sẽ quét và lấy UID của thẻ mới. Ở đây, chúng ta có thể nhận thấy rằng code sẽ không tiếp tục nữa cho đến khi chúng ta quét một thẻ vì dòng trả về trong câu lệnh if.

Khi đã quét thẻ, chúng tôi sẽ kiểm tra xem thẻ đó có phải là thẻ chính mà đã đăng ký trước đó hay không và nếu điều đó đúng, chúng tôi sẽ vào chế độ chương trình. Trong chế độ này, nếu quét một thẻ đã được ủy quyền, nó sẽ bị xóa khỏi hệ thống hoặc nếu thẻ không xác định, nó sẽ được thêm vào hệ thống như được ủy quyền.

// Checks whether the scanned tag is the master tag
    if (tagID == myTags[0]) {
      lcd.clear();
      lcd.print("Program mode:");
      lcd.setCursor(0, 1);
      lcd.print("Add/Remove Tag");
      while (!successRead) {
        successRead = getID();
        if ( successRead == true) {
          for (int i = 0; i < 100; i++) {
            if (tagID == myTags[i]) {
              myTags[i] = "";
              lcd.clear();
              lcd.setCursor(0, 0);
              lcd.print("  Tag Removed!");
              printNormalModeMessage();
              return;
            }
          }
          myTags[tagsCount] = strdup(tagID.c_str());
          lcd.clear();
          lcd.setCursor(0, 0);
          lcd.print("   Tag Added!");
          printNormalModeMessage();
          tagsCount++;
          return;
        }
      }
    }

Bên ngoài chế độ chương trình, với vòng lặp tiếp theo dành cho người dùng, chúng tôi kiểm tra xem thẻ được quét có phải với thẻ đã đăng ký không và chúng tôi sẽ mở khóa cửa hoặc giữ quyền truy cập bị từ chối. Cuối cùng, trong câu lệnh khác, chúng tôi đợi cho đến khi cửa đóng, sau đó chúng tôi khóa cửa và in lại thông báo chế độ bình thường.

// Checks whether the scanned tag is authorized
    for (int i = 0; i < 100; i++) {
      if (tagID == myTags[i]) {
        lcd.clear();
        lcd.setCursor(0, 0);
        lcd.print(" Access Granted!");
        myServo.write(170); // Unlocks the door
        printNormalModeMessage();
        correctTag = true;
      }
    }
    if (correctTag == false) {
      lcd.clear();
      lcd.setCursor(0, 0);
      lcd.print(" Access Denied!");
      printNormalModeMessage();
    }
  }
  // If door is open...
  else {
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print(" Door Opened!");
    while (!doorOpened) {
      proximitySensor = analogRead(A0);
      if (proximitySensor > 200) {
        doorOpened = true;
      }
    }
    doorOpened = false;
    delay(500);
    myServo.write(10); // Locks the door
    printNormalModeMessage();
  }

Code hoàn chỉnh của dự án:

/*
* Arduino Door Lock Access Control Project
* Library: MFRC522, https://github.com/miguelbalboa/rfid
*/

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

#define RST_PIN   9
#define SS_PIN    10

byte readCard[4];
char* myTags[100] = {};
int tagsCount = 0;
String tagID = "";
boolean successRead = false;
boolean correctTag = false;
int proximitySensor;
boolean doorOpened = false;

// Create instances
MFRC522 mfrc522(SS_PIN, RST_PIN);
LiquidCrystal lcd(2, 3, 4, 5, 6, 7); //Parameters: (rs, enable, d4, d5, d6, d7)
Servo myServo; // Servo motor

void setup() {
  // Initiating
  SPI.begin();        // SPI bus
  mfrc522.PCD_Init(); //  MFRC522
  lcd.begin(16, 2);   // LCD screen
  myServo.attach(8);  // Servo motor

  myServo.write(10); // Initial lock position of the servo motor
  // Prints the initial message
  lcd.print("-No Master Tag!-");
  lcd.setCursor(0, 1);
  lcd.print("    SCAN NOW");
  // Waits until a master card is scanned
  while (!successRead) {
    successRead = getID();
    if ( successRead == true) {
      myTags[tagsCount] = strdup(tagID.c_str()); // Sets the master tag into position 0 in the array
      lcd.clear();
      lcd.setCursor(0, 0);
      lcd.print("Master Tag Set!");
      tagsCount++;
    }
  }
  successRead = false;
  printNormalModeMessage();
}

void loop() {
  int proximitySensor = analogRead(A0);
  // If door is closed...
  if (proximitySensor > 200) {
    if ( ! mfrc522.PICC_IsNewCardPresent()) { //If a new PICC placed to RFID reader continue
      return;
    }
    if ( ! mfrc522.PICC_ReadCardSerial()) {   //Since a PICC placed get Serial and continue
      return;
    }
    tagID = "";
    // The MIFARE PICCs that we use have 4 byte UID
    for ( uint8_t i = 0; i < 4; i++) {  //
      readCard[i] = mfrc522.uid.uidByte[i];
      tagID.concat(String(mfrc522.uid.uidByte[i], HEX)); // Adds the 4 bytes in a single String variable
    }
    tagID.toUpperCase();
    mfrc522.PICC_HaltA(); // Stop reading

    correctTag = false;
    // Checks whether the scanned tag is the master tag
    if (tagID == myTags[0]) {
      lcd.clear();
      lcd.print("Program mode:");
      lcd.setCursor(0, 1);
      lcd.print("Add/Remove Tag");
      while (!successRead) {
        successRead = getID();
        if ( successRead == true) {
          for (int i = 0; i < 100; i++) {
            if (tagID == myTags[i]) {
              myTags[i] = "";
              lcd.clear();
              lcd.setCursor(0, 0);
              lcd.print("  Tag Removed!");
              printNormalModeMessage();
              return;
            }
          }
          myTags[tagsCount] = strdup(tagID.c_str());
          lcd.clear();
          lcd.setCursor(0, 0);
          lcd.print("   Tag Added!");
          printNormalModeMessage();
          tagsCount++;
          return;
        }
      }
    }
    successRead = false;
    // Checks whether the scanned tag is authorized
    for (int i = 0; i < 100; i++) {
      if (tagID == myTags[i]) {
        lcd.clear();
        lcd.setCursor(0, 0);
        lcd.print(" Access Granted!");
        myServo.write(170); // Unlocks the door
        printNormalModeMessage();
        correctTag = true;
      }
    }
    if (correctTag == false) {
      lcd.clear();
      lcd.setCursor(0, 0);
      lcd.print(" Access Denied!");
      printNormalModeMessage();
    }
  }
  // If door is open...
  else {
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print(" Door Opened!");
    while (!doorOpened) {
      proximitySensor = analogRead(A0);
      if (proximitySensor > 200) {
        doorOpened = true;
      }
    }
    doorOpened = false;
    delay(500);
    myServo.write(10); // Locks the door
    printNormalModeMessage();
  }
}

uint8_t getID() {
  // Getting ready for Reading PICCs
  if ( ! mfrc522.PICC_IsNewCardPresent()) { //If a new PICC placed to RFID reader continue
    return 0;
  }
  if ( ! mfrc522.PICC_ReadCardSerial()) {   //Since a PICC placed get Serial and continue
    return 0;
  }
  tagID = "";
  for ( uint8_t i = 0; i < 4; i++) {  // The MIFARE PICCs that we use have 4 byte UID
    readCard[i] = mfrc522.uid.uidByte[i];
    tagID.concat(String(mfrc522.uid.uidByte[i], HEX)); // Adds the 4 bytes in a single String variable
  }
  tagID.toUpperCase();
  mfrc522.PICC_HaltA(); // Stop reading
  return 1;
}

void printNormalModeMessage() {
  delay(1500);
  lcd.clear();
  lcd.print("-Access Control-");
  lcd.setCursor(0, 1);
  lcd.print(" Scan Your Tag!");
}

Để lại một bình luận

Email của bạn sẽ không được hiển thị công khai. Các trường bắt buộc được đánh dấu *

Chat hỗ trợ
Chat ngay