STM32进阶学习(1)-ESP01-S的AT指令测试、MQTT原理


一、什么是ESP01-S

在这里插入图片描述
如图,不多解释了。
参数:
在这里插入图片描述
这里注意的是,频谱范围是2.4GHZ,所以连接WIFI时只支持2.4HGZ的频段,不支持5Ghz频段。另外,供电是3.3V,这里让单片机给其供电即可。
电路图:
在这里插入图片描述

二、使用AT指令进行测试

拿到手的ESP01S,首先要验证其功能是否正常,这里我用ESP01S连接USB转串口模块,并与电脑上的串口调试助手进行通信。

1.AT指令

AT命令组成和通讯过程
AT命令由三个部分组成,分别是前缀、主体和结束符。其中前缀由字符 AT 构成;主体由命令、参数和可能用到的数据组成;结束符一般为 (“\r\n”)。

比如 AT+CWMODE=3\r\n 这条命令,AT就是前缀,中间就是主体部分,\r\n 就是结束符。

AT命令通讯过程的实现,需要AT Client 和 AT Server 两部分共同完成。

AT客户端和AT服务器之间硬件通讯接口,一般最常用的是串口,也有SPI接口等。

AT Client主要作用是主动发送AT命令,然后等待AT Server的响应数据,并对响应数据或者AT Server主动发送的数据(即URC数据)进行解析。

AT Server 返回给 AT Client 的数据有两种。命令响应数据和 URC 数据(unsolicited result code)。

命令响应数据:AT Client 发送命令后 AT Server 回应的响应状态和信息。

URC数据:AT Server 主动发送给 AT Client 的数据。比如 AT Server接收到网络的数据后,会主动把这些数据发送给 AT Client ,又或者 WIFI 断开连接等,也会主动发数据告知 AT Client。

2.基于ESP01的AT指令

命令功能
AT回复OK。主要用于查询模块是否正常工作
AT+RST复位模块
ATE0/ATE1关闭/打开命令回显功能
AT+CWMODE=1设置WIFI模式为 WIFI station 模式
AT+GMR获取模块版本信息
AT+CIFSR查询模块IP地址
AT+CIPMUX=0/10:单连接。1:开启多连接。这时可以支持多个TCP客户端接入模块(模块作为TCP Server)。当使能了多连接之后,后面的有些指令就要带上连接号了,不然模块会识别为错误的AT指令。
AT+CWJAP=“SSID”,“password”连接WIFI。SSID是WIFI名称,password是WIFI密码。
AT+CIPSTART=“TCP”,“192.168.0.102”,8080ESP8266作为TCP Client连接到TCP服务器。TCP代表协议,192.168.0.102是服务器IP,8080是服务器端口。
AT+CIPSEND=nESP8266模块向TPC Server发送数据,n表示要发送多少个字节。如果这条命令发送成功的话,会回复 OK 然后接着下一行回复 ‘>’ 这个符号。然后再接着向模块写入n字节数据(超过n字节的话,会丢弃超过的数据),这个时候就相当于发送出去了。如果回复 SEND OK 表示发送成功,回复 SEND FAIL 表示发送失败。
+IPD,n:xxxxxxxxxxx当模块接收到 TCP Server 发送的数据时,会回复这条数据给主芯片(AT Client)。其中n,表示接收到了n字节,: 号后面就是 TCP Server 实际发送过来的数据。
AT+CIPCLOSEESP8266模块断开与 TCP Server 的网络连接。
AT+CWQAPESP8266模块断开 WIFI 连接。

3.测试

打开串口调试助手,
在这里插入图片描述
AT+GMR指令用于获取ESP8266模块的固件版本号和SDK版本号。根据返回信息,可以得到以下信息:

AT version:模块使用的AT指令版本号,这里是2.3.0.0-dev。
SDK version:模块使用的SDK版本号,这里是v3.4-22-g967752e2。
compile time:固件编译日期和时间,这里是Jun 30 2021 11:28:20。
Bin version:ESP8266模块的固件版本号,这里是2.2.0(ESP8266_1MB)。
通过这些信息,可以了解ESP8266模块的软件版本和开发时间等信息。
在这里插入图片描述
AT+CIFSR指令用于获取ESP8266模块的IP地址。根据返回信息,可以得到以下信息:
busy p…:这个表示模块正在忙碌中,可能是在连接WiFi网络或者建立TCP连接等操作。
+CIFSR:APIP,“192.168.4.1”:这个表示模块当前的IP地址是192.168.4.1,这是一个局域网IP地址,通常用于ESP8266模块作为WiFi热点时的地址。
+CIFSR:APMAC,“ae:0b:fb:f6:98:22”:这个表示模块当前的MAC地址是ae:0b:fb:f6:98:22,MAC地址是网络通信中用于识别设备的唯一标识符。
根据返回信息,可以看出ESP8266模块当前作为WiFi热点工作,并且其IP地址是192.168.4.1。

