### 第12课 刷卡开门

#### 12.1 项目介绍

现在很多小区的门使用了刷卡开门这个功能，非常的方便。这节课我们将学习使用及RFID-MFRC522模块和磁卡（钥匙扣/白卡）控制门转动。

#### 12.2 模块相关资料

**（1）元件知识**

**RFID：** RFID (Radio Frequency Identification)是一种无线通信技术。一个完整的RFID系统一般由应答器和读取器组成。通常我们使用标签作为应答器，每个标签都有一个唯一的代码，它附着在物体上，用来识别目标物体。阅读器是用来读取(或写入)标签信息的设备。

从RFID技术衍生的产品可以分为三类：无源RFID产品、有源RFID产品和半有源RFID产品。而无源RFID产品是市场上最早、最成熟、使用最广泛的产品。它在我们的日常生活中随处可见，如公交卡、餐卡、银行卡、酒店门禁卡等，这些都属于近距离接触识别。无源RFID产品的主要工作频率有:125KHZ(低频)、13.56MHZ(高频)、433MHZ(超高频)、915MHZ(超高频)。有源和半有源RFID产品工作在更高的频率。

我们使用的RFID模块是无源RFID产品，工作频率为13.56MHz。

**RFID-MFRC522刷卡模块：** MFRC522是一个高度集成的读取/写入器IC，用于13.56MHz的非接触式通信。MFRC522的内部发射器能够驱动一个读取/写入天线，设计用于与ISO/IEC 14443A/MIFARE卡和应答器通信，而无需额外的有源电路。接收模块为来自ISO/IEC 14443 A/MIFARE兼容卡和应答器的信号解调和解码提供了一个健壮和高效的实现。数字模块管理完整的ISO/IEC 14443A组帧和错误检测(奇偶校验和CRC)功能。

该RFID模块采用MFRC522作为控制芯片，采用I2C (Inter－Integrated Circuit)接口。

**（2）规格参数：**

工作电压：DC 3.3V-5V

工作电流：13—100mA/DC 5V

空闲电流：10-13mA/DC 5V

休眠电流：\<80uA

峰值电流：\<100mA

工作频率：13.56MHz

最大功率：0.5W

支持的卡类型：mifare1 S50、mifare1 S70、mifare UltraLight、mifare Pro、mifare Desfire

环境工作温度：摄氏-20—80℃  
环境储存温度：摄氏-40—85℃  
环境相对湿度：相对湿度5%—95%

数据传输速率：最大10Mbit/s

#### 12.3 实验组件

|![](media/esp32.png)|![](media/RFID-MFRC522.png)|![](media/servo.png)|![](media/3p.png)|
|-|-|-|-|
|ESP32 Plus主板 *1|RFID-MFRC522刷卡模块 *1|180度舵机 *1|3P线 *1|
|![](media/lcd1.png)|![](media/button.png)|![](media/white-card.jpeg)|![](media/4p.png)|
|I2C LCD1602模块 *1|按键 *1|白卡 *1|4P线 *1| 
|![](media/4p1.png)|![](media/usb.png)|![Img](./media/blue-card.png)|  |
|4pin 黑红蓝绿母对母连拼 *1|USB线 *1|钥匙扣 *1|  |

#### 12.4 模块接线图

RFID-RC522刷卡模块，木板房子⑦处(左侧)按键1，门舵机和I2C 1602 LCD模块的控制引脚：

|木板房子⑦处(左侧)按键1（S引脚）|io4|
|-|-|
|门舵机（橙黄色线引脚）|io13|
|RFID-MFRC522刷卡模块（SDA引脚）|SDA|
|RFID-MFRC522刷卡模块（SCL引脚）|SCL|
|I2C 1602 LCD模块（SDA引脚）|SDA|
|I2C 1602 LCD模块（SCL引脚）|SCL|

⚠️ **特别注意：智能家居已经组装好了，这里不需要把RFID-RC522模块、按键、舵机和I2C 1602 LCD模块拆下来又重新组装和接线，这里再次提供接线图，是为了方便您编写代码！**

![](media/pjt12.png)

#### 12.5 代码流程图

![](media/project12.png)

#### 12.6 实验代码

