写点什么

基于 STM32F103 设计的智能门锁 (支持多种开锁解锁方式)

作者:DS小龙哥
  • 2022 年 8 月 20 日
    湖北
  • 本文字数:5867 字

    阅读完需:约 19 分钟

这是基于 STM32 设计的智能锁模型,支持多种开锁方式,支持门禁卡刷卡开锁、蓝牙自动开锁、微信小程序开锁、关锁、使用 RC522 射频卡读卡器、按键开锁、关锁。

一、环境介绍

编程软件: keil5


主控 MCU: STM32F103ZET6


射频卡读写器: RFID-RC522


步进电机: 28BYJ4 4 相 5 线


蓝牙: ATK-HC05


WIFI: ATK-ESP8266


物联网云平台: 采用腾讯云物联网平台,直接支持微信小程序和手机独立 APP 控制

二、功能介绍

这是基于 STM32 设计的智能锁模型,支持多种开锁方式,详情如下:


1. 门禁卡刷卡开锁: 使用 RC522 射频卡读卡器,读取 IC 卡卡号和内部数据,验证身份,开锁。


2. 蓝牙自动开锁: 业主的手机蓝牙在范围内,自动开锁(通过连接蓝牙地址确认业主身份),范围是通过蓝牙断开与连接上为准。


3. 微信小程序开锁、关锁: 通过 ESP8266 连接腾讯云物联网平台,业主可以通过微信小程序“腾讯连连” 进行远程开锁和关锁。


4. 按键开锁、关锁: 可以通过开发板上的按键进行开锁和关锁(模拟物理钥匙而已)


开锁和关锁使用步进电机正转一圈、反转一圈模拟。



三、使用的相关硬件介绍

3.1 STM32F103ZET6 系统板

3.2 HC05 蓝牙模块

3.3 WIFI 模块

3.4 RFID-RC522 模块

3.5 步进电机

四、腾讯物联网平台