三、MQTT协议

1.MQTT协议是什么?

MQTT(Message Queue Telemetry Transport)是一种轻量级的、基于发布/订阅模式的消息传输协议,主要用于物联网设备与服务器之间的通信。MQTT协议最初由IBM公司开发,目前已经成为一种开放的、国际标准的协议。

MQTT协议的特点如下:
轻量级:MQTT协议设计非常简洁,传输的消息头部非常小,可以在网络带宽较小的情况下快速传输数据。
发布/订阅模式:MQTT协议采用发布/订阅模式,可以将各种设备、传感器、应用程序等连接在一起,形成一个可扩展的网络。
QoS级别:MQTT协议支持三种QoS级别,可以确保消息的可靠传输。QoS 0表示最多一次传输,QoS 1表示至少一次传输,QoS 2表示恰好一次传输。
保留消息:MQTT协议支持保留消息,可以将最新的消息保留在服务器上,以供新的订阅者使用。
遗嘱消息:MQTT协议支持遗嘱消息,可以在客户端异常断开时,向服务器发送一条遗嘱消息,以通知其他客户端。
安全性:MQTT协议支持TLS/SSL加密传输,可以确保消息的安全性。

2.topic和payload

MQTT协议中的消息由两个部分组成:topic和payload。其中,topic表示消息的主题,payload表示消息的内容。

Topic是一个字符串,用于标识消息的主题。在MQTT中,topic采用树形结构组织,以“/”分隔不同的层级。例如,一个topic可以是“/sensors/temperature”,表示温度传感器的数据。在订阅和发布消息时,需要指定相应的topic。

Payload是消息的内容,可以是任意格式的数据。在MQTT中,payload可以是二进制数据、JSON数据、XML数据等,具体格式由应用程序自行定义。Payload的大小可以根据实际情况进行调整,通常建议不要超过最大的消息限制。

在MQTT中,订阅者可以订阅多个不同的topic,以接收不同的消息。当一个消息被发布时,MQTT服务器会将该消息转发给所有订阅了相应topic的客户端。这种发布/订阅的模式可以实现一对多的消息传输,使得MQTT协议具有很强的扩展性和灵活性。

3.MCU如何利用MQTT协议?

首先,传感器要采集数据,可以用各种模块采集比如温湿度、光照强度、距离等等数据。

然后,将数据与主题等信息按照特定的格式打包成MQTT协议包。

接着,通过TCP传输到MQTT服务器上。

下一步,MQTT服务器根据主题和信息向订阅了此主题的设备发送MQTT协议包。

最后,接收端按照规则解析协议包,并提取数据。

4.MQTT的服务器、客户端

在MQTT协议通讯中,有两个最为重要的角色。它们分别是服务端和客户端。首先我们来初步了解一下它们。

MQTT服务端
MQTT服务端通常是一台服务器。它是MQTT信息传输的枢纽,负责将MQTT客户端发送来的信息传递给MQTT客户端。MQTT服务端还负责管理MQTT客户端。确保客户端之间的通讯顺畅,保证MQTT消息得以正确接收和准确投递。

MQTT客户端
MQTT客户端可以向服务端发布信息,也可以从服务端收取信息。我们把客户端发送信息的行为成为“发布”信息。而客户端要想从服务端收取信息,则首先要向服务端“订阅”信息。“订阅”信息这一操作很像我们在视频网站订阅某一部电视剧。当这部电视剧上新后,视频网站会向订阅了该剧的用户发送信息,告诉他们有新剧上线了。

MQTT主题
刚刚我们在讲解MQTT客户端订阅信息时,使用了用户在视频网站订阅电视剧这个例子。在MQTT通讯中,客户端所订阅的肯定不是一部部电视剧,而是一个个“主题”。MQTT服务端在管理MQTT信息通讯时,就是使用“主题”来控制的。

1.如何让客户端连接到服务器端?

首先MQTT客户端将会向服务端发送连接请求。该请求实际上是一个包含有连接请求信息的数据包。这个数据包的官方名称为CONNECT。
在这里插入图片描述

MQTT服务端收到客户端连接请求后,会向客户端发送连接确认。同样的,该确认也是一个数据包。这个数据包官方名称为CONNACK。
在这里插入图片描述

