基于STM32+华为云IOT设计的智能门禁系统

一、项目介绍

智能门禁系统是一种应用物联网技术的智能化安防系统,提供安全高效的门禁管理和远程监控功能。传统的门禁系统通常使用磁卡、密码或钥匙等方式进行开锁,但存在易丢失、易复制、操作繁琐等问题。为了解决这些问题,并提高门禁安全性和便捷性,这里介绍了一款基于STM32F103和华为云IOT的智能门禁系统的设计方案。

系统的核心控制器采用了STM32F103单片机,具有丰富的外设接口和强大的处理能力,能够实现对门禁设备的精确控制和数据处理。为了提供多种开锁方式,选择了RFID-RC522读写模块和4x4电容矩阵键盘作为输入设备,用户可以通过刷卡或输入密码来开启门禁。采用了28BYJ-48步进电机作为门锁控制装置,能够实现对门锁的精确控制。

为了方便用户与门禁系统进行交互,使用了SPI接口的0.96寸OLED显示屏和蜂鸣器,可以显示门锁状态信息和人机交互提示音。此外,为了实现远程控制和消息推送功能,选择了ESP8266 WiFi模块连接华为云物联网平台,用户可以通过手机APP实现远程开锁,并且可以随时监控门锁状态。当门锁打开或关闭成功时,手机APP会收到通知提醒,以增加用户的使用安全性和便捷性。

通过将STM32F103和华为云IOT相结合,可以实现智能门禁系统在数据传输、远程控制和消息推送等方面的高效、稳定和安全性能。该系统不仅提供了多种开锁方式和人机交互功能,还具备远程监控和消息提醒的智能化特点,适用于住宅小区、学校、企事业单位等场所的门禁管理需求。

image-20230801151934943

image-20230801151925200

二、硬件选型

在智能门禁系统的硬件选型中,选择了以下模块:

【1】主控制器:STM32F103单片机。它是一款高性能、低功耗的ARM Cortex-M3内核微控制器,具有丰富的外设接口和强大的计算和控制能力,非常适合用于门禁系统的控制和数据处理。

【2】RFID读写模块:RFID-RC522。这个模块基于13.56MHz的射频识别技术,可以实现对RFID卡片的读写操作,通过刷卡方式进行门禁的开启和关闭。

【3】门锁控制:28BYJ-48步进电机。该步进电机结构简单、体积小巧,能够实现对门锁的准确控制,提供开启和关闭门锁的功能。

【4】密码输入设备:4x4电容矩阵键盘。这种键盘采用电容触摸技术,具有防水、灵敏度高的特点,用户可以通过输入密码来开启门禁。

【5】显示屏:SPI接口的0.96寸OLED显示屏。该显示屏具有高亮度、高对比度和低功耗的特点,可以显示门锁状态信息和人机交互提示。

【6】网络连接模块:ESP8266-WIFI。这个模块支持WiFi通信标准,能够实现与华为云物联网平台的连接,实现远程控制和消息推送功能。

【7】门状态检测:红外磁感应模块。通过红外磁感应技术,可以检测门是否打开或关闭,提供准确的门状态信息。

选择的这些硬件可以满足智能门禁系统的各项功能需求。主控制器STM32F103为整个系统提供了稳定可靠的控制和处理能力,RFID读写模块和密码键盘提供了多种开锁方式,步进电机实现了精确的门锁控制,显示屏和蜂鸣器提供了人机交互功能,ESP8266-WIFI模块连接华为云实现了远程控制和消息推送,红外磁感应模块检测门状态,使得整个智能门禁系统更加智能、安全和便捷。

三、系统设计思路

智能门禁系统的设计思路:

【1】硬件连接与集成:各个硬件组件(如主控制器、RFID读写模块、步进电机等)需要进行正确的连接和接口配置。通过连接线将各个硬件模块与主控制器相连,并设置正确的引脚连接和寄存器配置,以确保它们能够正常工作并实现相应的功能。

【2】数据采集与处理:系统通过RFID读写模块读取用户刷卡信息或通过电容矩阵键盘获取用户输入的密码信息。主控制器接收到这些数据后,进行相应的数据处理,例如验证刷卡信息或密码是否正确。如果验证通过,则进行下一步的门禁控制流程。

【3】门锁控制与状态检测:主控制器通过控制步进电机来实现门锁的精确控制。当用户验证成功后,主控制器发送指令给步进电机,使其旋转相应的步数,从而打开或关闭门锁。同时,主控制器还使用红外磁感应模块来检测门的状态,以确保门锁的准确控制。

【4】用户界面与人机交互:系统配备了0.96寸OLED显示屏和蜂鸣器,通过显示屏可以向用户展示门锁的状态信息和相关提示,如开锁成功、密码错误等。蜂鸣器则可以发出不同的提示音,提供与用户的交互反馈。

【5】远程控制与消息推送:通过ESP8266-WIFI模块与华为云物联网平台连接,使得用户可以通过手机APP进行远程开锁操作。用户在手机APP上输入开锁指令后,APP会将指令发送到华为云平台,再由云平台将指令传输给物联网设备(智能门禁系统)。主控制器接收到开锁指令后,执行相应的控制动作,并将结果通过云平台发送回手机APP,实现远程控制和消息推送功能。

整个系统的设计思路是将各个硬件组件协调配合,通过主控制器进行数据处理和门锁控制,并提供人机交互界面和远程控制功能,以实现智能门禁系统的安全、高效和便捷的门禁管理和远程监控。

四、华为云物联网平台部署

华为云官网: https://www.huaweicloud.com/

