我是靠谱客的博主 感动毛豆,最近开发中收集的这篇文章主要介绍实训9——门磁报警实验九:门磁报警,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

实验九:门磁报警

一、实验目的

通过门磁传感器,判断三种开门方式
1、正常开门,就是有正常开门方式,例指纹开门、蓝牙开门后,主人打开门,触发门磁
2、门未关好:在正常开门后,主人没有即使关门,会引发门未关好报警
3、有人撬门:非正常开门,即没有正常开门指令,门磁状态就发送变化算有人撬门的情况,触发撬门报警

二、实验内容

1.连接ESP32与门磁的引脚,另一引脚接地
2.将程序上传到ESP32
3.打开串口调试助手,分别以不同方式触发门磁,观察串口输出的消息

三、实验设备

门磁
ESP32开发板
杜邦线

四、实验步骤

1)连接引脚

RC522:

RC522的引脚:
在这里插入图片描述
引脚依次为:SDA SCK MOSI MISO SCL GND RST 3.3V

ESP32:

ESP32的引脚图:
ESP32

连接:

将RC522与ESP32上对应的引脚连接:
在这里插入图片描述

2)上传程序

程序中需要MFRC522的库,在arduino上方工具->管理库中搜索MFRC522下载库

#include <dummy.h>
#include <Servo.h>
#include <BLEDevice.h>
#include <BLE2902.h>
#include <String.h>
#include <Keypad.h>
#include <SPI.h>
#include <MFRC522.h> 
#define SS_PIN 21  //定义RC522的SDA引脚的接线位置
#define RST_PIN 22  //定义RC522的RST引脚的接线位置
#define SERVO_PIN 15
#define NormolClose 13

#define SERVICE_UUID           "6E400001-B5A3-F393-E0A9-E50E24DCCA9E"   
#define CHARACTERISTIC_UUID_RX "6E400002-B5A3-F393-E0A9-E50E24DCCA9E"
#define CHARACTERISTIC_UUID_TX "6E400003-B5A3-F393-E0A9-E50E24DCCA9E"
#define openInterval  5000
BLECharacteristic *pCharacteristic;
bool deviceConnected = false; 
/*
 * 按键
*/
const byte ROWS = 4; //four rows
const byte COLS = 3; //three columns
char keys[ROWS][COLS] = {
  {'1','2','3'},
  {'4','5','6'},
  {'7','8','9'},
  {'*','0','#'}
};
byte rowPins[ROWS] = {33, 27, 14, 12}; //connect to the row pinouts of the keypad
byte colPins[COLS] = {4, 0, 2}; //connect to the column pinouts of the keypad
/*
 * RFID标签结构体
 */
