当前位置: 首页 > news >正文

基于物联网设计的智能储物柜(4G+华为云IOT+微信小程序)

一、项目介绍

在游乐场、商场、景区等人流量较大的地方,往往存在用户需要临时存放物品的情况,例如行李箱、外套、购物袋等。为了满足用户的储物需求,并提供更加便捷的服务体验,当前设计了一款物联网智能储物柜。

该智能储物柜通过与华为云物联网服务器的连接,实现了数据的传输和管理,让用户可以通过微信小程序轻松查看储物柜的可用状态和选择合适的储物柜进行解锁。通过使用4G联网模块E29 Cat-1,储物柜实现了稳定的网络连接,确保了用户可以随时随地查看和使用储物柜。

主控芯片采用STC12C5A60S2,具有低功耗、高性能和丰富的外设接口等特点,能够满足储物柜的控制需求。而储物柜的锁则采用了电磁锁,能够快速、安全地实现储物柜的解锁和上锁操作。

用户在解锁储物柜后,会扣除相应的押金(预付金),然后根据使用时间进行计费。用户可以随时存取自己的物品,并且在使用完成后可以通过微信小程序完成订单结算,使整个使用过程更加便捷和透明。

这款4G智能储物柜为用户提供了一种灵活、安全、便捷的储物解决方案,能够有效满足人们日常生活中的储物需求,并提供良好的用户体验。

智能储物柜支持的主要功能:

(1)远程查看储物柜状态:用户可以通过微信小程序实时查看储物柜的可用状态,包括储物柜数量、剩余可用储物柜数量等信息。这使得用户在选择储物柜时可以提前了解储物柜的可用性,避免不必要的等待。

(2)指定储物柜解锁:用户可以在微信小程序上选择需要使用的储物柜,并进行解锁操作。当用户选择指定储物柜后,储物柜会自动解锁,方便用户存放物品。

(3)押金扣除和计费:在解锁储物柜时,系统会自动扣除用户的押金(预付金)。智能储物柜根据使用时间进行计费,用户只需根据实际使用时间支付相应费用。

(4)存取物品:一旦用户成功解锁储物柜,他们就可以将物品存放或取出。用户可以随时存取自己的物品,并享受到安全可靠的储物体验。

(5)临时解锁功能:如果用户需要频繁存取物品,储物柜提供了临时解锁功能。用户可以选择设置一段时间内的临时解锁,无需重复进行解锁操作,方便快捷。

(6)订单结算:用户在使用完成后,可以通过微信小程序完成订单结算。系统会根据实际使用时间和费率进行计算,并生成相应的费用清单供用户支付。

整体系统流程框架图:

image-20230925153026023

做好的柜子效果如下: (柜子不带屏幕的,全部操作在微信小程序上进行)

image-20230925151722754

二、软硬件选型

2.1 硬件选型

智能储物柜所需的硬件主要包括下面几个部分:

(1)主控芯片:采用STC12C5A60S2主控芯片,具有低功耗、高性能和丰富的外设接口,能够满足储物柜的控制需求。

(2)4G联网模块:采用华为云IOT提供的4G联网模块E29 Cat-1,确保储物柜具备稳定的网络连接功能,实现远程数据传输和管理。

(3)电磁锁(每个小柜子一个电磁锁):储物柜采用电磁锁作为解锁和上锁的装置,能够快速、安全地实现储物柜的开关操作。电磁锁具有较高的稳定性和安全性。

(4)电源系统:储物柜需要一个可靠的电源系统来供电,以确保储物柜的正常运行。

(5)外壳和结构组件:储物柜外壳。

采用主控板:

image-20230925150325217

采用的电磁锁:

image-20230925150848200

采用的柜子:

image-20230925151803556

2.2 软件选型

软件包含了4个部分。

(1)设备端的程序开发,智能储物柜设备端的程序。

(2)华为云IOT物联网服务器的配置。设备注册、消息转发。

(3)智能锁的后台云服务器搭建。

(4)小程序、公众号程序开发。

在这里插入图片描述

三、华为云物联网服务器部署

3.2 开通物联网服务

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

image-20230801151136153

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

image-20230925155200396

image-20230925155233810

总结:

端口号:   MQTT (1883)  
接入地址: e244e6efb9.st1.iotda-device.cn-north-4.myhuaweicloud.com

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

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

image-20230925155314730

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

3.3 创建产品

(1)创建产品

点击产品页,再点击创建产品。

image-20230925155450476

(2)填写产品信息

根据自己产品名字填写。