以上就是MQTT客户端在连接服务端的两步操作。接下来,我们一起来了解一下客户端在连接服务端时所发送的CONNECT报文内容。

CONNECT – 连接服务端
在上面的描述中我们看到。MQTT客户端要想连接服务端,首先要向服务端发送CONNECT报文。如果此CONNECT报文的格式或内容不符合MQTT规范,则服务器会拒绝客户端的连接请求。

下图是CONNECT报文所包含的信息内容。
在这里插入图片描述

所谓报文就是一个MQTT数据包。这个数据包中可能包含有多个信息。比如以上图片就是描绘了一个CONNECT报文(数据包)的详细内容。

在这个CONNECT报文(数据包)中包含有多个信息。上图左侧栏中的内容是CONNECT报文所包含的信息名称。右侧是信息的具体内容。如上图示例中,此CONNECT报文包含有名称为clientId的信息,该信息的内容是”client-1″。当然,上图只是一个示例,不是所有的CONNECT报文中的clientId信息内容都是”client-1″。

另外也请注意,上图中有些信息名称旁边标注了“可选”字样,而有些则没有。那些没有标注“可选”字样的信息是必须包含在CONNECT报文中的。而对于标注了“可选”字样的信息,CONNECT报文既可以包含它们也可以没有它们。

(1)CONNECT报文具体内容

clientId – 客户端ID
ClientId是MQTT客户端的标识。MQTT服务端用该标识来识别客户端。因此ClientId必须是独立的。如果两个MQTT客户端使用相同ClientId标识,服务端会把它们当成同一个客户端来处理。通常ClientId是由一串字符所构成的,如上图所示,此示例中的clientID是“client-1”。

cleanSession – 清除会话
所谓“清除会话”这一翻译源自MQTT官方文档中文版。要说明cleanSession的具体含义,首先要从MQTT网络环境讲起。MQTT客户端与服务端的连接可能不是非常稳定,在不稳定的网络环境下,要想保证所有信息传输都能够做到准确无误,这是非常困难的。因此,我们就要根据客户端对系统运行的重要性来区别对待。有些MQTT客户端对整个系统运行起着关键作用,这些客户端一定要准确无误的收到服务端发来的报文。比如一辆自动驾驶汽车的导航系统。假如这个导航系统错过了服务端发来的报文,可能会导致交通事故甚至人员伤亡。因此,即使网络不是非常稳定,我们仍然要求汽车导航系统一定要准确无误的收到服务端所发来的报文。
但是有些MQTT客户端对整个系统运行并不是很重要。比如同样是这辆自动驾驶汽车。它的音乐播放系统如果没有及时收到服务端发来的音乐播放报文,这对驾驶系统来说影响不大。

以上所举的两个例子说明,MQTT通讯中有些客户端必须准确无误的收到报文,有些则不需要。
为了保证重要的MQTT报文可以被客户端准确无误的收到。在服务端向客户端发送报文后,客户端会向服务端返回一个确认报文。如果服务端没有收到客户端返回的确认报文,那么服务端就会认为刚刚发送给客户端的报文没有被准确无误的送达。在这种情况下,服务端将会执行以下两个操作:
操作1:将尚未被客户端确认的报文保存起来
操作2:再次尝试向客户端发送报文,并且再次等待客户端发来确认信息。
讲到这里就要看看cleanSession的作用了。
如果cleanSession 被设置为“true”。那么服务端不需要客户端确认收到报文,也不会保存任何报文。在这种情况下,即使客户端错过了服务端发来的报文,也没办法让服务端再次发送报文。其实我们从字面上也很容易理解。cleanSession 的第一个词是clean。这个词的意思是clean(干净)的。服务端一旦发送完报文,就会把报文忘得“干干净净”了。
反过来,如果我们将cleanSession 设置为”false”。那么服务端就知道,后续通讯中,客户端可能会要求我保存没有收到的报文
从以上的描述不难看出,如果某个客户端用于收发非常重要的信息(比如前文示例中汽车自动驾驶系统),那么该客户端在连接服务端时,应该将cleanSession设置为”false”*。这样才能让服务端保存那些没有得到客户端接收确认的信息。以便服务端再次尝试将这些重要信息再次发送给客户端。
相反的,如果某个客户端用于收发不重要的信息(比如前文示例中车载音乐系统)那么该客户端在连接服务端时,应该将cleanSession设置为”true”。
请注意,如果需要服务端保存重要报文,光设置cleanSession 为false是不够的,还需要传递的MQTT信息QoS级别大于0。
如果想让服务器记住重要报文,那么客户端在连接服务端时,需要把cleanSession中设置为false。这一点非常关键,请务必牢记。

