亿迅智能制造网
工业4.0先进制造技术信息网站!
首页 | 制造技术 | 制造设备 | 工业物联网 | 工业材料 | 设备保养维修 | 工业编程 |
home  MfgRobots >> 亿迅智能制造网 >  >> Manufacturing Technology >> 制造工艺

RFID 的工作原理以及如何制作基于 Arduino 的 RFID 门锁

在本教程中,我们将了解 RFID 是什么、它是如何工作的以及如何制作基于 Arduino 的 RFID 门锁。您可以观看以下视频或阅读下面的书面教程了解更多详情。

概览

RFID 代表 射频识别 它是一种非接触式技术,在许多行业中广泛用于人员跟踪、访问控制、供应链管理、图书馆图书跟踪、收费站系统等任务。[/column]

RFID 的工作原理


RFID系统由两个主要组件组成,一个位于我们想要识别的物体上的转发器或标签,以及一个收发器或阅读器。

RFID阅读器由射频模块、控制单元和产生高频电磁场的天线线圈组成。另一方面,标签通常是无源元件,仅由天线和电子微芯片组成,因此当它靠近收发器的电磁场时,由于感应,其天线线圈中会产生电压,这电压作为微芯片的电源。

现在,随着标签通电,它可以从阅读器中提取传输的消息,并将消息发送回阅读器,它使用了一种称为负载操作的技术。打开和关闭标签天线上的负载会影响阅读器天线的功耗,这可以通过电压降来测量。电压的这种变化将被捕获为 1 和 0,这就是数据从标签传输到阅读器的方式。

阅读器和标签之间还有另一种数据传输方式,称为反向散射耦合。在这种情况下,标签使用部分接收到的能量来产生另一个电磁场,该电磁场将被阅读器的天线接收到。

RFID 和 Arduino

这就是基本的工作原理,现在让我们看看如何将 RFID 与 Arduino 结合使用并构建我们自己的 RFID 门锁。我们将使用基于 MIFARE 协议的标签和 MFRC522 RFID 阅读器,只需几美元。

这些标签有 1kb 的内存,并有一个可以进行算术运算的微芯片。它们的工作频率为 13.56 MHz,工作距离可达 10 cm,具体取决于天线的几何形状。如果我们将其中一个标签放在光源前,我们会注意到我们之前谈到的天线和微芯片。

至于 RFID 阅读器模块,它使用 SPI 协议与 Arduino 板进行通信,这是我们需要连接它们的方式。请注意,我们必须将模块的 VCC 连接到 3.3V,至于其他引脚我们不必担心,因为它们可以承受 5V。

连接模块后,我们需要从 GitHub 下载 MFRC522 库。该库附带了几个很好的示例,我们可以从中学习如何使用该模块。

首先我们可以上传“DumpInfo”示例,测试我们的系统是否正常工作。现在如果我们运行串口监视器并将标签放在模块附近,阅读器将开始读取标签,标签中的所有信息都将显示在串口监视器上。

这里我们可以注意到标签的 UID 号以及 1 KB 的内存,实际上分为 16 个扇区,每个扇区分为 4 个块,每个块可以存储 2 个字节的数据。在本教程中,我们不会使用任何标签的内存,我们将只使用标签的 UID 号。

Arduino RFID 门锁访问控制项目

在介绍我们的RFID门锁项目的代码之前,我们先来看看这个项目的组件和电路原理图。

除了 RFID 模块,我们还将使用用于检查门是否关闭或打开的接近传感器、用于锁定机构的伺服电机和字符显示器。

您可以从以下链接获取本 Arduino 教程所需的组件:

  • MFRC522 RFID模块…………………….
  • 伺服电机……………………………………..
  • 液晶显示屏…………………………………………
  • Arduino 开发板……………………………………。
  • 面包板和跳线………………..
  • 接近传感器 CNY70 ……………………

该项目有以下工作流程:首先我们必须设置一个主标签,然后系统进入正常模式。如果我们扫描未知标签,访问将被拒绝,但如果我们扫描主设备,我们将进入程序模式,从中我们可以添加和授权未知标签。所以现在如果我们再次扫描标签,就会被授予访问权限,这样我们就可以开门了。

我们关门后门会自动锁上。如果我们想从系统中删除标签,我们只需要再次进入程序模式,扫描已知标签,它将被删除。

源代码

现在让我们看一下代码。  所以首先我们需要包含 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 motorCode language: Arduino (arduino)

在设置部分,首先我们初始化模块,并将伺服电机的初始值设置为锁定位置。然后我们将初始消息打印到显示器上,并使用以下“while”循环等待主标签被扫描。 getID() 自定义函数获取标签 UID,我们将其放入 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();
}Code language: Arduino (arduino)

让我们看一下 getID() 自定义函数。首先,它检查阅读器附近是否有新标签,如果有,我们将继续执行“for”循环,该循环将获取标签的 UID。我们使用的标签有 4 个字节的 UID 编号,这就是为什么我们需要在这个循环中进行 4 次迭代,并使用 concat() 函数将 4 个字节添加到单个字符串变量中。我们还将字符串的所有字符设置为大写,并在结束时停止读取。

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;
}Code language: Arduino (arduino)

在进入主循环之前,在设置部分的最后,我们还调用了 printNormalModeMessage() 自定义函数,该函数会在显示屏上打印“访问控制”消息。

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

在主循环中,我们从读取接近传感器的值开始,它告诉我们门是否关闭。

int proximitySensor = analogRead(A0);Code language: Arduino (arduino)

因此,如果门已关闭,使用我们在 getID() 自定义函数中描述的相同行,我们将扫描并获取新标签的 UID。我们可以注意到,由于“if”语句中的“return”行,在我们扫描标签之前,代码不会继续执行。

扫描完标签后,我们检查该标签是否是我们之前注册的主标签,如果是,我们将进入程序模式。在这种模式下,如果我们扫描一个已经授权的标签,它将从系统中删除,或者如果标签是未知的,它将作为授权添加到系统中。

// 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;
        }
      }
    }Code language: Arduino (arduino)

在程序模式之外,通过下一个“for”循环,我们检查扫描的标签是否等于任何已注册的标签,我们要么解锁门,要么拒绝访问。在“else”语句的最后,我们等到门关闭,然后锁上门并再次打印正常模式消息。

// 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 language: Arduino (arduino)

以上就是全部内容了,下面是项目的完整代码:

/*
* Arduino Door Lock Access Control Project
*                
* by Dejan Nedelkovski, www.HowToMechatronics.com
* 
* 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!");
}Code language: Arduino (arduino)

希望您喜欢本教程,并随时在下面的评论部分提出任何问题。


制造工艺

  1. 带有 RC522 的 Arduino RFID 锁 - MIFARE 协议 13.56 Mhz
  2. Arduino RFID 锁教程
  3. 如何制作可自定义的打孔键盘按钮
  4. 基于密码的门锁
  5. 基于 Arduino 和 OLED 的元胞自动机
  6. eDOT - 基于 Arduino 的精密时钟和气象站
  7. 基于Arduino和谷歌电子表格的考勤系统
  8. 如何用 Arduino 制作音乐
  9. 如何制作基于 Arduino 的自动开门
  10. 基于 Arduino 和 Android 的密码保护门锁
  11. 如何制作 Arduino 蓝牙控制汽车
  12. 如何使用 Arduino 和 Processing IDE 制作指南针