image-20230925155543528

(3)产品创建成功

image-20230925155557999

(4)添加自定义模型

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

image-20230925155634106

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

先点击自定义模型。

image-20230925155710677

再创建一个服务ID。

image-20230925155738113

接着点击新增属性。

image-20230925155908114

设置属性。

image-20230925155933814

属性添加成功。

image-20230925155956728

3.4 添加设备

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

(1)注册设备

image-20230925160050686

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

设备标识码、密码这些根据自己情况认真填写。

image-20230925160152785

(3)保存设备信息

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

image-20230925160232066

创建之后,得到的设备信息如下:

{"device_id": "65113d05a559fd7cd41435f8_lock1","secret": "12345678"
}

(4)设备创建完成

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

image-20230925160613806

3.5 MQTT协议主题订阅与发布

(1)主题订阅格式

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

image-20230801151350067

image-20230801151355027

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

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

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

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

(2)主题发布格式

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

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

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

image-20230925160939978

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

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

3.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服务器地址:117.78.5.125
域名:e244e6efb9.st1.iotda-device.cn-north-4.myhuaweicloud.com
华为云的MQTT端口号:1883

注意! 具体要看这里:

image-20230925161111346

(2)生成MQTT三元组

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

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

下面是打开的页面:

image-20230801151418248

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

image-20230925161154059

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

ClientId 65113d05a559fd7cd41435f8_lock1_0_0_2023092508
Username 65113d05a559fd7cd41435f8_lock1
Password 1a3e7f486aa551bca7b6ff5c19c29d2006e940ec1f98ab416e10be1288106953

3.7 模拟设备登录测试

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

(1)填入登录信息

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

image-20230925161345360

(2)打开网页查看

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

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

image-20230925161426088

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

3.8 添加控制命令(云端控制设备)

在产品页面,添加控制命令。

image-20230925162251674

根据自己设备的情况填写需要发送的控制命令。

image-20230925162418179

image-20230925162526196

3.9 云端发送控制命令

在设备页面测试刚才添加的命令。

image-20230925162711916

image-20230925162751673

点击确定之后,在MQTT客户端上就能收到云端下发的控制命令。

说明:当前的MQTT客户端实际就是模拟的真实设备。 真实设备收到控制命令就可以判断,完成锁的开关控制。

image-20230925162830773

这个下发的命令是有反馈。设备端收到之后,可以向服务器反馈状态,这样服务器才能知道刚才的控制命令确实发送成功了。

设备收到信息之后,上传回应给服务器的主题和内容格式:

Topic:$oc/devices/{device_id}/sys/commands/response/request_id={request_id}
数据格式:  
{"result_code": 0,"response_name": "COMMAND_RESPONSE","paras": {"result": "success"}
}

云端发送控制命令之后,设备收到的消息如下:

$oc/devices/65113d05a559fd7cd41435f8_lock1/sys/commands/request_id=d49f0bb9-ba87-4c9b-b915-98a1f0fcf689{"paras":{"lock":true},"service_id":"lock","command_name":"锁开关控制"}

其中request_id=d49f0bb9-ba87-4c9b-b915-98a1f0fcf689 就是本次的请求ID。回应的时候需要加上请求ID。服务器才好对应。

以当前设备为例:

发布的主题这样填: $oc/devices/65113d05a559fd7cd41435f8_lock1/sys/commands/response/request_id=ce49181e-7636-4b24-946d-c034ca083c1c发布的内容这样填:
{"result_code":0,"response_name":"COMMAND_RESPONSE","paras":{"result":"success"}}

在MQTT软件里这样填:

image-20230925163506474

MQTT回应之后,可以在云端的发送命令界面,看到右上角有弹窗提示,命令下发成功。

image-20230925163208848

四、微信小程序开发

如果要开发自己的上位机,远程控制设备。

一般有两种需求。

(1)获取设备的状态。

(2)给设备发送控制指令。

那么下面就介绍这两种接口如何使用,就是标准的HTTPS接口。