keepAlive – 心跳时间间隔

MQTT服务端运行过程中,当有客户端因为某种原因断开了与服务端的连接,服务端需要实时了解这一情况。KeepAlive (心跳时间间隔)正是用于服务端了解客户端连接情况的。不过关于KeepAlive (心跳时间间隔)目前讲解还为时过早,我们会在后续的课程中给您做详细介绍。目前您只需要记住,KeepAlive用于服务端实时了解客户端是否与其保持连接的情况。

(2)CONNACK报文详细内容。

CONNACK – 确认连接请求
下图是CONNACK报文所包含的信息内容。
在这里插入图片描述

returnCode – 连接返回码

当服务端收到了客户端的连接请求后,会向客户端发送returnCode(连接返回码),用以说明连接情况。如果客户端与服务端成功连接,则返回数字“0”。如果未能成功连接,连接返回码将会是一个非零的数值,具体这个数值的含义,请见下表:

返回码返回码描述
0成功连接
1连接被服务端拒绝,原因是不支持客户端的MQTT协议版本
2连接被服务端拒绝,原因是不支持客户端标识符的编码。可能造成此原因的是客户端标识符编码是UTF-8,但是服务端不允许使用此编码。
3连接被服务端拒绝,原因是服务端不可用。即,网络连接已经建立,但MQTT服务不可用。
4连接被服务端拒绝,原因是用户名或密码无效。
5连接被服务端拒绝,原因是客户端未被授权连接到此服务端。

sessionPresent – 当前会话

要说明sessionPresent,首先我们要回顾一下CONNECT报文中的cleanSession – 清除会话。

我们还用自动驾驶汽车为例。对于自动驾驶汽车来说,自动导航系统属于非常重要的MQTT客户端。服务端发送给导航系统的报文必须要准确无误的送达。相反,音乐播放系统就不那么重要了。即使音乐播放系统错过服务端发送的报文也没有关系。

对于不重要的MQTT客户端,它们在向服务器发送连接请求时,CONNECT报文中的cleanSession通常设置为true。原因是这类不重要的MQTT客户端即使丢失信息也不会影响整体系统运行。因此服务端在看到客户端的cleanSession为true时,就不会保存发送给它们的信息。

然而对于汽车导航系统这类重要的MQTT客户端来说。当它在连接服务端时,cleanSession肯定时设置为false。原因是重要客户端需要服务端确保信息发送准确无误。如果服务端发现发送给重要客户端的信息没有得到确认,会将报文进行保存。

当重要客户端连接服务端时,服务端可能保存着没有得到确认的报文。如果是这样的话,那么客户端在连接服务端时,就会通过sessionPresent来了解服务端是否有之前未能确认的信息。

下面我们分几种情况来讲述sessionPresent的作用。

首先,当客户端发送的CONNECT报文中的cleanSession设置为true。在这种情况下,客户端是不需要服务端保存任何报文的。那么服务端发送的确认连接CONNACK报文中,sessionPresent肯定是false,也就是说,服务端没有保存任何报文。

当客户端发送的CONNECT报文中的cleanSession设置为false时,客户端是要求服务端保存报文的。在这种情况下,如果服务端的确保存了没有收到客户端接收确认的报文信息,那么cleanSession为true,否则为false。

简言之,CONNACK报文的sessionPresent与CONNECT报文的cleanSession相互配合。其作用是客户端发送连接请求时,服务端告知客户端有没有保存报文信息。这个被服务端保存的报文信息是来自于上一次客户端连接时,服务端曾经发送此报文给客户端,但是发送后没有收到客户端接收确认。

2.QOS等级

MQTT协议中定义了三个服务质量等级(QoS,Quality of Service),分别是QoS0、QoS1和QoS2。

QoS0:最多一次(At most once),消息发布者只发送一次消息,不保证消息能够被接收端接收到;
QoS1:最少一次(At least once),消息发布者保证消息至少被接收端接收一次,但可能会重复发送;
QoS2:恰好一次(Exactly once),消息发布者保证消息恰好被接收端接收一次,确保消息不会重复发送。
QoS等级越高,消息传输的可靠性越高,但同时也会增加网络通信的负担和延迟。在选择QoS等级时需要根据实际场景和需求进行选择。

5.用esp8266连接云平台,并上传温湿度数据,这到底属于发布主题还是订阅主题呢?

这属于发布主题。因为设备(esp8266)将温湿度数据发布到云平台,相当于发布了一个主题(topic),而在MQTT协议中,发布主题是由设备发起的。订阅主题则是由应用程序或服务发起的。