五、设备核心源码

 #include "stm32f10x.h" #include "led.h" #include "delay.h" #include "key.h" #include "usart.h" #include <string.h> #include "timer.h" #include "esp8266.h" #include "mqtt.h" #include "hc05_Bluetooth.h" #include "RFID_RC522.h" #include "motor.h" /* 硬件连接方式: ATK-HC-05串口蓝牙模块与STM32的串口2相连接。 PA1--LED 配对状态输出; 配对成功输出高电平,未配对则输出低电平。 PA4---KEY 用于进入 AT 状态;高电平有效(悬空默认为低电平)。 PA2--RXD 模块接收脚 PA3--TXD 模块发送脚 GND---GND 地 VCC---VCC 电源(3.3V~5.0V) ATK-ESP8266串口WIFI模块与STM32的串口3相连接。 PB10--RXD 模块接收脚 PB11--TXD 模块发送脚 GND---GND 地 VCC---VCC 电源(3.3V~5.0V) RC522射频模块外部的接口:     *1--SDA <----->PB5--片选脚 *2--SCK <----->PB4--时钟线 *3--MOSI<----->PA12--输出 *4--MISO<----->PA11--输入 *5--悬空 *6--GND <----->GND *7--RST <----->PA8--复位脚 *8--VCC <----->VCC ULN2003控制28BYJ-48步进电机接线: ULN2003接线: IN4: PC9   d IN3: PC8   c IN2: PC7   b IN1: PC6   a +  : 5V -  : GND */ //腾讯物联网服务器的设备信息 #define MQTT_ClientID "3XM7FNOG4Llock" #define MQTT_UserName "3XM7FNOG4Llock;12010126;W5WOU;1624006004" #define MQTT_PassWord "209f8dfc3079a54540aeb4263e99be24c5b0212141d8067e6348036383535941;hmacsha256" //订阅与发布的主题 #define SET_TOPIC  "$thing/down/property/3XM7FNOG4L/lock"  //订阅 #define POST_TOPIC "$thing/up/property/3XM7FNOG4L/lock"  //发布 #define CONNECT_WIFI  "CMCC-Cqvn"   //将要连接的路由器名称 --不要出现中文、空格等特殊字符 #define CONNECT_PASS "99pu58cb"     //将要连接的路由器密码 #define CONNECT_SERVER_IP "106.55.124.154"  //服务器IP地址 #define CONNECT_SERVER_PORT 1883            //服务器端口号 char mqtt_message[200];//上报数据缓存区 unsigned char SN[4]; //存放读出的卡号 unsigned char CheckSN[4]={71,151,114,179}; //用于验证的卡号--业主的卡号用于开锁 char SendBuff[10]; /* 函数功能: 打印卡号 */ void print_info(unsigned char *p,int cnt) {   int i;     for(i=0;i<cnt;i++)     {         printf("%d ",p[i]);     }     printf("\r\n"); } /* 函数功能: 读卡号--电子标签的卡号 返回值: 1成功 0失败 */ int ReadCardNumber(void) {     unsigned char CT[2];//卡类型     u8 status=1;     status=RC522_PcdRequest(PICC_REQIDL ,CT);//(寻卡模式,卡类型),成功返回0     if(status==MI_OK)//寻卡成功     {        status=MI_ERR;        status=RC522_PcdAnticoll(SN);  //防冲撞,成功返回0,SN是读到卡号的地址                          printf("卡类型:");         print_info(CT,2);//打印类型         printf("卡号:");         print_info(SN,4);//打印卡号          return 1;     }     return 0; } int main() {     u8 esp8266_state=0;     u8 key;     u8 i;     u32 time_cnt=0;     u8 ble_connect_flag=0;     u8 Motor=0; //电机状态          LED_Init();     KEY_Init();     USART1_Init(115200);     RC522_Init();        //RC522      Moto_Init();  //步进电机初始化     USART3_Init(115200);//串口-WIFI     TIMER3_Init(72,20000); //超时时间20ms     USART1_Printf("正在初始化WIFI请稍等.\r\n");          for(i=0;i<5;i++)     {         if(ESP8266_Init()==0)         {            esp8266_state=1;            break;         }         else         {             esp8266_state=0;             USART1_Printf("ESP8266硬件检测错误.\n");           }     }       if(esp8266_state)    {        printf("准备连接服务器....\r\n");                 //非加密端口         USART1_Printf("WIFI:%d\n",ESP8266_STA_TCP_Client_Mode(CONNECT_WIFI,CONNECT_PASS,CONNECT_SERVER_IP,CONNECT_SERVER_PORT,1));                   //2. MQTT协议初始化           MQTT_Init();          //3. 连接服务器           for(i=0;i<5;i++)         {             if(MQTT_Connect(MQTT_ClientID,MQTT_UserName,MQTT_PassWord)==0)             {                 esp8266_state=1;                 break;             }             esp8266_state=0;             USART1_Printf("服务器连接失败,正在重试...\n");             delay_ms(500);         }         USART1_Printf("服务器连接成功.\n");         //3. 订阅主题         if(MQTT_SubscribeTopic(SET_TOPIC,0,1))         {            USART1_Printf("主题订阅失败.\n");         }         else         {            USART1_Printf("主题订阅成功.\n");         }     }             /*4. 初始化HC05串口蓝牙*/     printf("蓝牙正在初始化.........\r\n");     USART2_RX_FLAG=0;     while(HC05_Bluetooth_Init()){}     /*设置当前蓝牙为从机模式---这里设置从机的代码只需要设置一次,后面就可以屏蔽掉了*/ //    HC05_Bluetooth_SetCmd((u8*)"AT+ROLE=0\r\n"); //设置为从机模式 //    if(HC05_Bluetooth_GetRoleStatus()==0)printf("当前蓝牙处于从机状态!\r\n"); //    else if(HC05_Bluetooth_GetRoleStatus()==1)printf("当前蓝牙处于主机状态!\r\n"); //    HC05_Bluetooth_SetCmd((u8*)"AT+RESET\r\n");   //复位ATK-HC05模块     DelayMs(1000);          //等待蓝牙模块稳定            /*2. 查询蓝牙主从状态*/     if(HC05_Bluetooth_GetRoleStatus()==0)printf("2 当前蓝牙处于从机状态!\r\n");     else if(HC05_Bluetooth_GetRoleStatus()==1)printf("2 当前蓝牙处于主机状态!\r\n");     else printf("2 当前蓝牙主从状态查询失败!\r\n");     /*3. 查看蓝牙连接状态*/     if(HC05_LED)printf("3 当前蓝牙连接成功!\r\n");     else printf("3 当前蓝牙未连接!\r\n"); //    /*4. 设置蓝牙的名称*/ //    if(HC05_Bluetooth_SetCmd((u8*)"AT+NAME=WBYQ_HC-05\r\n"))printf("4 蓝牙名称设置失败!\r\n"); //    else printf("4 蓝牙名称设置为 WBYQ_HC-05! \r\n"); //    /*5. 设置蓝牙配对密码*/ //    if(HC05_Bluetooth_SetCmd((u8*)"AT+PSWD=1234\r\n"))printf("5 蓝牙配对密码设置失败!\r\n"); //密码必须是4位 //    else printf("5 蓝牙配对密码设置为 1234 \r\n");               while(1)      {          //按键可以测试开锁和关锁         key=KEY_Scan(0);         if(key==1)         {             LED1=0;  //亮灯--表示开锁             time_cnt=0;             Motorcw_ring(1,300);   //电机正转1圈                          Motor=1;             //更新微信小程序             sprintf(mqtt_message,"{"method":"report","clientToken":"123","params":{"Motor":%d}}",Motor);             MQTT_PublishData(POST_TOPIC,mqtt_message,0);             USART1_Printf("更新门锁状态:开锁\r\n");         }         else if(key==2)         {             LED1=1;  //灭灯--表示关锁             time_cnt=0;             Motorccw_ring(1,300);  //电机反转1圈              Motor=0;             //更新微信小程序             sprintf(mqtt_message,"{"method":"report","clientToken":"123","params":{"Motor":%d}}",Motor);             MQTT_PublishData(POST_TOPIC,mqtt_message,0);             USART1_Printf("更新门锁状态:关锁\r\n");            }          DelayMs(10);         time_cnt++;         if(time_cnt>=50)         {             time_cnt=0;             LED2=!LED2;         }                       //微信小程序开锁方式: 接收WIFI返回的数据         if(USART3_RX_FLAG)         {             USART3_RX_BUFFER[USART3_RX_CNT]='\0';                          printf("UART3收到数据.....\r\n");             //向串口打印微信小程序返回的数据             for(i=0;i<USART3_RX_CNT;i++)             {                 USART1_Printf("%c",USART3_RX_BUFFER[i]);             }                          //如果是下发了属性,判断是开锁还是关锁             if(USART3_RX_CNT>5)             {                 //使用字符串查找函数                 //开锁                 if(strstr((char*)&USART3_RX_BUFFER[5],""Motor":1"))                 {                     LED1=0;  //亮灯--表示开锁                      //开锁                     //执行开锁代码--电机正转                     Motorcw_ring(1,300);   //电机正转1圈                      Motor=1;                 }                 //关锁                 else if(strstr((char*)&USART3_RX_BUFFER[5],""Motor":0"))                 {                     LED1=1;  //灭灯--表示关锁                                          //关锁                     //执行开锁代码--电机反转                    Motorccw_ring(1,300);  //电机反转1圈                      Motor=0;                 }             }                         USART3_RX_CNT=0;             USART3_RX_FLAG=0;         }                         //RC522开锁方式:  读取IC卡号         if(ReadCardNumber())         {             sprintf(SendBuff,"%x%x%x%x\r\n",SN[0],SN[1],SN[2],SN[3]);                           //比较卡号是否是业主的卡号,决定是否需要开锁             int i=0;             for(i=0;i<4;i++)             {                 if(CheckSN[i]!=SN[i])break;             }                          //如果是业主,就开锁             if(i==4)             {                  LED1=0;  //亮灯--表示开锁                                  //更新微信小程序                 sprintf(mqtt_message,"{"method":"report","clientToken":"123","params":{"Motor":%d}}",Motor);                 MQTT_PublishData(POST_TOPIC,mqtt_message,0);                 USART1_Printf("更新门锁状态:开锁\r\n");                                    Motor=1;                  //执行开锁代码--电机正转                  Motorcw_ring(1,300);   //电机正转1圈                   }         }                           if(USART2_RX_FLAG)         {             USART2_RX_BUFFER[USART2_RX_CNT]='\0';             USART1_Printf("蓝牙:%s\r\n",USART2_RX_BUFFER);             USART2_RX_CNT=0;             USART2_RX_FLAG=0;         }                  //蓝牙解锁方式: 离开范围就自动关锁   连接上就自动解锁         // 区分业主身份方式: 使用蓝牙的配对密码区分.         if(HC05_LED==1 && Motor==0) //关锁状态才需要开始         {             LED1=0;  //亮灯--表示开锁             ble_connect_flag=1; //表示蓝牙已经连接过             printf("蓝牙已经连接.\r\n");              Motor=1;                          //更新微信小程序             sprintf(mqtt_message,"{"method":"report","clientToken":"123","params":{"Motor":%d}}",Motor);             MQTT_PublishData(POST_TOPIC,mqtt_message,0);             USART1_Printf("更新门锁状态:开锁\r\n");                            //开锁             //执行开锁代码--电机正转             Motorcw_ring(1,300);   //电机正转1圈         }               else         {             //之前蓝牙连接过             if(ble_connect_flag)             {                 ble_connect_flag=0; //清除标记                 LED1=1;  //关灯--表示上锁                 printf("蓝牙已经断开.\r\n");                 Motor=0;                 //关锁                 //执行开锁代码--电机反转                 Motorccw_ring(1,300);  //电机反转1圈                 //更新微信小程序                 sprintf(mqtt_message,"{"method":"report","clientToken":"123","params":{"Motor":%d}}",Motor);                 MQTT_PublishData(POST_TOPIC,mqtt_message,0);                 USART1_Printf("更新门锁状态:关锁\r\n");             }            }      } }
复制代码


发布于: 刚刚阅读数: 4
用户头像

DS小龙哥

关注

之所以觉得累,是因为说的比做的多。 2022.01.06 加入

熟悉C/C++、51单片机、STM32、Linux应用开发、Linux驱动开发、音视频开发、QT开发. 目前已经完成的项目涉及音视频、物联网、智能家居、工业控制领域

评论

发布
暂无评论
基于STM32F103设计的智能门锁(支持多种开锁解锁方式)_8月月更_DS小龙哥_InfoQ写作社区