⚠️ <span style="color: rgb(255, 76, 65);">特别注意：</span>对于不同的RFID-RC522的白磁卡和蓝色钥匙扣，其白磁卡值和蓝色钥匙扣的值可能都不一样。所以，当使用你自己的白磁卡片靠近RFID-MFRC522刷卡模块的感应区域时，你需要将你在串口监视器窗口中读取对应的白磁卡值(Card UID)更换代码程序中的值 (⚠️ <span style="color: rgb(255, 76, 65);">**特别提醒：需要先上传示例代码至ESP32主控板上，打开串口监视器，设置波特率为115200，白磁卡片靠近RFID-MFRC522刷卡模块的感应区域，可以读取到白磁卡值，将对应的白磁卡值(Card UID)更换代码程序中的值。**</span>)。

![](media/card-value.png)

```c
/*  
 * 项目: RFID door
 * 描述: RFID 控制门
 * 编译IDE：ARDUINO IDE
 * 作者: http//www.keyes-robot.com
*/
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C mylcd(0x27,16,2);
#include <ESP32Servo.h>
Servo myservo;
#include <Wire.h>
#include "MFRC522_I2C.h"
// IIC引脚默认为ESP32的GPIO21和GPIO22
// 0x28是SDA的i2c地址，如果不匹配，请与i2c核对你的地址。
MFRC522 mfrc522(0x28);   // 创建 MFRC522.
#define servoPin  13
#define btnPin 4
boolean btnFlag = 0;

String password = "";

void setup() {
  Serial.begin(115200);           // 初始化和PC的串行通信
  mylcd.init();
  mylcd.backlight();
  Wire.begin();                   // 初始化I2C
  mfrc522.PCD_Init();             // 初始化MFRC522
  ShowReaderDetails();            // 显示PCD - MFRC522读卡机
  Serial.println(F("Scan PICC to see UID, type, and data blocks..."));

  myservo.attach(servoPin);   // 将引脚13上的舵机连接到舵机对象上
  myservo.write(0);
  delay(1000);
  mylcd.setCursor(0, 0);
  mylcd.print("Card");
}

void loop() {
  // 
  if ( ! mfrc522.PICC_IsNewCardPresent() || ! mfrc522.PICC_ReadCardSerial() ) {
    delay(50);
    password = "";
    if(btnFlag == 1)
    {
      boolean btnVal = digitalRead(btnPin);
      if(btnVal == 0)  //如果按下关门按钮（active-low）
      {
        mylcd.setCursor(0, 0);
        mylcd.print("close");
        myservo.write(0);
        delay(1000);
        btnFlag = 0;
      }
    }
    return;
  }
  
  // 选择一张门卡。UID和SAK为mfrc522.uid。
  
  // 保存UID
  Serial.print(F(" Card 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(mfrc522.uid.uidByte[i]);
    password = password + String(mfrc522.uid.uidByte[i]);
    delay(100);
  }
  if(password == "17121741227")  //卡号正确，开门
  {
    mylcd.setCursor(0, 0);
    mylcd.clear();
    mylcd.print("open");
    myservo.write(180);
    delay(1000);
    password = "";
    btnFlag = 1;
  }
  else   //卡号错误，显示错误
  {
    password = "";
    mylcd.setCursor(0, 0);
    mylcd.print("error");
  }
  //Serial.println(password);
}

void ShowReaderDetails() {
  //  获得MFRC522软件
  byte v = mfrc522.PCD_ReadRegister(mfrc522.VersionReg);
  Serial.print(F("MFRC522 Software Version: 0x"));
  Serial.print(v, HEX);
  if (v == 0x91)
    Serial.print(F(" = v1.0"));
  else if (v == 0x92)
    Serial.print(F(" = v2.0"));
  else
    Serial.print(F(" (unknown)"));
  Serial.println("");
  // 返回0x00或0xFF时，可能会导致通信信号传输失败
  if ((v == 0x00) || (v == 0xFF)) {
    Serial.println(F("WARNING: Communication failure, is the MFRC522 properly connected?"));
  }
}
```

#### 12.7 实验结果

按照接线图接好线，外接电源，选择好正确的开发板板型（ESP32 Dev Module）和 适当的串口端口（COMxx），然后单击按钮![](media/cou0.png)上传示例代码至ESP32主控板。示例代码上传成功后，上电后，设置串口波特率为115200，然后将我们提供的白磁卡片靠近(或接触)RFID-MFRC522刷卡模块的感应区域，门就会转动打开，LCD1602显示”open”。然后点击一下木板房子⑦处(左侧)按键1，门转动关闭，LCD1602显示”close”。用另一个蓝色的钥匙扣靠近(或接触)RFID-MFRC522刷卡模块的感应区域，LCD1602显示“error”。

![Img](../../media/image-12.gif)