struct RFIDTag {  //Tag标签结构体
  uint8_t uid[4];
  char *name;
};
MFRC522 rfid(SS_PIN, RST_PIN); //实例化类 
struct RFIDTag tags[20] = {  // 初始化结构资料,请自行修改RFID识别码
  {{233, 232, 210, 126}, "Mini_Tag"},
  {{0, 0, 0, 0}, "Mini_Tag1"}, 
  {{1, 1, 1, 1}, "Mini_Tag2"}, 
};
byte totalTags = sizeof(tags) / sizeof(RFIDTag);  //计算结构资料的数量
bool door_open_flag; //开门动作标志位
bool alarm_flag;
static bool lock_back_flag=false; //回锁标志位
Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );
byte ble_rx_buffer[20]; //接收蓝牙指令
byte verfi_code[6] = {0x31,0x32,0x33,0x34,0x35,0x36};//初始密码
byte init_pw[6] = {1,2,3,4,5,6};//初始按键密码
Servo myservo;
int pos=0;
bool toggle; //开锁判断位
void locker(bool toggle) { //开锁
  myservo.attach(SERVO_PIN); 
  if (toggle) {
    myservo.write(90); // 开锁
  } else {
    myservo.write(0); // 关锁
  }
  delay(500); // 等马达转到定位
  myservo.detach();
}
class MyServerCallbacks: public BLEServerCallbacks {
    void onConnect(BLEServer* pServer) {
      deviceConnected = true;
    };
    void onDisconnect(BLEServer* pServer) {
      deviceConnected = false;
    }
};
//55aa1000313233343536 蓝牙发送开门指令,hex 16进制发送
class MyCallbacks: public BLECharacteristicCallbacks {
    void onWrite(BLECharacteristic *pCharacteristic) {
      std::string rxValue = pCharacteristic->getValue(); 
      byte op;
      for (int i = 0; i < rxValue.length(); i++){
          ble_rx_buffer[i] = rxValue[i];
          Serial.print(rxValue[i]);
       }
       if(ble_rx_buffer[0] == 0x55 && ble_rx_buffer[1] == 0xaa){
            op=ble_rx_buffer[2];
       
       switch(op){
        case 0x10:{ //蓝牙开门
          if(memcmp(ble_rx_buffer+4,verfi_code,6) == 0){ //匹配成功
             toggle = true;  
             Serial.println("开门成功");     
          }
          else{
            Serial.println("密码错误");
          }
          break;
        }
        case 0x20:{ //设置密码
          break;
        }
        case 0x30:{ //查看指纹
          break;
        }
        case 0x31:{//添加指纹
          break;
        }
        case 0x32:{ //删除指纹
          break;
        }
       }
       //locker(toggle);
     }
    }
};
/*配置蓝牙
 * 参数:BLEName 蓝牙名字
*/
void setupBLE(String BLEName){           
  const char *ble_name = BLEName.c_str();       
  BLEDevice::init(ble_name);                    
  BLEServer *pServer = BLEDevice::createServer(); //创建服务
  pServer->setCallbacks(new MyServerCallbacks());
  BLEService *pService = pServer->createService(SERVICE_UUID);    
  pCharacteristic = pService->createCharacteristic(CHARACTERISTIC_UUID_TX,BLECharacteristic::PROPERTY_NOTIFY);  
  pCharacteristic->addDescriptor(new BLE2902());  //添加描述
  BLECharacteristic *pCharacteristic = pService->createCharacteristic(CHARACTERISTIC_UUID_RX,BLECharacteristic::PROPERTY_WRITE);
  pCharacteristic->setCallbacks(new MyCallbacks());  //receive message callback  
  pService->start();// Start the service
  pServer->getAdvertising()->start();// Start advertising
  Serial.println("Waiting a client connection to notify...");
}
/*按键输入的匹配函数
 * 参数:key为一次按键输入的值
*/
bool compare_pw(char key){
  static byte pw[20];
  static byte keys_len = 0;
  bool pw_flag = false; //匹配密码的标志位
  if(key){
    Serial.println(key);
    switch(key){
      case '#':{ //确认键
        if(keys_len == 6 && memcmp(pw,init_pw,6)==0){  //匹配成功,开锁
            Serial.println("开门成功");
            pw_flag = true; 
        }
        else{
          Serial.println("密码错误");
        }
        keys_len=0; //清零
        break;
      }
      case '*':{ //回退键
        if(keys_len >0)
          keys_len--;
        break;
      }
      default:{ //默认数字键0-9
        pw[keys_len++]=key-'0';
        if(keys_len>19){
          Serial.println("OverSize");
          keys_len=0;
        }
        break;
      }
    }
  }
  return pw_flag;
}
void printDec(byte *buffer, byte bufferSize) {
  for (byte i = 0; i < bufferSize; i++){
    //Serial.print(buffer[i] < 0x10 ? " 0" : "");
    Serial.print(buffer[i]);
    Serial.print(" ");
  }
}
/*
 * RFID匹配函数
 * 参数:card_num为卡片资料的总数
*/
bool Match_Card(byte card_num){ 
  bool foundTag = false;    //是否找到记录中的标签,初始是false
  if (rfid.PICC_IsNewCardPresent() && rfid.PICC_ReadCardSerial()) { //寻找新卡
    byte *id = rfid.uid.uidByte;   // 取得卡片的UID
    byte idSize = rfid.uid.size;   // 取得UID的长度
    Serial.print("十进制UID:");
    printDec(rfid.uid.uidByte, rfid.uid.size);
    Serial.println();
    for (byte i = 0; i < card_num; i++) {
    if (memcmp(tags[i].uid, id, idSize) == 0) {  // 比对阵列资料值
          Serial.println(tags[i].name);  //显示标签名字
          foundTag = true;
          break;
      }
     if(i==card_num-1){
        Serial.println("验证失败");  
     }
   }
  
    // 使放置在读卡区的IC卡进入休眠状态,不再重复读卡
    rfid.PICC_HaltA();
    // 停止读卡模块编码
    rfid.PCD_StopCrypto1(); 
  }
  return foundTag;
}
/*门磁中断函数
 * 参数 open_flag:正常开门的标志位
*/
void handleInterrupt() {
  delay(100);
  if (digitalRead(NormolClose)){// 电平高,门开
      detachInterrupt(digitalPinToInterrupt(NormolClose)); //屏蔽中断脚位
      door_open_flag = 1;  
      if(!lock_back_flag){//门没在开锁时间,门磁变化,算撬门报警
        alarm_flag = 1;  
      }    
    //Serial.println("door open");
  }
}
void setup() { 
  Serial.begin(115200);
  setupBLE("ESP32 Device");//设置蓝牙名称
  myservo.attach(SERVO_PIN); //引脚12为PWM脚  
  SPI.begin(); // 初始化SPI总线
  rfid.PCD_Init(); // 初始化 MFRC522
  pinMode(NormolClose, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(NormolClose), handleInterrupt, RISING); 
}
void loop() {
  static unsigned long toggle_time = millis();
    if (!digitalRead(NormolClose)){ //电平低,门关
    attachInterrupt(digitalPinToInterrupt(NormolClose), handleInterrupt, RISING); // 设置中断脚位,检测下降沿电压
    door_open_flag = 0; 
  }
  if(compare_pw(keypad.getKey()) || Match_Card(totalTags)){ //密码正确 or 刷卡成功
    toggle = true;
    alarm_flag = false; //解除报警
  }
  if(toggle){ //开门
    locker(toggle); //开锁
    toggle = false;
    lock_back_flag = true;
    toggle_time = millis();
  }
  if(millis() - toggle_time > openInterval && lock_back_flag){  //回锁时间5s
    lock_back_flag = false;
    locker(toggle);//回锁
  }
  //报警信息:1、门未关好 2、有人撬门
  if(!lock_back_flag && door_open_flag){//关锁 and 门的状态是开
    if(alarm_flag){ //非法撬门
      Serial.println("非法撬门");
    }
    else{ //门未关好
      Serial.println("门未关好");
    }
  } 
}

3)三种方式开门

1、正常开门,就是有正常开门方式,例指纹开门、蓝牙开门、刷卡开门后,主人打开门,触发门磁
2、门未关好:在正常开门后,主人没有即使关门,会引发门未关好报警,串口输出门未关好
3、有人撬门:非正常开门,即没有正常开门指令,门磁状态就发送变化算有人撬门的情况,触发撬门报警,串口输出非法撬门
在这里插入图片描述

五、其他问题

最后

以上就是感动毛豆为你收集整理的实训9——门磁报警实验九:门磁报警的全部内容,希望文章能够帮你解决实训9——门磁报警实验九:门磁报警所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(59)

评论列表共有 0 条评论

立即
投稿
返回
顶部