打开官网,搜索物联网,就能快速找到 设备接入IoTDA

image-20230801151116995

4.1 物联网平台介绍

华为云物联网平台(IoT 设备接入云服务)提供海量设备的接入和管理能力,将物理设备联接到云,支撑设备数据采集上云和云端下发命令给设备进行远程控制,配合华为云其他产品,帮助我们快速构筑物联网解决方案。

使用物联网平台构建一个完整的物联网解决方案主要包括3部分:物联网平台、业务应用和设备。

物联网平台作为连接业务应用和设备的中间层,屏蔽了各种复杂的设备接口,实现设备的快速接入;同时提供强大的开放能力,支撑行业用户构建各种物联网解决方案。

设备可以通过固网、2G/3G/4G/5G、NB-IoT、Wifi等多种网络接入物联网平台,并使用LWM2M/CoAP、MQTT、HTTPS协议将业务数据上报到平台,平台也可以将控制命令下发给设备。

业务应用通过调用物联网平台提供的API,实现设备数据采集、命令下发、设备管理等业务场景。

image-20230801151124332

image-20230801151130369

4.2 开通物联网服务

地址: https://www.huaweicloud.com/product/iothub.html

image-20230801151136153

点击总览,查看接入信息。 我们当前设备准备采用MQTT协议接入华为云平台,这里可以看到MQTT协议的地址和端口号等信息。

image-20230801151202953

总结:

端口号:   MQTT (1883)| MQTTS (8883)   
接入地址: a161a58a78.iot-mqtts.cn-north-4.myhuaweicloud.com

根据域名地址得到IP地址信息:

Microsoft Windows [版本 10.0.19045.2965]
(c) Microsoft Corporation。保留所有权利。C:\Users\11266>ping a161a58a78.iot-mqtts.cn-north-4.myhuaweicloud.com正在 Ping a161a58a78.iot-mqtts.cn-north-4.myhuaweicloud.com [121.36.42.100] 具有 32 字节的数据:
来自 121.36.42.100 的回复: 字节=32 时间=38ms TTL=94
来自 121.36.42.100 的回复: 字节=32 时间=37ms TTL=94
来自 121.36.42.100 的回复: 字节=32 时间=38ms TTL=94
来自 121.36.42.100 的回复: 字节=32 时间=36ms TTL=94121.36.42.100 的 Ping 统计信息:数据包: 已发送 = 4,已接收 = 4,丢失 = 0 (0% 丢失),
往返行程的估计时间(以毫秒为单位):最短 = 36ms,最长 = 38ms,平均 = 37msC:\Users\11266>

image-20230801151212765

MQTT协议接入端口号有两个,1883是非加密端口,8883是证书加密端口,单片机无法加载证书,所以使用1883端口比较合适。 接下来的ESP8266就采用1883端口连接华为云物联网平台。

4.3 创建产品

(1)创建产品

点击产品页,再点击左上角创建产品。

image-20230801151220860

(2)填写产品信息

根据自己产品名字填写。

image-20230801151228433

(3)产品创建成功

image-20230801151234528

(4)添加自定义模型

产品创建完成之后,点击进入产品详情页面,翻到最下面可以看到模型定义。

这个模型就是定义自己设备接下来需要向服务器上传那些数据类型。根据自己的数据类型进行编写。

先点击自定义模型。

image-20230801151243343

再创建一个服务ID。

image-20230801151250227

接着点击新增属性。

image-20230801151255512

image-20230801151300240

4.4 添加设备

产品是属于上层的抽象模型,接下来在产品模型下添加实际的设备。添加的设备最终需要与真实的设备关联在一起,完成数据交互。

(1)注册设备

image-20230801151308625

(2)根据自己的设备填写

image-20230801151315386

(3)保存设备信息

创建完毕之后,点击保存并关闭,得到创建的设备密匙信息。该信息在后续生成MQTT三元组的时候需要使用。

image-20230801151322328

(4)设备创建完成

可以点击设备进入到设备详情页面。

image-20230801151331651

4.5 MQTT协议主题订阅与发布

(1)MQTT协议介绍

当前的设备是采用MQTT协议与华为云平台进行通信。

MQTT是一个物联网传输协议,它被设计用于轻量级的发布/订阅式消息传输,旨在为低带宽和不稳定的网络环境中的物联网设备提供可靠的网络服务。MQTT是专门针对物联网开发的轻量级传输协议。MQTT协议针对低带宽网络,低计算能力的设备,做了特殊的优化,使得其能适应各种物联网应用场景。目前MQTT拥有各种平台和设备上的客户端,已经形成了初步的生态系统。

MQTT是一种消息队列协议,使用发布/订阅消息模式,提供一对多的消息发布,解除应用程序耦合,相对于其他协议,开发更简单;MQTT协议是工作在TCP/IP协议上;由TCP/IP协议提供稳定的网络连接;所以,只要具备TCP协议栈的网络设备都可以使用MQTT协议。 本次设备采用的ESP8266就具备TCP协议栈,能够建立TCP连接,所以,配合STM32代码里封装的MQTT协议,就可以与华为云平台完成通信。

华为云的MQTT协议接入帮助文档在这里: https://support.huaweicloud.com/devg-iothub/iot_02_2200.html

image-20230801151337395

业务流程:

image-20230801151342879

(2)华为云平台MQTT协议使用限制

