飞道的博客

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

362人阅读  评论(0)

一、环境介绍

编程软件: keil5

主控MCU: STM32F103ZET6

射频卡读写器: RFID-RC522

步进电机: 28BYJ4  4相5线

蓝牙:  ATK-HC05

WIFI: ATK-ESP8266

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

完整项目源码下载地址: https://download.csdn.net/download/xiaolong1126626497/19101807

 

二、功能介绍

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

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

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

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

如果没有使用过腾讯云物联网平台的,可以看这里:https://blog.csdn.net/xiaolong1126626497/article/details/116902653

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

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

三、使用的相关硬件介绍

3.1  STM32F103ZET6系统板

3.2 HC05蓝牙模块

3.3 WIFI模块

3.4 RFID-RC522模块

3.5 步进电机

四、腾讯物联网平台

没有使用过物联网云平台的参考这里: https://blog.csdn.net/xiaolong1126626497/article/details/116902653

五、设备核心源码


  
  1. #include "stm32f10x.h"
  2. #include "led.h"
  3. #include "delay.h"
  4. #include "key.h"
  5. #include "usart.h"
  6. #include <string.h>
  7. #include "timer.h"
  8. #include "esp8266.h"
  9. #include "mqtt.h"
  10. #include "hc05_Bluetooth.h"
  11. #include "RFID_RC522.h"
  12. #include "motor.h"
  13. /*
  14. 硬件连接方式:
  15. ATK-HC-05串口蓝牙模块与STM32的串口2相连接。
  16. PA1--LED 配对状态输出; 配对成功输出高电平,未配对则输出低电平。
  17. PA4---KEY 用于进入 AT 状态;高电平有效(悬空默认为低电平)。
  18. PA2--RXD 模块接收脚
  19. PA3--TXD 模块发送脚
  20. GND---GND 地
  21. VCC---VCC 电源(3.3V~5.0V)
  22. ATK-ESP8266串口WIFI模块与STM32的串口3相连接。
  23. PB10--RXD 模块接收脚
  24. PB11--TXD 模块发送脚
  25. GND---GND 地
  26. VCC---VCC 电源(3.3V~5.0V)
  27. RC522射频模块外部的接口:
  28. *1--SDA <----->PB5--片选脚
  29. *2--SCK <----->PB4--时钟线
  30. *3--MOSI<----->PA12--输出
  31. *4--MISO<----->PA11--输入
  32. *5--悬空
  33. *6--GND <----->GND
  34. *7--RST <----->PA8--复位脚
  35. *8--VCC <----->VCC
  36. ULN2003控制28BYJ-48步进电机接线:
  37. ULN2003接线:
  38. IN4: PC9 d
  39. IN3: PC8 c
  40. IN2: PC7 b
  41. IN1: PC6 a
  42. + : 5V
  43. - : GND
  44. */
  45. //腾讯物联网服务器的设备信息
  46. #define MQTT_ClientID "3XM7FNOG4Llock"
  47. #define MQTT_UserName "3XM7FNOG4Llock;12010126;W5WOU;1624006004"
  48. #define MQTT_PassWord "209f8dfc3079a54540aeb4263e99be24c5b0212141d8067e6348036383535941;hmacsha256"
  49. //订阅与发布的主题
  50. #define SET_TOPIC "$thing/down/property/3XM7FNOG4L/lock" //订阅
  51. #define POST_TOPIC "$thing/up/property/3XM7FNOG4L/lock" //发布
  52. #define CONNECT_WIFI "CMCC-Cqvn" //将要连接的路由器名称 --不要出现中文、空格等特殊字符
  53. #define CONNECT_PASS "99pu58cb" //将要连接的路由器密码
  54. #define CONNECT_SERVER_IP "106.55.124.154" //服务器IP地址
  55. #define CONNECT_SERVER_PORT 1883 //服务器端口号
  56. char mqtt_message[ 200]; //上报数据缓存区
  57. unsigned char SN[ 4]; //存放读出的卡号
  58. unsigned char CheckSN[ 4]={ 71, 151, 114, 179}; //用于验证的卡号--业主的卡号用于开锁
  59. char SendBuff[ 10];
  60. /*
  61. 函数功能: 打印卡号
  62. */
  63. void print_info(unsigned char *p,int cnt)
  64. {
  65. int i;
  66. for(i= 0;i<cnt;i++)
  67. {
  68. printf( "%d ",p[i]);
  69. }
  70. printf( "\r\n");
  71. }
  72. /*
  73. 函数功能: 读卡号--电子标签的卡号
  74. 返回值: 1成功 0失败
  75. */
  76. int ReadCardNumber(void)
  77. {
  78. unsigned char CT[ 2]; //卡类型
  79. u8 status= 1;
  80. status=RC522_PcdRequest(PICC_REQIDL ,CT); //(寻卡模式,卡类型),成功返回0
  81. if(status==MI_OK) //寻卡成功
  82. {
  83. status=MI_ERR;
  84. status=RC522_PcdAnticoll(SN); //防冲撞,成功返回0,SN是读到卡号的地址
  85. printf( "卡类型:");
  86. print_info(CT, 2); //打印类型
  87. printf( "卡号:");
  88. print_info(SN, 4); //打印卡号
  89. return 1;
  90. }
  91. return 0;
  92. }
  93. int main()
  94. {
  95. u8 esp8266_state= 0;
  96. u8 key;
  97. u8 i;
  98. u32 time_cnt= 0;
  99. u8 ble_connect_flag= 0;
  100. u8 Motor= 0; //电机状态
  101. LED_Init();
  102. KEY_Init();
  103. USART1_Init( 115200);
  104. RC522_Init(); //RC522
  105. Moto_Init(); //步进电机初始化
  106. USART3_Init( 115200); //串口-WIFI
  107. TIMER3_Init( 72, 20000); //超时时间20ms
  108. USART1_Printf( "正在初始化WIFI请稍等.\r\n");
  109. for(i= 0;i< 5;i++)
  110. {
  111. if(ESP8266_Init()== 0)
  112. {
  113. esp8266_state= 1;
  114. break;
  115. }
  116. else
  117. {
  118. esp8266_state= 0;
  119. USART1_Printf( "ESP8266硬件检测错误.\n");
  120. }
  121. }
  122. if(esp8266_state)
  123. {
  124. printf( "准备连接服务器....\r\n");
  125. //非加密端口
  126. USART1_Printf( "WIFI:%d\n",ESP8266_STA_TCP_Client_Mode(CONNECT_WIFI,CONNECT_PASS,CONNECT_SERVER_IP,CONNECT_SERVER_PORT, 1));
  127. //2. MQTT协议初始化
  128. MQTT_Init();
  129. //3. 连接服务器
  130. for(i= 0;i< 5;i++)
  131. {
  132. if(MQTT_Connect(MQTT_ClientID,MQTT_UserName,MQTT_PassWord)== 0)
  133. {
  134. esp8266_state= 1;
  135. break;
  136. }
  137. esp8266_state= 0;
  138. USART1_Printf( "服务器连接失败,正在重试...\n");
  139. delay_ms( 500);
  140. }
  141. USART1_Printf( "服务器连接成功.\n");
  142. //3. 订阅主题
  143. if(MQTT_SubscribeTopic(SET_TOPIC, 0, 1))
  144. {
  145. USART1_Printf( "主题订阅失败.\n");
  146. }
  147. else
  148. {
  149. USART1_Printf( "主题订阅成功.\n");
  150. }
  151. }
  152. /*4. 初始化HC05串口蓝牙*/
  153. printf( "蓝牙正在初始化.........\r\n");
  154. USART2_RX_FLAG= 0;
  155. while(HC05_Bluetooth_Init()){}
  156. /*设置当前蓝牙为从机模式---这里设置从机的代码只需要设置一次,后面就可以屏蔽掉了*/
  157. // HC05_Bluetooth_SetCmd((u8*)"AT+ROLE=0\r\n"); //设置为从机模式
  158. // if(HC05_Bluetooth_GetRoleStatus()==0)printf("当前蓝牙处于从机状态!\r\n");
  159. // else if(HC05_Bluetooth_GetRoleStatus()==1)printf("当前蓝牙处于主机状态!\r\n");
  160. // HC05_Bluetooth_SetCmd((u8*)"AT+RESET\r\n"); //复位ATK-HC05模块
  161. DelayMs( 1000); //等待蓝牙模块稳定
  162. /*2. 查询蓝牙主从状态*/
  163. if(HC05_Bluetooth_GetRoleStatus()== 0) printf( "2 当前蓝牙处于从机状态!\r\n");
  164. else if(HC05_Bluetooth_GetRoleStatus()== 1) printf( "2 当前蓝牙处于主机状态!\r\n");
  165. else printf( "2 当前蓝牙主从状态查询失败!\r\n");
  166. /*3. 查看蓝牙连接状态*/
  167. if(HC05_LED) printf( "3 当前蓝牙连接成功!\r\n");
  168. else printf( "3 当前蓝牙未连接!\r\n");
  169. // /*4. 设置蓝牙的名称*/
  170. // if(HC05_Bluetooth_SetCmd((u8*)"AT+NAME=WBYQ_HC-05\r\n"))printf("4 蓝牙名称设置失败!\r\n");
  171. // else printf("4 蓝牙名称设置为 WBYQ_HC-05! \r\n");
  172. // /*5. 设置蓝牙配对密码*/
  173. // if(HC05_Bluetooth_SetCmd((u8*)"AT+PSWD=1234\r\n"))printf("5 蓝牙配对密码设置失败!\r\n"); //密码必须是4位
  174. // else printf("5 蓝牙配对密码设置为 1234 \r\n");
  175. while( 1)
  176. {
  177. //按键可以测试开锁和关锁
  178. key=KEY_Scan( 0);
  179. if(key== 1)
  180. {
  181. LED1= 0; //亮灯--表示开锁
  182. time_cnt= 0;
  183. Motorcw_ring( 1, 300); //电机正转1圈
  184. Motor= 1;
  185. //更新微信小程序
  186. sprintf(mqtt_message, "{\"method\":\"report\",\"clientToken\":\"123\",\"params\":{\"Motor\":%d}}",Motor);
  187. MQTT_PublishData(POST_TOPIC,mqtt_message, 0);
  188. USART1_Printf( "更新门锁状态:开锁\r\n");
  189. }
  190. else if(key== 2)
  191. {
  192. LED1= 1; //灭灯--表示关锁
  193. time_cnt= 0;
  194. Motorccw_ring( 1, 300); //电机反转1圈
  195. Motor= 0;
  196. //更新微信小程序
  197. sprintf(mqtt_message, "{\"method\":\"report\",\"clientToken\":\"123\",\"params\":{\"Motor\":%d}}",Motor);
  198. MQTT_PublishData(POST_TOPIC,mqtt_message, 0);
  199. USART1_Printf( "更新门锁状态:关锁\r\n");
  200. }
  201. DelayMs( 10);
  202. time_cnt++;
  203. if(time_cnt>= 50)
  204. {
  205. time_cnt= 0;
  206. LED2=!LED2;
  207. }
  208. //微信小程序开锁方式: 接收WIFI返回的数据
  209. if(USART3_RX_FLAG)
  210. {
  211. USART3_RX_BUFFER[USART3_RX_CNT]= '\0';
  212. printf( "UART3收到数据.....\r\n");
  213. //向串口打印微信小程序返回的数据
  214. for(i= 0;i<USART3_RX_CNT;i++)
  215. {
  216. USART1_Printf( "%c",USART3_RX_BUFFER[i]);
  217. }
  218. //如果是下发了属性,判断是开锁还是关锁
  219. if(USART3_RX_CNT> 5)
  220. {
  221. //使用字符串查找函数
  222. //开锁
  223. if( strstr(( char*)&USART3_RX_BUFFER[ 5], "\"Motor\":1"))
  224. {
  225. LED1= 0; //亮灯--表示开锁
  226. //开锁
  227. //执行开锁代码--电机正转
  228. Motorcw_ring( 1, 300); //电机正转1圈
  229. Motor= 1;
  230. }
  231. //关锁
  232. else if( strstr(( char*)&USART3_RX_BUFFER[ 5], "\"Motor\":0"))
  233. {
  234. LED1= 1; //灭灯--表示关锁
  235. //关锁
  236. //执行开锁代码--电机反转
  237. Motorccw_ring( 1, 300); //电机反转1圈
  238. Motor= 0;
  239. }
  240. }
  241. USART3_RX_CNT= 0;
  242. USART3_RX_FLAG= 0;
  243. }
  244. //RC522开锁方式: 读取IC卡号
  245. if(ReadCardNumber())
  246. {
  247. sprintf(SendBuff, "%x%x%x%x\r\n",SN[ 0],SN[ 1],SN[ 2],SN[ 3]);
  248. //比较卡号是否是业主的卡号,决定是否需要开锁
  249. int i= 0;
  250. for(i= 0;i< 4;i++)
  251. {
  252. if(CheckSN[i]!=SN[i]) break;
  253. }
  254. //如果是业主,就开锁
  255. if(i== 4)
  256. {
  257. LED1= 0; //亮灯--表示开锁
  258. //更新微信小程序
  259. sprintf(mqtt_message, "{\"method\":\"report\",\"clientToken\":\"123\",\"params\":{\"Motor\":%d}}",Motor);
  260. MQTT_PublishData(POST_TOPIC,mqtt_message, 0);
  261. USART1_Printf( "更新门锁状态:开锁\r\n");
  262. Motor= 1;
  263. //执行开锁代码--电机正转
  264. Motorcw_ring( 1, 300); //电机正转1圈
  265. }
  266. }
  267. if(USART2_RX_FLAG)
  268. {
  269. USART2_RX_BUFFER[USART2_RX_CNT]= '\0';
  270. USART1_Printf( "蓝牙:%s\r\n",USART2_RX_BUFFER);
  271. USART2_RX_CNT= 0;
  272. USART2_RX_FLAG= 0;
  273. }
  274. //蓝牙解锁方式: 离开范围就自动关锁 连接上就自动解锁
  275. // 区分业主身份方式: 使用蓝牙的配对密码区分.
  276. if(HC05_LED== 1 && Motor== 0) //关锁状态才需要开始
  277. {
  278. LED1= 0; //亮灯--表示开锁
  279. ble_connect_flag= 1; //表示蓝牙已经连接过
  280. printf( "蓝牙已经连接.\r\n");
  281. Motor= 1;
  282. //更新微信小程序
  283. sprintf(mqtt_message, "{\"method\":\"report\",\"clientToken\":\"123\",\"params\":{\"Motor\":%d}}",Motor);
  284. MQTT_PublishData(POST_TOPIC,mqtt_message, 0);
  285. USART1_Printf( "更新门锁状态:开锁\r\n");
  286. //开锁
  287. //执行开锁代码--电机正转
  288. Motorcw_ring( 1, 300); //电机正转1圈
  289. }
  290. else
  291. {
  292. //之前蓝牙连接过
  293. if(ble_connect_flag)
  294. {
  295. ble_connect_flag= 0; //清除标记
  296. LED1= 1; //关灯--表示上锁
  297. printf( "蓝牙已经断开.\r\n");
  298. Motor= 0;
  299. //关锁
  300. //执行开锁代码--电机反转
  301. Motorccw_ring( 1, 300); //电机反转1圈
  302. //更新微信小程序
  303. sprintf(mqtt_message, "{\"method\":\"report\",\"clientToken\":\"123\",\"params\":{\"Motor\":%d}}",Motor);
  304. MQTT_PublishData(POST_TOPIC,mqtt_message, 0);
  305. USART1_Printf( "更新门锁状态:关锁\r\n");
  306. }
  307. }
  308. }
  309. }

 


转载:https://blog.csdn.net/xiaolong1126626497/article/details/117305333
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场