4.1 获取设备影子数据(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-20230925161642973

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

{"device_id": "65113d05a559fd7cd41435f8_lock1","shadow": [{"service_id": "lock","desired": {"properties": null,"event_time": null},"reported": {"properties": {"lock": 1},"event_time": "20230925T081357Z"},"version": 0}]
}

4.2 控制命令发送(API接口)

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

image-20230925164327371

在线调试地址:https://console.huaweicloud.com/apiexplorer/#/openapi/IoTDA/debug?api=CreateCommand

填写需要发送给设备的消息。

image-20230925164546678

{"lock":1}

设备端可以收到下发的命令

image-20230925164631704

设备端收到下发命令之后,也可以向服务器反馈状态,反馈的方式在前面的3.9小节已经介绍过了。

4.3 创建IAM账户

创建一个IAM账户,因为接下来开发上位机,需要使用云平台的API接口,这些接口都需要token进行鉴权。简单来说,就是身份的认证。 调用接口获取Token时,就需要填写IAM账号信息。所以,接下来演示一下过程。

地址: https://console.huaweicloud.com/iam/?region=cn-north-4#/iam/users

获取Token时,除了AIM账号外,还需要项目凭证:

9254586ba43841e6bf4995dc24023d6b

image-20230925165102886

鼠标点击自己昵称,点击统一身份认证。

点击左上角创建用户

image-20230313175315289

image-20221207161209880

image-20221207161308917

image-20221207161327200

创建成功:

image-20221212174359962

image-20221212174412097

用户创建成功。

image-20230925165154324

4.4 TOKEN动态获取

调用服务器的API接口都需要填写token,下面介绍如何通过账号信息动态获取token(正常的token时效性是24小时)。

帮助文档:https://support.huaweicloud.com/api-iam/iam_30_0001.html#section4

image-20230925170016192

请求地址:

POST https://iam.<服务ID>.myhuaweicloud.com/v3/auth/tokens

请求参数:

{"auth": {"identity": {"methods": ["password"],"password": {"user": {"domain": {"name": "IAMDomain"        //IAM用户所属帐号名(华为云的主账号)},"name": "IAMUser",             //IAM用户名(刚才创建的)"password": "IAMPassword"      //IAM用户密码(刚才创建的)}}},"scope": {"project": {"name": "cn-north-1"               //服务ID(创建产品时创建的)}}}
}

Qt编写的示例代码:

/*
功能: 获取token
*/
void Widget::GetToken()
{QString requestUrl;QNetworkRequest request;//设置请求地址QUrl url;//获取token请求地址requestUrl = QString("https://iam.%1.myhuaweicloud.com/v3/auth/tokens").arg(SERVER_ID);//自己创建的TCP服务器,测试用//requestUrl="http://10.0.0.6:8080";//设置数据提交格式request.setHeader(QNetworkRequest::ContentTypeHeader, QVariant("application/json;charset=UTF-8"));//构造请求url.setUrl(requestUrl);request.setUrl(url);QString text =QString("{\"auth\":{\"identity\":{\"methods\":[\"password\"],\"password\":""{\"user\":{\"domain\": {""\"name\":\"%1\"},\"name\": \"%2\",\"password\": \"%3\"}}},""\"scope\":{\"project\":{\"name\":\"%4\"}}}}").arg(MAIN_USER).arg(IAM_USER).arg(IAM_PASSWORD).arg(SERVER_ID);//发送请求manager->post(request, text.toUtf8());
}

4.5 规则转发

为了能让自己的私有服务器收到设备的状态变化,可以在华为云物联网服务器上创建转发规则。

(1)创建规则

image-20230925170635632

填充规则转发的信息:

参数名参数说明
规则名称自定义,如: led_obs。
规则描述自定义,如数据转发至OBS服务。
数据来源选择“设备属性”。
触发事件自动匹配“设备属性上报”。
资源空间和上一步创建的产品所在的资源空间保持一致。

(2)创建属性:设备上报消息时触动转发规则

image-20230925170830858

image-20230925170914880

image-20230925170929848

(3)添加转发规则

可以根据自己的需求设置目的地址。

image-20230925170959685

如果自己有私有服务器,创建转发规则即可。

image-20230925171126233

五、硬件端代码开发

5.1 E29 Cat-1模块

全网通E29 Cat-1 支持多种协议基于4G网络,具有速度快,延迟低等特点,Cat-1相比于4G有具有更低的功耗。全网通E29Cat-1模块的特点:
1.TAS-E29 Cat-1全网通芯片
2.4G全网通Cat-1芯片
3.支持TCP/UDP/MQTT/HTTP等多种协议
4.基于4G网络,网络速度快
5.功耗比4G芯片低40%
6.支持标准AT指令、短信透传
7.中英文短信透传/配置
8.支持LBS基站定位
9.modbus轮询技术、自定义心跳包、注册包。

5.2 4G模块与MQTT服务器交互常用的AT指令

AT:检查模块是否正常工作并响应AT指令。AT+CGATT:激活或取消激活GPRS附着。在使用EC20模块进行网络通信之前,需要先激活GPRS附着。AT+CIPSHUT:关闭移动场景TCP/IP连接。使用该指令可以关闭之前建立的TCP连接。AT+CIPSTART:建立TCP或UDP连接到远程服务器。对于MQTT协议,首先需要使用AT+CIPSTART建立到MQTT服务器的TCP连接。AT+CIPSEND:发送数据到TCP或UDP连接。对于MQTT协议,您可以使用该指令发送MQTT数据包,例如订阅主题、发布消息等。AT+CIPCLOSE:关闭TCP或UDP连接。AT+CMQTTUSR:设置MQTT连接的用户名。AT+CMQTTPASS:设置MQTT连接的密码。AT+CMQTTACCQ:设置MQTT连接的客户端ID。AT+CMQTTCONN:连接到MQTT服务器。在设置好MQTT连接参数后,使用该指令进行连接。AT+CMQTTPUB:发布MQTT消息。使用该指令发布消息到指定的主题。AT+CMQTTSUB:订阅MQTT主题。使用该指令订阅感兴趣的主题,当有消息发布到该主题时,EC20模块会收到相应的回调。AT+CMQTTUNS:取消订阅MQTT主题。使用该指令取消已经订阅的主题。

5.3 MQTT连接主要代码

核心代码模板:

// 引入必要的库
#include <reg51.h>
#include <string.h>// 定义串口通信相关的寄存器地址
#define UART_BAUD_RATE_H 0xFD // 波特率高位
#define UART_BAUD_RATE_L 0xFE // 波特率低位
#define UART_CONTROL_REG 0x98 // 控制寄存器地址// 定义MQTT服务器信息
#define MQTT_SERVER "mqtt.example.com" // MQTT服务器地址
#define MQTT_PORT "1883" // MQTT端口号// 定义设备ID和认证信息
#define DEVICE_ID "your_device_id" // 设备ID
#define USERNAME "your_username" // 用户名
#define PASSWORD "your_password" // 密码// 定义订阅和发布的主题
#define SUBSCRIBE_TOPIC "your_subscribe_topic" // 订阅主题
#define PUBLISH_TOPIC "your_publish_topic" // 发布主题// 定义MQTT协议相关指令
#define CONNECT_CMD "AT+CMQTTCONN=\"" MQTT_SERVER "\",\"" MQTT_PORT "\",\"" DEVICE_ID "\",\"" USERNAME "\",\"" PASSWORD "\"\r\n" // 连接指令
#define SUBSCRIBE_CMD "AT+CMQTTSUB=\"" SUBSCRIBE_TOPIC "\",1\r\n" // 订阅指令
#define PUBLISH_CMD "AT+CMQTTPUB=\"" PUBLISH_TOPIC "\",0,0,0,\"your_message\"\r\n" // 发布指令// 定义串口发送函数
void UART_SendString(char *str) {while (*str) {SBUF = *str;while (!TI);TI = 0;str++;}
}// 主函数
void main() {// 配置串口通信波特率为9600bpsPCON = 0x00;TMOD = 0x20;TH1 = UART_BAUD_RATE_H;TL1 = UART_BAUD_RATE_L;TR1 = 1;SCON = UART_CONTROL_REG;// 连接MQTT服务器UART_SendString(CONNECT_CMD);// 等待连接成功的回复// 编写等待回复的代码// 订阅主题UART_SendString(SUBSCRIBE_CMD);// 等待订阅成功的回复// 编写等待回复的代码// 设备登录成功,进入循环while (1) {// 定时上报数据,可以根据需求设置时间间隔// 这里使用延时函数模拟时间间隔delay(5000); // 上报数据到指定主题UART_SendString(PUBLISH_CMD);// 等待上报完成的回复// 编写等待回复的代码}
}

4.4 锁控制代码

// 引入必要的库
#include <reg51.h>
#include <string.h>// 定义串口通信相关的寄存器地址
#define UART_BAUD_RATE_H 0xFD // 波特率高位
#define UART_BAUD_RATE_L 0xFE // 波特率低位
#define UART_CONTROL_REG 0x98 // 控制寄存器地址// 定义MQTT服务器信息
#define MQTT_SERVER "mqtt.example.com" // MQTT服务器地址
#define MQTT_PORT "1883" // MQTT端口号// 定义设备ID和认证信息
#define DEVICE_ID "your_device_id" // 设备ID
#define USERNAME "your_username" // 用户名
#define PASSWORD "your_password" // 密码// 定义订阅主题
#define SUBSCRIBE_TOPIC "your_subscribe_topic" // 订阅主题// 定义电磁锁的IO口连接图纸
#define LOCK_1 P2_0 // 电磁锁1的控制IO口
#define LOCK_2 P2_1 // 电磁锁2的控制IO口
#define LOCK_3 P2_2 // 电磁锁3的控制IO口
#define LOCK_4 P2_3 // 电磁锁4的控制IO口
#define LOCK_5 P2_4 // 电磁锁5的控制IO口
#define LOCK_6 P2_5 // 电磁锁6的控制IO口
#define LOCK_7 P2_6 // 电磁锁7的控制IO口
#define LOCK_8 P2_7 // 电磁锁8的控制IO口
#define LOCK_9 P3_0 // 电磁锁9的控制IO口
#define LOCK_10 P3_1 // 电磁锁10的控制IO口
#define LOCK_11 P3_2 // 电磁锁11的控制IO口
#define LOCK_12 P3_3 // 电磁锁12的控制IO口// 定义MQTT协议相关指令
#define CONNECT_CMD "AT+CMQTTCONN=\"" MQTT_SERVER "\",\"" MQTT_PORT "\",\"" DEVICE_ID "\",\"" USERNAME "\",\"" PASSWORD "\"\r\n" // 连接指令
#define SUBSCRIBE_CMD "AT+CMQTTSUB=\"" SUBSCRIBE_TOPIC "\",1\r\n" // 订阅指令// 定义串口发送函数
void UART_SendString(char *str) {while (*str) {SBUF = *str;while (!TI);TI = 0;str++;}
}// 电磁锁控制函数
void controlLock(int lockNumber, int lockState) {switch (lockNumber) {case 3:// 控制电磁锁3if (lockState == 1) {// 打开电磁锁LOCK_3 = 1;} else {// 关闭电磁锁LOCK_3 = 0;}break;case 4:// 控制电磁锁4if (lockState == 1) {// 打开电磁锁LOCK_4 = 1;} else {// 关闭电磁锁LOCK_4 = 0;}break;case 5:// 控制电磁锁5if (lockState == 1) {// 打开电磁锁LOCK_5 = 1;} else {// 关闭电磁锁LOCK_5 = 0;}break;case 6:// 控制电磁锁6if (lockState == 1) {// 打开电磁锁LOCK_6 = 1;} else {// 关闭电磁锁LOCK_6 = 0;}break;case 7:// 控制电磁锁7if (lockState == 1) {// 打开电磁锁LOCK_7 = 1;} else {// 关闭电磁锁LOCK_7 = 0;}break;case 8:// 控制电磁锁8if (lockState == 1) {// 打开电磁锁LOCK_8 = 1;} else {// 关闭电磁锁LOCK_8 = 0;}break;case 9:// 控制电磁锁9if (lockState == 1) {// 打开电磁锁LOCK_9 = 1;} else {// 关闭电磁锁LOCK_9 = 0;}break;case 10:// 控制电磁锁10if (lockState == 1) {// 打开电磁锁LOCK_10 = 1;} else {// 关闭电磁锁LOCK_10 = 0;}break;case 11:// 控制电磁锁11if (lockState == 1) {// 打开电磁锁LOCK_11 = 1;} else {// 关闭电磁锁LOCK_11 = 0;}break;case 12:// 控制电磁锁12if (lockState == 1) {// 打开电磁锁LOCK_12 = 1;} else {// 关闭电磁锁LOCK_12 = 0;}break;default:// 锁编号无效break;
}}// 主函数
void main() {// 配置串口通信波特率为9600bpsPCON = 0x00;TMOD = 0x20;TH1 = UART_BAUD_RATE_H;TL1 = UART_BAUD_RATE_L;TR1 = 1;SCON = UART_CONTROL_REG;// 连接MQTT服务器UART_SendString(CONNECT_CMD);// 等待连接成功的回复// 编写等待回复的代码// 订阅主题UART_SendString(SUBSCRIBE_CMD);// 等待订阅成功的回复// 编写等待回复的代码// 设备登录成功,进入循环while (1) {// 接收到MQTT消息后,解析并控制对应的电磁锁// 编写接收和解析MQTT消息的代码// 设备接收到的消息格式为 "LOCK_X_ON" 或 "LOCK_X_OFF",其中 X 为电磁锁编号// 解析消息,并提取电磁锁编号和状态int lockNumber; // 电磁锁编号int lockState; // 电磁锁状态,0表示关闭,1表示打开if (strncmp(receivedMessage, "LOCK_", 5) == 0) {lockNumber = receivedMessage[5] - '0'; // 提取锁编号if (strstr(receivedMessage, "ON") != NULL) {lockState = 1; // 提取锁状态,ON表示打开} else if (strstr(receivedMessage, "OFF") != NULL) {lockState = 0; // 提取锁状态,OFF表示关闭}// 控制对应的电磁锁controlLock(lockNumber, lockState);}}
}

六、总结

这款基于单片机设计的智能储物柜是一种应用于游乐场、商场和景区等场所的便捷储物解决方案。用户可以通过微信小程序实时查看储物柜的可用状态,并选择指定柜子进行解锁。

该智能储物柜支持4G联网,采用主控芯片STC12C5A60S2和4G联网模块E29 Cat-1来实现与网络的连接。用户在解锁储物柜时需要支付押金(预付金),随后系统开始计时并按照使用的时间进行收费。储物柜也支持临时解锁和存取物品功能。用户完成使用后,可以通过微信小程序完成订单结算。

储物柜的锁采用电磁锁技术,通过控制相应的IO口来实现开锁或关锁。整体而言,该智能储物柜以单片机为核心,集成了4G通信模块、电磁锁和华为云物联网服务器等技术,提供方便、安全的储物服务。每个储物柜都是一个独立的设备,通过华为云物联网服务器实现数据传输和管理。

基于单片机设计的智能储物柜在不同场所为用户提供便捷的储物解决方案,通过技术的融合和应用,提升用户体验和管理效率。

相关文章:

基于物联网设计的智能储物柜(4G+华为云IOT+微信小程序)

一、项目介绍 在游乐场、商场、景区等人流量较大的地方&#xff0c;往往存在用户需要临时存放物品的情况&#xff0c;例如行李箱、外套、购物袋等。为了满足用户的储物需求&#xff0c;并提供更加便捷的服务体验&#xff0c;当前设计了一款物联网智能储物柜。 该智能储物柜通…...

12种常见的网络钓鱼

网络钓鱼是一种网络攻击&#xff0c;是指具有恶意动机的攻击者伪装欺骗人们并收集用户名或密码等敏感信息的一系列行为。由于网络钓鱼涉及心理操纵并依赖于人为失误(而不是硬件或软件漏洞)&#xff0c;因此被认定为是一种社会工程攻击。 1. 普通网络钓鱼&#xff08;群攻&…...

电商物流查询:未来的发展方向

在电商日益繁荣的时代&#xff0c;物流信息查询不仅关乎消费者体验&#xff0c;更影响着电商运营的效率。快速、准确地追踪物流信息至关重要。本文将简述物流信息快速追踪的价值&#xff0c;并重点介绍固乔快递查询助手这一高效查询工具及其批量查询功能。 一、物流信息快速追踪…...

【数据库原理】(25)数据完整性

一.完整性概述 数据库的完整性是保证数据正确性和一致性的关键。它防止数据库中存在不符合业务逻辑或语义规则的数据&#xff0c;避免错误信息的输入和输出。数据库的完整性和安全性不同&#xff0c;安全性关注的是防止非法用户的访问和恶意操作&#xff0c;而完整性则关注数据…...

逻辑运算符

逻辑运算符 什么是逻辑运算符&#xff1f; 在数学中&#xff0c;一个数据x大于5&#xff0c;小于15&#xff0c;我们可以这样来进行表示&#xff1a;5<x<15.在Java中&#xff0c;需要把上面的式子先进行拆解&#xff0c;再进行合并表达。 拆解为&#xff1a;x>5和 x…...

SpringBoot @RequestBody和@ResponseBody注解

1. RequestBody注解 用于将HTTP请求体的内容绑定到方法的参数上。通常情况下&#xff0c;我们使用这个注解来处理POST请求&#xff0c;特别是传递JSON格式的数据。 例&#xff1a; PostMapping("/user") public ResponseEntity<String> createUser(RequestB…...

实验四:静态路由配置

实验四&#xff1a;静态路由配置 1. 静态路由 ( 一般配置 ) 【实验名称】静态路由配置 【实验目的】掌握静态路由的配置方法&#xff0c;理解路由表的作用和原理 【实验设备】路由器&#xff08; 2 台&#xff09;、计算机&#xff08; 2 台&#xff09;、交叉线&#xf…...

UML-类图和类图转化为代码

提示&#xff1a;文章详细的讲解了类图的四种关系&#xff0c;以及每种关系如何转化为对应的代码。 UML-类图和类图转化为代码 一、类于类之间的关系1.依赖关系2.关联关系(1) 单向关联(2) 双向关联(3) 自关联(4) 聚合关联(has-a)(5) 组合关联&#xff08;contains-a&#xff09…...

数据科学与大数据导论期末复习笔记(大数据)

来自于深圳技术大学&#xff0c;此笔记涵盖了期末老师画的重点知识&#xff0c;分享给大家。 等深分箱和等宽分箱的区别&#xff1a;等宽分箱基于数据的范围来划分箱子&#xff0c;每个箱子的宽度相等。等深分箱基于数据的观测值数量来划分箱子&#xff0c;每个箱子包含相同数量…...

【保姆级教程|YOLOv8添加注意力机制】【2】在C2f结构中添加ShuffleAttention注意力机制并训练

《博主简介》 小伙伴们好&#xff0c;我是阿旭。专注于人工智能、AIGC、python、计算机视觉相关分享研究。 ✌更多学习资源&#xff0c;可关注公-仲-hao:【阿旭算法与机器学习】&#xff0c;共同学习交流~ &#x1f44d;感谢小伙伴们点赞、关注&#xff01; 《------往期经典推…...

Hive聚合函数详细讲解

Hive中的聚合函数用于在数据上进行计算并返回单个值,这些值通常是基于一组行或列的汇总。以下是您提到的聚合函数的详细讲解,包括案例和使用注意事项: SUM() 功能:计算某列的总和。语法:SUM(column)案例:SELECT SUM(salary) FROM employees;注意事项:通常用于数值型列。…...

方案:如何列出 Jira 中授予用户的所有权限

文章目录 概述解决方案REST API数据库 概述 为了进行故障排除或某些管理任务&#xff0c;我们可能想知道给定用户拥有的所有权限。 Jira 通过其 UI 提供权限助手和类似工具&#xff0c;但对于所有权限的列表&#xff0c;我们只能通过作为用户本身进行身份验证的 REST API 请求…...

Flutter-Web从0到部署上线(实践+埋坑)

本文字数&#xff1a;7743字 预计阅读时间&#xff1a;60分钟 01 前言 首先说明一下&#xff0c;这篇文章是给具备Flutter开发经验的客户端同学看的。Flutter 的诞生虽然来自 Google 的 Chrome 团队&#xff0c;但大家都知道 Flutter 最先支持的平台是 Android 和 iOS&#xff…...

Redis键值设计

文章目录 1.优雅的key2.拒绝BigKey2.1.什么是BigKey2.2.BigKey的危害2.3.如何发现BigKey2.4.如何删除BigKey 3.恰当的数据类型 1.优雅的key 2.拒绝BigKey 2.1.什么是BigKey 2.2.BigKey的危害 2.3.如何发现BigKey scan扫描示例代码 final static int STR_MAX_LEN 10 * 1024;fi…...

CSS 下载进度条

<template><view class=btn>下载中</view></template><script></script><style>/* 设置整个页面的样式 */body {width: 100vw; /* 页面宽度为视口宽度 */background: #000000; /* 背景颜色为白色 */display: flex; /* 使用 flex…...

风力发电防雷监测浪涌保护器的应用解决方案

风力发电是一种利用风能转化为电能的可再生能源技术&#xff0c;具有清洁、环保、低碳的优点&#xff0c;是应对全球气候变化和能源危机的重要途径之一。然而&#xff0c;风力发电也面临着一些技术和经济的挑战&#xff0c;其中之一就是雷电的威胁。由于风力发电机组通常位于高…...

开发安全之:Database access control

Overview 如果没有适当的 access control&#xff0c;就会执行一个包含用户控制主键的 SQL 指令&#xff0c;从而允许攻击者访问未经授权的记录。 Details Database access control 错误在以下情况下发生&#xff1a; 1. 数据从一个不可信赖的数据源进入程序。 2. 这个数据用…...

VMware Vsphere 日志:用户 dcui@127.0.01已以vMware-client/6.5.0 的身份登录

一、事件截图&#xff1a; 二、解决办法 原因&#xff1a; 三、解决办法 1.开启锁定模式 2.操作 1、从清单中选择您的 ESXi 主机&#xff0c;然后转至管理 > 设置 > 安全配置文件&#xff0c;然后单击锁定模式的编辑按钮 2、在打开的锁定模式窗口中&#xff0c;选中启…...

全面了解网络性能监测:从哪些方面进行监测?

目录 摘要 引言 CPU内存监控 磁盘监控 网络监控 GPU监控 帧率监控 总结 摘要 本文介绍了网络性能监测的重要性&#xff0c;并详细介绍了一款名为克魔助手的应用开发工具&#xff0c;该工具提供了丰富的性能监控功能&#xff0c;包括CPU、内存、磁盘、网络等指标的实时监…...

智能分析网关V4基于AI视频智能分析技术的周界安全防范方案

一、背景分析 随着科技的不断进步&#xff0c;AI视频智能检测技术已经成为周界安全防范的一种重要手段。A智能分析网关V4基于深度学习和计算机视觉技术&#xff0c;可以通过多种AI周界防范算法&#xff0c;实时、精准地监测人员入侵行为&#xff0c;及时发现异常情况并发出警报…...

YSYX学习记录(八)

C语言&#xff0c;练习0&#xff1a; 先创建一个文件夹&#xff0c;我用的是物理机&#xff1a; 安装build-essential 练习1&#xff1a; 我注释掉了 #include <stdio.h> 出现下面错误 在你的文本编辑器中打开ex1文件&#xff0c;随机修改或删除一部分&#xff0c;之后…...

PL0语法,分析器实现!

简介 PL/0 是一种简单的编程语言,通常用于教学编译原理。它的语法结构清晰,功能包括常量定义、变量声明、过程(子程序)定义以及基本的控制结构(如条件语句和循环语句)。 PL/0 语法规范 PL/0 是一种教学用的小型编程语言,由 Niklaus Wirth 设计,用于展示编译原理的核…...

leetcodeSQL解题:3564. 季节性销售分析

leetcodeSQL解题&#xff1a;3564. 季节性销售分析 题目&#xff1a; 表&#xff1a;sales ---------------------- | Column Name | Type | ---------------------- | sale_id | int | | product_id | int | | sale_date | date | | quantity | int | | price | decimal | -…...

【JavaSE】绘图与事件入门学习笔记

-Java绘图坐标体系 坐标体系-介绍 坐标原点位于左上角&#xff0c;以像素为单位。 在Java坐标系中,第一个是x坐标,表示当前位置为水平方向&#xff0c;距离坐标原点x个像素;第二个是y坐标&#xff0c;表示当前位置为垂直方向&#xff0c;距离坐标原点y个像素。 坐标体系-像素 …...

Linux --进程控制

本文从以下五个方面来初步认识进程控制&#xff1a; 目录 进程创建 进程终止 进程等待 进程替换 模拟实现一个微型shell 进程创建 在Linux系统中我们可以在一个进程使用系统调用fork()来创建子进程&#xff0c;创建出来的进程就是子进程&#xff0c;原来的进程为父进程。…...

docker 部署发现spring.profiles.active 问题

报错&#xff1a; org.springframework.boot.context.config.InvalidConfigDataPropertyException: Property spring.profiles.active imported from location class path resource [application-test.yml] is invalid in a profile specific resource [origin: class path re…...

C#中的CLR属性、依赖属性与附加属性

CLR属性的主要特征 封装性&#xff1a; 隐藏字段的实现细节 提供对字段的受控访问 访问控制&#xff1a; 可单独设置get/set访问器的可见性 可创建只读或只写属性 计算属性&#xff1a; 可以在getter中执行计算逻辑 不需要直接对应一个字段 验证逻辑&#xff1a; 可以…...

(一)单例模式

一、前言 单例模式属于六大创建型模式,即在软件设计过程中,主要关注创建对象的结果,并不关心创建对象的过程及细节。创建型设计模式将类对象的实例化过程进行抽象化接口设计,从而隐藏了类对象的实例是如何被创建的,封装了软件系统使用的具体对象类型。 六大创建型模式包括…...

Chrome 浏览器前端与客户端双向通信实战

Chrome 前端&#xff08;即页面 JS / Web UI&#xff09;与客户端&#xff08;C 后端&#xff09;的交互机制&#xff0c;是 Chromium 架构中非常核心的一环。下面我将按常见场景&#xff0c;从通道、流程、技术栈几个角度做一套完整的分析&#xff0c;特别适合你这种在分析和改…...

数据结构:递归的种类(Types of Recursion)

目录 尾递归&#xff08;Tail Recursion&#xff09; 什么是 Loop&#xff08;循环&#xff09;&#xff1f; 复杂度分析 头递归&#xff08;Head Recursion&#xff09; 树形递归&#xff08;Tree Recursion&#xff09; 线性递归&#xff08;Linear Recursion&#xff09;…...