描述限制
支持的MQTT协议版本3.1.1
与标准MQTT协议的区别支持Qos 0和Qos 1支持Topic自定义不支持QoS2不支持will、retain msg
MQTTS支持的安全等级采用TCP通道基础 + TLS协议(最高TLSv1.3版本)
单帐号每秒最大MQTT连接请求数无限制
单个设备每分钟支持的最大MQTT连接数1
单个MQTT连接每秒的吞吐量,即带宽,包含直连设备和网关3KB/s
MQTT单个发布消息最大长度,超过此大小的发布请求将被直接拒绝1MB
MQTT连接心跳时间建议值心跳时间限定为30至1200秒,推荐设置为120秒
产品是否支持自定义Topic支持
消息发布与订阅设备只能对自己的Topic进行消息发布与订阅
每个订阅请求的最大订阅数无限制

(3)主题订阅格式

帮助文档地址:https://support.huaweicloud.com/devg-iothub/iot_02_2200.html

image-20230801151350067

image-20230801151355027

对于设备而言,一般会订阅平台下发消息给设备 这个主题。

设备想接收平台下发的消息,就需要订阅平台下发消息给设备 的主题,订阅后,平台下发消息给设备,设备就会收到消息。

如果设备想要知道平台下发的消息,需要订阅上面图片里标注的主题。

以当前设备为例,最终订阅主题的格式如下:
$oc/devices/{device_id}/sys/messages/down最终的格式:
$oc/devices/6419627e40773741f9fbdac7_dev1/sys/messages/down

(4)主题发布格式

对于设备来说,主题发布表示向云平台上传数据,将最新的传感器数据,设备状态上传到云平台。

这个操作称为:属性上报。

帮助文档地址:https://support.huaweicloud.com/usermanual-iothub/iot_06_v5_3010.html

image-20230801151401246

根据帮助文档的介绍, 当前设备发布主题,上报属性的格式总结如下:

发布的主题格式:
$oc/devices/{device_id}/sys/properties/report最终的格式:
$oc/devices/6419627e40773741f9fbdac7_dev1/sys/properties/report
发布主题时,需要上传数据,这个数据格式是JSON格式。上传的JSON数据格式如下:{"services": [{"service_id": <填服务ID>,"properties": {"<填属性名称1>": <填属性值>,"<填属性名称2>": <填属性值>,..........}}]
}
根据JSON格式,一次可以上传多个属性字段。 这个JSON格式里的,服务ID,属性字段名称,属性值类型,在前面创建产品的时候就已经介绍了,不记得可以翻到前面去查看。根据这个格式,组合一次上传的属性数据:
{"services": [{"service_id": "stm32","properties":{"DS18B20":18,"motor_water":1,"motor_oxygen":1,"temp_max":10,"water_hp":130,"motor_food":0,"time_food":0,"oxygen_food":3}}]}

4.6 MQTT三元组

MQTT协议登录需要填用户ID,设备ID,设备密码等信息,就像我们平时登录QQ,微信一样要输入账号密码才能登录。MQTT协议登录的这3个参数,一般称为MQTT三元组。

接下来介绍,华为云平台的MQTT三元组参数如何得到。

(1)MQTT服务器地址

要登录MQTT服务器,首先记得先知道服务器的地址是多少,端口是多少。

帮助文档地址:https://console.huaweicloud.com/iotdm/?region=cn-north-4#/dm-portal/home

MQTT协议的端口支持1883和8883,它们的区别是:8883 是加密端口更加安全。但是单片机上使用比较困难,所以当前的设备是采用1883端口进连接的。

根据上面的域名和端口号,得到下面的IP地址和端口号信息: 如果设备支持填写域名可以直接填域名,不支持就直接填写IP地址。 (IP地址就是域名解析得到的)

华为云的MQTT服务器地址:114.116.232.138
域名:7445c6bcd3.st1.iotda-device.cn-north-4.myhuaweicloud.com
华为云的MQTT端口号:1883

注意!!!! 具体要看这里:

image-20230801151408871

(2)生成MQTT三元组

华为云提供了一个在线工具,用来生成MQTT鉴权三元组: https://iot-tool.obs-website.cn-north-4.myhuaweicloud.com/

打开这个工具,填入设备的信息(也就是刚才创建完设备之后保存的信息),点击生成,就可以得到MQTT的登录信息了。

下面是打开的页面:

image-20230801151418248

填入设备的信息: (上面两行就是设备创建完成之后保存得到的)

得到三元组之后,设备端通过MQTT协议登录鉴权的时候,填入参数即可。

ClientId 6419627e40773741f9fbdac7_dev1_0_0_2023032108
Username 6419627e40773741f9fbdac7_dev1
Password 861ac9e6a579d36888b2aaf97714be7af6c77017b017162884592bd68b086a6e

4.7 模拟设备登录测试

经过上面的步骤介绍,已经创建了产品,设备,数据模型,得到MQTT登录信息。 接下来就用MQTT客户端软件模拟真实的设备来登录平台。测试与服务器通信是否正常。

(1)填入登录信息

打开MQTT客户端软件,对号填入相关信息(就是上面的文本介绍)。然后,点击登录,订阅主题,发布主题。

image-20230801151429390

(2)打开网页查看

完成上面的操作之后,打开华为云网页后台,可以看到设备已经在线了。

点击详情页面,可以看到上传的数据。

到此,云平台的部署已经完成,设备已经可以正常上传数据了。

4.8 获取设备影子数据(API接口)

帮助文档:https://support.huaweicloud.com/api-iothub/iot_06_v5_0079.html

设备影子介绍:

设备影子是一个用于存储和检索设备当前状态信息的JSON文档。
每个设备有且只有一个设备影子,由设备ID唯一标识
设备影子仅保存最近一次设备的上报数据和预期数据
无论该设备是否在线,都可以通过该影子获取和设置设备的属性

简单来说:设备影子就是保存,设备最新上传的一次数据。

我们设计的软件里,如果想要获取设备的最新状态信息,就采用设备影子接口。

如果对接口不熟悉,可以先进行在线调试:https://apiexplorer.developer.huaweicloud.com/apiexplorer/doc?product=IoTDA&api=ShowDeviceShadow

在线调试接口,可以请求影子接口,了解请求,与返回的数据格式。

image-20230801151441245

设备影子接口返回的数据如下:

{"device_id": "6419627e40773741f9fbdac7_dev1","shadow": [{"service_id": "stm32","desired": {"properties": null,"event_time": null},"reported": {"properties": {"DS18B20": 18,"motor_water": 1,"motor_oxygen": 1,"temp_max": 10,"water_hp": 130,"motor_food": 0,"time_food": 0,"oxygen_food": 3},"event_time": "20230321T081126Z"},"version": 0}]
}

4.9 修改设备属性(API接口)

地址: https://support.huaweicloud.com/api-iothub/iot_06_v5_0034.html

接口说明

设备的产品模型中定义了物联网平台可向设备下发的属性,应用服务器可调用此接口向指定设备下发属性。平台负责将属性以同步方式发送给设备,并将设备执行属性结果同步返回。

修改设备属性的接口,可以让服务器给设备下发指令,如果需要控制设备。

在线调试地址:

https://apiexplorer.developer.huaweicloud.com/apiexplorer/doc?product=IoTDA&api=UpdateProperties

修改设备属性是属于同步命令,需要设备在线才可以进行调试,先使用MQTT客户端登录服务器,模拟设备上线。

然后进行调试,测试数据远程下发给设备。

【1】利用MQTT客户端先登录设备 (这是同步命令,必须在线才能调试)

image-20230801151450774

【2】点击调试

image-20230801151457386

{"services":{"temp_max":100}}

【4】可以看到,MQTT客户端软件上已经收到了服务器下发的消息

image-20230801151505222

由于是同步命令,服务器必须要收到设备的响应才能顺利完成一个流程,设备响应了服务器才能确定数据下发成功。

五、代码设计

5.1 ESP8266模块介绍

ESP8266-WIFI是一款由乐鑫科技开发的低成本Wi-Fi芯片,可与其他微控制器或单片机配合使用,实现无线通讯功能。该芯片集成了一个高性能的32位Tensilica L106 RISC处理器,以及一组内置的WIFI模块和电源管理模块,能够在低功耗下提供稳定的无线网络连接。

以下是ESP8266与MQTT协议相关常用的AT指令介绍:

【1】AT+CIPSTART:建立TCP连接。

在使用MQTT协议时,需要先建立TCP连接。AT+CIPSTART可以实现与MQTT服务器的TCP连接,格式如下:

AT+CIPSTART="TCP","MQTT服务器地址",MQTT服务器端口号

【2】AT+CIPSEND:发送数据。

在建立TCP连接之后,可以使用AT+CIPSEND发送数据,包括MQTT协议的各种命令。格式如下:

AT+CIPSEND=<length>
<MQTT命令>

其中,表示数据长度,<MQTT命令>表示MQTT协议的命令,例如CONNECT、PUBLISH、SUBSCRIBE等。

【3】AT+CIPCLOSE:关闭TCP连接。在使用完MQTT协议之后,可以使用AT+CIPCLOSE关闭TCP连接,格式如下:

AT+CIPCLOSE

【4】AT+CIPSTATUS:查询TCP连接状态。使用AT+CIPSTATUS可以查询当前TCP连接的状态,格式如下:

AT+CIPSTATUS

返回值包括:STATUS、TCP连接状态;LINK ID、TCP连接ID;IP、TCP连接的IP地址;PORT、TCP连接端口号。

【5】AT+MQTTCONN:连接MQTT服务器。使用AT+MQTTCONN可以连接MQTT服务器,格式如下:

AT+MQTTCONN=<clientID>,<user>,<password>,<keepalive>,<clean>,<willTopic>,<willMessage>,<willQoS>,<willRetain>

其中,表示客户端ID;表示用户名;表示密码;表示心跳包间隔时间;表示清除会话标志;表示遗言主题;表示遗言消息;表示遗言QoS等级;表示遗言消息是否保留。

【6】AT+MQTTPUB:发布消息。使用AT+MQTTPUB可以发布MQTT消息,格式如下:

AT+MQTTPUB=<topic>,<payload>,<QoS>,<retain>

其中,表示MQTT主题;表示消息负载;表示消息QoS等级;表示消息是否保留。

【7】AT+MQTTSUB:订阅主题。使用AT+MQTTSUB可以订阅MQTT主题,格式如下:

AT+MQTTSUB=<topic>,<QoS>

其中,表示MQTT主题;表示消息QoS等级。

5.2 连接云端代码

以下是STM32F103+ESP8266通过MQTT协议登录MQTT物联网服务器,实现主题订阅、发布的示例代码,其中利用了ESP8266-WIFI的AT指令实现与MQTT服务器的通信。

需要在STM32F103上配置UART串口,以实现与ESP8266的通信。在STM32F103上编写AT指令的发送和接收函数,将其集成到工程中。

代码如下:

#include "stm32f1xx_hal.h"
#include <string.h>
#include <stdio.h>/* 定义ESP8266的UART串口 */
UART_HandleTypeDef huart1;/* 定义MQTT服务器地址、端口号、用户名和密码等信息 */
const char* mqtt_server = "mqtt.example.com";
const int mqtt_port = 1883;
const char* mqtt_username = "username";
const char* mqtt_password = "password";/* 定义MQTT主题 */
const char* mqtt_topic = "test/topic";/* 定义回调函数,处理MQTT消息 */
void messageArrived(MessageData* data)
{printf("Message arrived: topic=%.*s, payload=%.*s\n", data->topicName->lenstring.len, data->topicName->lenstring.data, data->message->payloadlen, data->message->payload);
}/* 发送AT指令并等待响应 */
int ESP8266_SendATCommand(char* cmd, char* response, int timeout)
{HAL_UART_Transmit(&huart1, (uint8_t*)cmd, strlen(cmd), timeout);int len = 0;int len_read = 0;HAL_Delay(100);while (1) {if (HAL_UART_Receive(&huart1, (uint8_t*)response + len, 1, timeout) == HAL_OK) {len++;if (strstr(response, "OK") != NULL) {return len;}if (strstr(response, "ERROR") != NULL) {return -1;}if (len >= 1024) {return -1;}}}
}/* 连接MQTT服务器 */
int MQTT_Connect(void)
{char cmd[1024];char response[1024];/* 设置ESP8266为透传模式 */ESP8266_SendATCommand("AT+CIPMODE=1\r\n", response, 1000);ESP8266_SendATCommand("AT+CIPMUX=0\r\n", response, 1000);/* 建立TCP连接 */sprintf(cmd, "AT+CIPSTART=\"TCP\",\"%s\",%d\r\n", mqtt_server, mqtt_port);ESP8266_SendATCommand(cmd, response, 5000);/* 连接MQTT服务器 */sprintf(cmd, "AT+CIPSEND=%d\r\n", 33 + strlen(mqtt_username) + strlen(mqtt_password));ESP8266_SendATCommand(cmd, response, 1000);sprintf(cmd, "CONNECT\n\rclient_id:ESP8266\n\ruser:%s\n\rpassword:%s\n\r\n\r", mqtt_username, mqtt_password);ESP8266_SendATCommand(cmd, response, 5000);/* 订阅MQTT主题 */sprintf(cmd, "AT+CIPSEND=%d\r\n", 10 + strlen(mqtt_topic));ESP8266_SendATCommand(cmd, response, 1000);sprintf(cmd, "SUBSCRIBE\n\r%d\n\r0\n\r\n\r", strlen(mqtt_topic));ESP8266_SendATCommand(cmd, response, 5000);return 0;
}/* 发布MQTT消息 */
void MQTT_Publish(const char* message)
{char cmd[1024];char response[1024];sprintf(cmd, "AT+CIPSEND=%d\r\n", 8 + strlen(mqtt_topic) + strlen(message));ESP8266_SendATCommand(cmd, response, 1000);sprintf(cmd, "PUBLISH\n\r%d\n\r%s\n\r\n\r%s\n\r", strlen(mqtt_topic), mqtt_topic, message);ESP8266_SendATCommand(cmd, response, 5000);
}/* 主程序 */
int main(void)
{/* 连接MQTT服务器 */if (MQTT_Connect() != 0) {while (1) {/* 连接失败,进入死循环 */}}/* 发布MQTT消息 */MQTT_Publish("Hello, MQTT!");/* 等待接收MQTT消息 */while (1) {/* 读取ESP8266接收缓冲区中的数据 */char response[1024];int len = ESP8266_SendATCommand("AT+CIPRXGET=2,1024\r\n", response, 1000);if (len > 0) {printf("Received data: %.*s\n", len, response);/* TODO: 解析并处理MQTT消息 */}/* 延时一段时间 */HAL_Delay(100);}return 0;
}

代码实现了连接MQTT服务器、订阅主题、发布消息等功能。

5.3 OLED显示屏代码

以下是使用STM32F103ZET6控制0.96寸SPI接口的OLED显示屏的代码:

cCopy Code#include "stm32f10x.h"
#include "spi.h" // SPI库头文件// OLED相关定义
#define OLED_CMD  0 // 命令模式
#define OLED_DATA 1 // 数据模式#define OLED_ADDR_START 0xB0 // OLED起始地址
#define OLED_PAGE_START 0x00 // 第一个页的地址
#define OLED_COLUMN_START 0x10 // 列起始地址// 初始化OLED显示屏
void OLED_Init(void)
{// 初始化SPI接口SPI_Init();Delay(100);// 向OLED发送初始化命令和数据// 模式设置:设置4位数据线,扩展指令集OLED_WriteCmd(OLED_CMD, 0x21);// 对比度设置,默认为0x7FOLED_WriteCmd(OLED_CMD, 0x81);OLED_WriteCmd(OLED_CMD, 0x7F);// 设置显示模式:正常显示OLED_WriteCmd(OLED_CMD, 0xA4);// 设置偏置电压OLED_WriteCmd(OLED_CMD, 0xA8);OLED_WriteCmd(OLED_CMD, 0x3F);// 设置显示方向:从左到右,从上到下OLED_WriteCmd(OLED_CMD, 0xC8);// 设置扫描地段,从COM0到COM[N-1]OLED_WriteCmd(OLED_CMD, 0xDA);OLED_WriteCmd(OLED_CMD, 0x12);// 设置时钟分频因子OLED_WriteCmd(OLED_CMD, 0xD5);OLED_WriteCmd(OLED_CMD, 0x80);// 设置显示开启OLED_WriteCmd(OLED_CMD, 0xAF);
}// 写入命令或数据到OLED显示屏
void OLED_WriteCmd(uint8_t mode, uint8_t cmd)
{if (mode == OLED_CMD) {GPIO_ResetBits(GPIOA, GPIO_Pin_4); // 将DC引脚置低,进入命令模式} else {GPIO_SetBits(GPIOA, GPIO_Pin_4); // 将DC引脚置高,进入数据模式}GPIO_ResetBits(GPIOA, GPIO_Pin_3); // 将CS引脚置低,选中OLEDSPI_SendData(cmd); // 发送命令或数据while (SPI_GetFlagStatus(SPI1, SPI_FLAG_TXE) == RESET);GPIO_SetBits(GPIOA, GPIO_Pin_3); // 将CS引脚置高,释放OLED
}// 在指定位置显示一个数字
void OLED_ShowNumber(uint8_t x, uint8_t y, uint32_t number)
{char str[11]; // 最大显示10位数字sprintf(str, "%lu", number); // 将数字转换为字符串OLED_ShowString(x, y, str); // 在指定位置显示字符串
}// 在指定位置显示一个字符串
void OLED_ShowString(uint8_t x, uint8_t y, char *str)
{uint8_t i = 0;while (str[i] != '\0') {OLED_ShowChar(x, y, str[i]); // 在指定位置显示一个字符x += 6; // 移动到下一列i++;}
}// 在指定位置显示一个字符
void OLED_ShowChar(uint8_t x, uint8_t y, char ch)
{uint8_t i, j;for (i = 0; i < 8; i++) { // 8行OLED_WriteCmd(OLED_CMD, OLED_ADDR_START + y); // 指定页OLED_WriteCmd(OLED_CMD, OLED_COLUMN_START + x); // 指定列for (j = 0; j < 6; j++) { // 6列OLED_WriteCmd(OLED_DATA, ASCII[ch - 32][j]);}y++;}
}

在这段代码中,定义了OLED相关的常量和函数,包括OLED命令模式和数据模式、OLED起始地址、页起始地址、列起始地址等。在OLED_Init()函数中进行了OLED的初始化过程,包括发送相应的初始化命令和数据给OLED显示屏。在OLED_WriteCmd()函数中,根据传入的命令模式(OLED_CMD)或数据模式(OLED_DATA),将DC引脚设置为相应的状态,并通过SPI接口将命令或数据发送给OLED显示屏。在OLED_ShowNumber()OLED_ShowString()OLED_ShowChar()函数中,通过调用OLED_WriteCmd()发送相应的指令和数据,实现在指定位置显示数字、字符串和字符。

5.4 步进电机控制代码

以下是STM32F103+28BYJ40步进电机实现角度控制和正反转控制的代码,使用了STM32F1xx_HAL库来控制GPIO口和定时器,实现精准的角度控制和正反转控制。

#include "stm32f1xx_hal.h"
#include <stdio.h>/* 定义步进电机的4个控制引脚 */
#define IN1_Pin GPIO_PIN_0
#define IN1_GPIO_Port GPIOA
#define IN2_Pin GPIO_PIN_1
#define IN2_GPIO_Port GPIOA
#define IN3_Pin GPIO_PIN_2
#define IN3_GPIO_Port GPIOA
#define IN4_Pin GPIO_PIN_3
#define IN4_GPIO_Port GPIOA/* 定义步进电机的步数数组 */
uint8_t step_sequence[8] = {0b0001, 0b0011, 0b0010, 0b0110, 0b0100, 0b1100, 0b1000, 0b1001};/* 定义当前步进电机的位置和方向 */
int current_step = 0;  // 当前步数
int direction = 1;  // 1为顺时针,-1为逆时针/* 定义角度控制参数 */
float angle_per_step = 1.8;  // 每步角度
int total_steps = 2048;  // 总步数/* 定义定时器中断处理函数,控制步进电机的运动 */
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{/* 更新步进电机的位置 */current_step += direction;if (current_step >= total_steps) {current_step = 0;} else if (current_step < 0) {current_step = total_steps - 1;}/* 控制步进电机的旋转方向 */int sequence_index = current_step % 8;GPIO_PinState in1_state = (step_sequence[sequence_index] & 0b0001) ? GPIO_PIN_SET : GPIO_PIN_RESET;GPIO_PinState in2_state = (step_sequence[sequence_index] & 0b0010) ? GPIO_PIN_SET : GPIO_PIN_RESET;GPIO_PinState in3_state = (step_sequence[sequence_index] & 0b0100) ? GPIO_PIN_SET : GPIO_PIN_RESET;GPIO_PinState in4_state = (step_sequence[sequence_index] & 0b1000) ? GPIO_PIN_SET : GPIO_PIN_RESET;HAL_GPIO_WritePin(IN1_GPIO_Port, IN1_Pin, in1_state);HAL_GPIO_WritePin(IN2_GPIO_Port, IN2_Pin, in2_state);HAL_GPIO_WritePin(IN3_GPIO_Port, IN3_Pin, in3_state);HAL_GPIO_WritePin(IN4_GPIO_Port, IN4_Pin, in4_state);
}/* 初始化定时器 */
void TIM_Init(void)
{TIM_HandleTypeDef htim;/* 使能定时器时钟 */__HAL_RCC_TIM2_CLK_ENABLE();/* 配置定时器 */htim.Instance = TIM2;htim.Init.Prescaler = 7199;  // 72MHz / 7200 = 10kHzhtim.Init.CounterMode = TIM_COUNTERMODE_UP;htim.Init.Period = 99;  // 10kHz / 100 = 100Hzhtim.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;HAL_TIM_Base_Init(&htim);/* 启动定时器 */HAL_TIM_Base_Start_IT(&htim);
}/* 控制步进电机旋转 */
void StepMotor_Rotate(int angle, int clockwise)
{/* 计算需要旋转的步数和方向 */int steps = angle / angle_per_step;direction = clockwise ? 1 : -1;/* 控制步进电机旋转 */for (int i = 0; i < steps; i++) {HAL_Delay(1);}
}/* 主程序 */
int main(void)
{/* 初始化定时器 */TIM_Init();/* 控制步进电机旋转 */StepMotor_Rotate(90, 1);  // 顺时针旋转90度StepMotor_Rotate(180, 0);  // 逆时针旋转180度while (1) {/* 循环等待 */}return 0;
}

IN1_Pin到IN4_Pin为步进电机的控制引脚,step_sequence为步进电机的步数数组,current_step为当前步数,direction为旋转方向,angle_per_step为每步的角度,total_steps为总步数。在HAL_TIM_PeriodElapsedCallback函数中,根据当前步数和旋转方向控制步进电机的旋转方向,使用HAL_GPIO_WritePin函数控制引脚输出状态。在StepMotor_Rotate函数中,根据传入的角度和旋转方向计算需要旋转的步数和方向,然后循环延时控制步进电机旋转。通过调用StepMotor_Rotate函数,可以实现步进电机的角度控制和正反转控制。

六、总结

智能门禁系统是一种基于STM32F103主控制器和华为云物联网平台的安全、便捷的门禁控制方案。通过整合多种硬件模块和网络通信技术,该系统实现了多种开锁方式(密码输入、RFID刷卡、手机APP远程开锁),并且具备远程监控和消息推送功能。

在硬件选型上,刷卡模块选择了RFID-RC522,采用28BYJ-48步进电机作为门锁控制器,4x4电容矩阵键盘用于密码输入,SPI接口的0.96寸OLED显示屏用于门锁状态信息显示,而ESP8266-WIFI模块则实现了联网功能。此外,红外磁感应模块用于检测门的状态。

整个系统的设计使得门禁更加安全可靠,用户可以通过多种方式进行开锁操作,包括输入密码、刷卡以及远程开锁。同时,系统可以实时监控门锁状态,并在门锁打开或关闭时通过手机APP向用户发送通知提醒,提高了使用者的安全性和便利性。

基于STM32F103和华为云物联网平台的智能门禁系统充分利用了现代科技的优势,提供了安全、便捷的门禁控制解决方案。除了基本的门禁功能外,该系统还具备远程控制和实时监控的能力,为用户带来更加智能化的门禁体验,并满足了现代人们对于安全、便捷生活的需求。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/88692.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Spring学习笔记13 Spring对事务的支持

Spring学习笔记12 面向切面编程AOP-CSDN博客 什么是事务:在一个业务流程当中,通常需要多条DML(insert delete update)语句共同联合才能完成,这多条DML语句必须同时成功,或者同时失败,这样才能保证数据的安全. 多条DML要么同时成功,要么同时失败,叫做事务(Transaction) 事务四…

ARM IIC总线实现温湿传感器

IIC.h #ifndef __IIC_H__ #define __IIC_H__ #include "stm32mp1xx_gpio.h" #include "stm32mp1xx_rcc.h"/* 通过程序模拟实现I2C总线的时序和协议* GPIOF ---> AHB4* I2C1_SCL ---> PF14* I2C1_SDA ---> PF15** */#define SET_SDA_OUT do{G…

机器人过程自动化(RPA)入门 3. 顺序、流程图和控制流程

到目前为止&#xff0c;我们已经了解了RPA是什么&#xff0c;并且我们已经看到了通过记录任务的活动并运行它来训练UiPath机器人是多么简单。使用记录器的UiPath可以很容易地自动化日常任务。在我们开始自动化复杂的任务之前&#xff0c;让我们学习如何控制从一个到另一个的活动…

Linux命令之chattr命令

一、chattr命令简介 chattr命令用于更改文件或目录的属性&#xff0c;包括不可修改属性、同步属性、追加属性、无尽属性、压缩属性、无尽属性、不可删除属性等。chattr命令只能由超级用户或文件的所有者使用。 二、chattr命令使用示例 1、给文件设置版本 -v参数设置版本信息只…

12KM02E-V0002 3EGM030300R0002 模块化和加固的边缘计算加速

12KM02E-V0002 3EGM030300R0002 模块化和加固的边缘计算加速 随着边缘人工智能解决方案的兴起&#xff0c;对实时洞察和自主决策的需求显著增长。这也带来了对变革性技术的高度需求&#xff0c;这些技术可以在坚固的边缘支持和提供最佳性能。为了应对技术革命&#xff0c;Prem…

linux使用操作[3]

文章目录 版权声明环境变量$符号自行设置环境变量 上传、下载rz、sz命令 压缩、解压tar命令压缩tar解压zip 命令压缩文件unzip 命令解压文件 版权声明 本博客的内容基于我个人学习黑马程序员课程的学习笔记整理而成。我特此声明&#xff0c;所有版权属于黑马程序员或相关权利人…

了解MES:提升制造业的效率与竞争力

今天我将和大家分享关于MES&#xff08;Manufacturing Execution System&#xff0c;制造执行系统&#xff09;的知识。随着制造业的发展和变革&#xff0c;MES作为一个关键的信息技术工具&#xff0c;已经成为许多企业提升效率和竞争力的重要策略之一。 MES的定义与作用 MES是…

Redis集群架构搭建——主从、哨兵、集群

上一篇文章Ubuntu上通过源码方式安装Redis已经介绍了如何安装redis&#xff0c;在这篇文章中&#xff0c;将会教大家搭建Redis的几种高可用的架构&#xff1a;主从架构、哨兵集群、Cluster集群。 本篇文章使用的redis版本为6.2.13&#xff0c;不同版本的配置可能有略微的区别&a…

HTTP代理SSL连接:保障网络安全的重要协议

HTTP代理SSL连接是一种网络安全协议&#xff0c;它结合了HTTP代理和SSL/TLS协议&#xff0c;用于在客户端和服务器之间建立加密通信通道。HTTP代理SSL连接可以保护数据在传输过程中不被窃听、篡改或伪造&#xff0c;从而确保数据的完整性、保密性和可靠性。在本文中&#xff0c…

目前很火的养猫微信小程序源码带流量主+搭建教程

目前很火的养猫微信小程序源码带流量主搭建教程。 搭建教程 进入小程序我们下载开发者工具 开发者工具安装好了 我们就把前端源码导入进开发者工具中 这里的APPID我们填写自己的小程序APPID 修改siteinfo.js里的uniacid和acid 这两个ID在刚才后端添加的小程序那里看 在把…

新版WordPress系统文章自动采集插件/Auto Post pro完美运行版/多线程采集(wp自动采集)

源码介绍&#xff1a; 最新版WordPress系统文章自动采集插件&#xff0c;它是一款帮助用户提供方便快捷的文章自动采集方案的插件。WordPress自动采集插件&#xff0c;让内容采集变得高效便捷。作为Auto Post pro完美运行版&#xff0c;这里分享的是WordPress文章采集插件Auto…

TG Pro for Mac强大的硬件温度检测、风扇控制工具测评

无论您是旧机型还是全新MacBookPro&#xff0c;使用TG Pro均可延长Mac的使用寿命。小编就给大家详细说一下使用TG Pro的体验~ 打开TG Pro&#xff0c;您会注意到的第一件事是带有大量温度&#xff0c;风扇速度和诊断信息的主窗口。 这是您将与之交互的应用程序的主要区域之一。…

Selenium自动化测试 —— 通过cookie绕过验证码的操作!

验证码的处理 对于web应用&#xff0c;很多地方比如登录、发帖都需要输入验证码&#xff0c;类型也多种多样&#xff1b;登录/核心操作过程中&#xff0c;系统会产生随机的验证码图片&#xff0c;进行验证才能进行后续操作 解决验证码的方法如下&#xff1a; 1、开发做个万能…

设计模式 - 代理模式

目录 一. 前言 二. 实现 三. 静态代理和动态代理 一. 前言 代理模式&#xff08;Proxy Pattern&#xff09;&#xff0c;为某个对象提供一种代理以控制对对象的访问。即客户端可通过代理对象间接访问目标对象&#xff0c;同时可限制、增强、修改目标对象的一些特性。访问者不…

vue3 - 按需导入使用Element Plus图标、iconify图标、本地SVG/PNG图标

GitHub Demo 地址 在线预览 vue3 - 按需导入使用Element Plus图标、iconify图标、本地SVG/PNG图标 [GitHub Demo 地址](https://github.com/iotjin/jh-vue3-admin)[在线预览 ](https://iotjin.github.io/jh-vue3-admin) 一、iconify插件安装使用效果图 二、通过自动导入使用ic…

AIGC: 区块链与数据安全

随着国家将区块链纳入战略发展规划&#xff0c;数字经济蓬勃发展。近年来&#xff0c;数据的流通成为了实体经济赋能的关键&#xff0c;而在这一过程中&#xff0c;区块链技术和数据安全变得至关重要。 中国已经成为全球最大的数据体&#xff0c;每天产生大量数据。数字经济已…

软件测试人员必须知道的接口测试基础

一、首先&#xff0c;什么是接口呢&#xff1f; 接口一般来说有两种&#xff0c;一种是程序内部的接口&#xff0c;一种是系统对外的接口。系统对外的接口&#xff1a;比如你要从别的网站或服务器上获取资源或信息&#xff0c;别人肯定不会把数据库共享给你&#xff0c;他只能…

【Linux】——基操指令(一)

个人主页 代码仓库 C语言专栏 初阶数据结构专栏 Linux专栏 LeetCode刷题 算法专栏 目录 前言 基操前的碎碎念 计算机的层状结构 基础指令 查看登录用户指令 查看用户指令 查看当前所处工作目录 清屏指令 基操指令 ls命令 cd命令 makdir指令 rmdir指令 &…

Mac电脑信息大纲记录软件 OmniOutliner 5 Pro for Mac中文

OmniOutliner 5 Pro是一款专业级的Mac大纲制作工具&#xff0c;它可以帮助用户更好地组织和管理信息&#xff0c;以及制作精美的大纲。以下是OmniOutliner 5 Pro的主要功能和特点&#xff1a; 强大的大纲组织和管理功能。OmniOutliner 5 Pro为用户提供了多层次的大纲结构&…

SpringBoot+MinIO8.0开箱即用的启动器

一、代码拉取及安装 1.码云地址 https://gitee.com/qiangesoft/rdp-starter/tree/master/rdp-starter-minio 2.本地安装 代码接入 1.引入依赖 <dependency><groupId>com.qiangesoft.rdp</groupId><artifactId>rdp-starter-minio</artifactId&g…