另外,esp8266订阅主题的场景,一般是在需要接收云平台或其他设备发送的指令或控制信号时使用。例如,一个智能家居系统中,esp8266作为控制设备,可以订阅云平台或其他设备发布的控制主题,接收控制指令并执行相应的操作,如打开灯、调节温度等。另外一个常见的场景是MQTT消息队列中间件的测试,esp8266可以订阅测试主题,接收和验证MQTT消息队列的功能是否正常。

总的来说,esp8266上传温湿度数据属于发布主题,接收云平台的控制指令属于订阅主题。

6.主题TOPIC和消息PAYLOAD

MQTT协议中,主题(Topic)是一个层级结构的字符串,用于标识消息的类型、内容或者目标。而消息(Message)则是实际传输的数据,包含了主题和负载(Payload),负载是消息的实际内容,可以是任何二进制数据。

简单来说,主题是消息的标识符,用于将相同类型或目标的消息归为一类,而消息则是具体传输的内容。可以把主题看作是消息的分类,而消息则是具体的数据。在MQTT中,发布者通过指定主题来发布消息,订阅者通过订阅主题来接收相应的消息。

7.用esp8266向云平台上传温湿度数据,怎么利用主题和消息呢?

在使用MQTT协议上传温湿度数据到云平台时,需要定义一个特定的主题(Topic),用于标识上传的数据类型。例如,您可以定义一个名为“temperature/humidity”的主题,用于上传温湿度数据。当esp8266上传温湿度数据时,需要将数据打包成一个消息(Message),并指定主题为“temperature/humidity”。

具体步骤如下:

①连接MQTT服务器:使用esp8266连接到MQTT服务器,建立连接。

②订阅主题:在连接成功后,esp8266可以订阅“temperature/humidity”主题,以便接收云平台的控制指令。

③上传数据:将温湿度数据打包成一个消息,并指定主题为“temperature/humidity”,通过MQTT协议上传到云平台。

④接收控制指令:如果云平台需要控制esp8266,可以通过MQTT协议发布一个控制指令,主题为“temperature/humidity”,esp8266会接收到这个消息并执行相应的操作。

总之,利用MQTT协议上传温湿度数据到云平台,需要定义一个特定的主题,并将上传的数据打包成一个消息,通过MQTT协议上传到云平台。同时,还需要订阅云平台发布的控制主题,以便接收控制指令。

  • 11
    点赞
  • 73
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
要利用ESP8266-01S将STM32连接到云上,需要进行以下步骤: 1. 在STM32上配置串口通信,将STM32与ESP8266-01S连接起来。 2. 在ESP8266-01S上配置WiFi连接,将ESP8266-01S连接到互联网。 3. 在ESP8266-01S上配置MQTT协议,将ESP8266-01S连接到MQTT服务器。 4. 在STM32上编写代码,利用MQTT协议将数据上传到MQTT服务器。 以下是STM32代码示例,可以通过MQTT协议将温度数据上传到MQTT服务器: ``` #include <stdio.h> #include <stdlib.h> #include <string.h> #include "MQTTClient.h" #define ADDRESS "tcp://mqtt.server.com:1883" #define CLIENTID "STM32_MQTT_Client" #define TOPIC "temperature" #define QOS 1 #define TIMEOUT 10000L int main(int argc, char* argv[]) { int temperature = 25; // 温度数据 Network network; MQTTClient client; MQTTClient_connectOptions conn_opts = MQTTClient_connectOptions_initializer; MQTTClient_message pubmsg = MQTTClient_message_initializer; MQTTClient_deliveryToken token; int rc = 0; NetworkInit(&network); MQTTClientInit(&client, &network, 10000, NULL, 0, NULL, 0); conn_opts.keepAliveInterval = 20; conn_opts.cleansession = 1; if ((rc = NetworkConnect(&network, ADDRESS, 1883)) != 0) { printf("Failed to connect to MQTT server, return code %d\n", rc); exit(-1); } if ((rc = MQTTClientConnect(&client, &conn_opts)) != MQTTCLIENT_SUCCESS) { printf("Failed to connect to MQTT server, return code %d\n", rc); exit(-1); } pubmsg.payload = (void *)&temperature; pubmsg.payloadlen = sizeof(temperature); pubmsg.qos = QOS; pubmsg.retained = 0; MQTTClient_publishMessage(client, TOPIC, &pubmsg, &token); rc = MQTTClient_waitForCompletion(client, token, TIMEOUT); MQTTClientDisconnect(client); NetworkDisconnect(&network); return 0; } ``` 以上代码仅供参考,实际应用中需要根据具体情况进行调整。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值