前言

班级的小教室使用刷卡开门,但小教室的门禁学生卡没有录入故只有教师才能开门,所以想要到小教室自习十分不便。想到用舵机牵引,上网搜索发现已有案例分享但全网并没有找到单基于 ESP32 与 RC522 的简易方案,于是自己动手丰衣足食,遂出此文分享。

准备

文中涉及到的设备以及环境是
ESP32-WROOM-32D 推荐 CH9102X 芯片,免驱
SG5010 舵机
ESP32 38Pin 拓展版 当然只是为了后续接线与固定在门上方便为主,不加或者使用面包板也可以
杜邦线
MFRC-522 射频模块
Arduino IDE

Arduino IDE 环境配置

首先去 IDE File-Preferences 首选项最后一行添加链接 https://ghproxy.com/https://raw.githubusercontent.com/espressif/arduino-esp32/gh-pages/package_esp32_index.json
再到 Boards Manager 搜索 esp32 安装,可能会安装出错或者后续编译有莫名其妙的报错,换个版本安装一般能够解决。
这时可以基础编译适配 ESP32,但我们还有 MFRC-522 模块与舵机,所以需要添加库,在 library Manager 搜索 MFRC-522 安装即可,再搜索 ESP32Servo 安装即可。需要注意的是,单搜索 Servo 安装的库不能支持 ESP32,碰到下载 ESP32Servo 依旧报错的可以到 Github 上下下来再到 C:\Users\ 用户名 \AppData\Local\Arduino15\libraries\Servo 替换文件,Github 上的名称是 ESP32_Servo 需要将文件名以及文件内部所有类似名字替换为 Servo 即可。

串口引脚连接

RC522 引脚名称

ESP32 引脚名称

3.3V

3V3

RST

27

GND

GND

MISO

19

MOSI

23

SCK

18

SDA/SS

12

舵机引脚颜色

ESP32 引脚名称

橙色

13

红色

5V

棕色

GND

编写程序

连接好引脚后就进入编写程序的环节。

//Libraries
#include <SPI.h>//https://www.arduino.cc/en/reference/SPI
#include <MFRC522.h>//https://github.com/miguelbalboa/rfid
#include <Servo.h>
#include <string.h>
#include <math.h>
//Constants
#define SS_PIN 12
#define RST_PIN 27
#define SERVO_PIN 13
//Servo
Servo servoMotor;
//Parameters
const int ipaddress[4] = {103, 97, 67, 25};
//
int decid=0;
int i=0;
//Variables
byte nuidPICC[4] = {0, 0, 0, 0};
MFRC522::MIFARE_Key key;
MFRC522 rfid = MFRC522(SS_PIN, RST_PIN);

void setup() {
  //Init Serial USB
  Serial.begin(115200);//这里在串口监视器(Serial Monitor)旁边数值要调成一样
  Serial.println("welcome!");
  Serial.println(F("Initialize System"));
  //init rfid D8,D5,D6,D7
  SPI.begin();
  rfid.PCD_Init();
  Serial.print(F("Reader :"));
  rfid.PCD_DumpVersionToSerial();
  // attaches the servo on ESP32 pin
  servoMotor.attach(SERVO_PIN);
  servoMotor.write(0);
}

void loop() {
  readRFID();
  switch(decid){
    case 869660://white 这里填写读卡器读到卡后的在串口监视器(Serial Monitor)上显示的decid数字
    Serial.println("Pass!");
    servoMotor.write(180);   //舵机转180度
    delay(3500);
    servoMotor.write(0);
    break;
  }
  decid=0;
  delay(1000);
}

void readRFID(void ) { /* function readRFID */
  ////Read RFID card
  unsigned char status;   //状态变量
  unsigned char str[5];
  for (byte i = 0; i < 6; i++) {
    key.keyByte[i] = 0xFF;
  }
  // Look for new 1 cards
  if ( ! rfid.PICC_IsNewCardPresent())
    return;

  // Verify if the NUID has been readed
  if (  !rfid.PICC_ReadCardSerial())
    return;

  // Store NUID into nuidPICC array
  for (byte i = 0; i < 4; i++) {
    nuidPICC[i] = rfid.uid.uidByte[i];
  }
  unsigned char* id = nuidPICC;
  decid=0;
  for(i=0;i<4;i++) {  
    decid=decid+id[i]*pow(16,i);    //16转10进制
  }
  Serial.print(F("RFID In dec: "));
  printDec(rfid.uid.uidByte, rfid.uid.size);
  Serial.println();
  Serial.print("DECID:");
  Serial.println(decid);   //输出卡DECID,10进制
  // 如果传感器/读卡器上没有新卡,则返回主程序。这将在空闲时保存整个进程。
  if ( ! rfid.PICC_IsNewCardPresent())
   return;
  // Halt PICC
  rfid.PICC_HaltA();

  // Stop encryption on PCD
  rfid.PCD_StopCrypto1();
  
  
}


/**
   Helper routine to dump a byte array as hex values to Serial.
*/
/**void printHex(byte *buffer, byte bufferSize) {
  for (byte i = 0; i < bufferSize; i++) {
    Serial.print(buffer[i] < 0x10 ? " 0" : " ");
    Serial.print(buffer[i], HEX);
  }
}
*/
/**
   Helper routine to dump a byte array as dec values to Serial.
*/
void printDec(byte *buffer, byte bufferSize) {
  for (byte i = 0; i < bufferSize; i++) {
    Serial.print(buffer[i] < 0x10 ? " 0" : " ");
    Serial.print(buffer[i], DEC);
  }
}

程序烧录

选择 ESP32 Dev Module,选择正确的串口
Upload 一下
接着打开 Monitor,刷卡,添加程序中 switch 语句的 case
大概效果如下图,当时没写 decid,大致看一下屏幕截图 2023-05-02 122213.png

实践

经过粗略测量,在门把手斜下方用热熔胶固定,再限位器粘在在舵机上方避免热熔胶纵向受力直接脱落。将 rc522 模块穿过门缝粘在外面。用线将门把手与舵机连接,最终实现了门外刷卡控制门内舵机向下转动拉动门把手实现开门的效果。

遇到的问题

最后效果近乎完美,广受师生好评,暂时无图。但目前采用的供电方式是使用充电宝低电流模式供电,貌似经过三个小时其依旧会自动断电,打算更换两个干电池盒试试,3V 独立给 ESP 供电,6V 独立给舵机供电。
不知是否可行。

总之到这里,整个奇妙探索旅程就结束了,总共历时半个月,总成本五十多。