STM32学习(MCU控制)(WiFi and MQTT)

文章目录

    • [WiFi 和 MQTT 协议](#WiFi 和 MQTT 协议)
        • [1. 物联网组网](#1. 物联网组网)
        • [2. ESP 8266 WiFi 模块](#2. ESP 8266 WiFi 模块)
          • [2.1 原理图](#2.1 原理图)
          • [2.2 ESP8266 模块和 STM32 链接](#2.2 ESP8266 模块和 STM32 链接)
          • [2.3 AT 指令操作 WiFi 模块连接 AP 热点](#2.3 AT 指令操作 WiFi 模块连接 AP 热点)
        • [3. MQTT 协议](#3. MQTT 协议)
          • [3.1 MQTT 概述](#3.1 MQTT 概述)
          • [3.2 MQTT 相关技术内容](#3.2 MQTT 相关技术内容)
          • [3.3 MQTT 控制报文结构](#3.3 MQTT 控制报文结构)
            • [3.3.1 MQTT 报文组成部分](#3.3.1 MQTT 报文组成部分)
            • [3.3.2 Fixed header 固定报头](#3.3.2 Fixed header 固定报头)
          • [3.4 CONNECT -- 连接服务端](#3.4 CONNECT – 连接服务端)
            • [3.4.1 CONNECT 主要作用](#3.4.1 CONNECT 主要作用)
            • [3.4.2 CONNECT 数据包分析](#3.4.2 CONNECT 数据包分析)
            • [3.4.3 STM32 利用 ESP8266 连接 MQTT 流程](#3.4.3 STM32 利用 ESP8266 连接 MQTT 流程)
          • [3.5 PUBLISH -- 发布消息](#3.5 PUBLISH – 发布消息)
            • [3.5.1 发布消息 Topic](#3.5.1 发布消息 Topic)
            • [3.5.2 发布数据包分析](#3.5.2 发布数据包分析)
          • [3.6 SUBSCRIBE - 订阅主题](#3.6 SUBSCRIBE - 订阅主题)
            • [3.6.1 订阅主题 Topic](#3.6.1 订阅主题 Topic)
            • [3.6.2 订阅主题数据包分析](#3.6.2 订阅主题数据包分析)

WiFi 和 MQTT 协议

1. 物联网组网
  • 设备组网是通过一定技术手段,将设备可以在一定的范围内进行数据传递和操作控制。常见的组网设备
  • WiFi 4G/5G NB-IoT LoRa BlueTooth LwIP(以太网)
  • 联网之后的设备可以将数据上发到云端,同时可以从云端得到相关的数据内容。
    • 远程监控
    • 远程操作
    • 批量多路处理
2. ESP 8266 WiFi 模块
2.1 原理图

▪ 802.11 b/g/n

▪ Wi-Fi Direct (P2P)、soft-AP

▪ 内置TCP/IP协议栈

▪ 内置TR开关、balun、LNA、功率放大器和匹配网络

▪ 内置PLL、稳压器和电源管理组件

▪ 802.11b模式下+19.5dBm的输出功率

▪ ⽀支持天线分集

▪ 断电泄露电流小于10uA

▪ 内置低功率32位CPU:可以兼作应用处理器

▪ SDIO 2.0、 SPI、UART

▪ STBC、1x1 MIMO、2x1 MIMO

▪ A-MPDU 、A-MSDU的聚合和 0.4μs的保护间隔

▪ 2ms之内唤醒、连接并传递数据包

▪ 待机状态消耗功率小于1.0mW (DTIM3)

2.2 ESP8266 模块和 STM32 链接

ESP8266 模块对应的电路引脚情况

  • 重点关注 RXD 和 TXD
  • RXD 是用于接收 MCU 提供的 AT 指令
  • TXD 是用于反馈数据到 MCU ,包括 AT 指令响应,网络数据响应内容,主要数据形式为【字符串形式】,除了基本字符串格式,包括方便后续解析使用的 JSON 格式数据

当前开发板中,对应的板载链接效果

  • ESP8266 模块的 RXD ==> MCU USART3 TX ==> PB10
  • ESP8266 模块的 TXD ==> MCU USART3 RX ==> PB11
  • 需要通过配置 USART3 数据发送和接收,来进行 ESP8266 WiFi 模块控制,利用 USART3 TX 发送 AT 指令到 WiFi 模块,利用 USART3 RX 接受 WiFi 模块的反馈数据。
  • PB11 ==> RX 浮空输入模式
  • PB10 ==> TX 复用推挽模式
2.3 AT 指令操作 WiFi 模块连接 AP 热点

参考文档

c 复制代码
#include "ESP8266.h"

ESP8266_Data esp8266_val = {0};
void ESP8266_Init(void)
{
	/*
	1. 时钟使能
		需要进行使用内容有 GPIOB 和 USART3
		APB2ENR --> GPIOB
		APB1ENR --> USART3
	*/
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, ENABLE);
	
	/*
	2. 配置 GPIO
	*/
	GPIO_InitTypeDef GPIO_InitStructure;
	
	// PB11 --> RX 浮空输入模式
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
	GPIO_Init(GPIOB, &GPIO_InitStructure);
	
	// PB10 --> TX 复用推挽输出
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOB, &GPIO_InitStructure);
	
	/*
	3. 配置 USART3 工作模式
	*/
	USART_InitTypeDef USART_InitStructure;
	
	// 波特率
	USART_InitStructure.USART_BaudRate = 115200;
	// 软件控制
	USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
	// 8N1
	USART_InitStructure.USART_WordLength = USART_WordLength_8b;
	USART_InitStructure.USART_Parity = USART_Parity_No;
	USART_InitStructure.USART_StopBits = USART_StopBits_1;
	// 使能 RX 和 TX
	USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
	USART_Init(USART3, &USART_InitStructure);
	
	// USART3 开启工作
	USART_Cmd(USART3, ENABLE);
	
	/*
	4. USART3 对应的中断使能配置
	*/
	NVIC_InitTypeDef NVIC_InitStructure;
		
	/*
	分别开启 USART_IT_IDLE 和 USART_IT_RXNE 中断
	*/
	USART_ITConfig(USART3, USART_IT_IDLE, ENABLE);
	USART_ITConfig(USART3, USART_IT_RXNE, ENABLE);
	
	// 设置当前优先级组为 NVIC_PriorityGroup_2 2 个占先,2 个次级
	NVIC_SetPriorityGrouping(NVIC_PriorityGroup_2);
	
	NVIC_InitStructure.NVIC_IRQChannel = USART3_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;  // 占先优先级 0
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;         // 次级优先级 1
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
	
	NVIC_Init(&NVIC_InitStructure);
}

void USART3_IRQHandler(void)
{
	u16 val = 0;
	
	
	/*
	1. 处理 RXNE 中断
		接收数据缓冲区非空,需要进行接收数据处理
	2. 处理 IDLE 中断
		当前接收数据总线已空闲,数据接收完毕
	*/
	/*
	检测到数据总线空闲,表示数据接收完毕,进行展示处理,同时
	处理当前中断标志位
		IDLE 清除要求
			1. 读取 USARTx->SR
			2. 读取 USARTx->DR
	不建议使用 void USART_ClearFlag(USART_TypeDef* USARTx, uint16_t USART_FLAG)
	*/
	if (USART_GetITStatus(USART3, USART_IT_IDLE) == SET)
	{
		esp8266_val.flag = 1;
			
		val = USART3->SR;
		val = USART3->DR;
		
		USART1_SendBuffer(esp8266_val.data, esp8266_val.count);
	}
	/*
	如果 flag 为 1 表示以当前数据已进行后续处理,需要对当前占用的内存空间
	进行擦除操作,方便进入下一次数据接受
	*/
	if (esp8266_val.flag)
	{
		memset(&esp8266_val, 0, sizeof(ESP8266_Data));
	}
	
	if (USART_GetITStatus(USART3, USART_IT_RXNE) == SET)
	{
		// 从 USART3 读取数据,存储到 esp8266_val 结构中,同时赋值 data 存储数据
		// count 累加有效数据个数
		esp8266_val.data[esp8266_val.count++] = USART_ReceiveData(USART3);
	
		// 如果数据已满,利用 USART1 发送数据到 PC 串口调试工具
		if (esp8266_val.count == ESP8266_DATA_SIZE)
		{
			// USART1_SendBuffer(esp8266_val.data, esp8266_val.count);
			esp8266_val.flag = 1;
		}
	}
	
	
}

void ESP8266_SendByte(u8 byte) 
{
	while (USART_GetFlagStatus(USART3, USART_FLAG_TC) == RESET);
	
	USART_SendData(USART3, byte);
}

void ESP8266_SendBuffer(u8 *buffer, u16 count)
{
	while (count--)
	{
		ESP8266_SendByte(*buffer);
		buffer++;
	}
}

void ESP8266_SendString(const char * str)
{
	while (*str)
	{
		ESP8266_SendByte(*str);
		str++;
	}
}

void ESP8266_Send_AT(const char *cmd, const char *ack, u16 timeout)
{
	// 展示 AT 指令内容
	printf("AT cmd : %s", cmd);
	
	/*
	发送 AT 指令到 ESP8266
	*/
	ESP8266_SendString(cmd);
	
	/*
	ESP8266 会返回对应的响应信息,USART3 接收数据信息是通过
	USART3_IRQHandler 处理,数据会存储到 ESP8266_Data 结构体中
	*/
	while (timeout)
	{
		// 根据应答结果判断,确定应答效果
		if (!ESP8266_AckCheck(ack))
		{
			break;
		}
		
		timeout--;
		SysTick_Delay_ms(1);
	}
	
	// 如果没有超时,表示应答信息正常
	if (timeout)
	{
		// printf("ACK Success\n");
	}
	else
	{
		// printf("ACK Failed\n");
	}
}

u8 ESP8266_AckCheck(const char *ack)
{
	// 判断当前 ESP8266 数据释放发送完成
	// 根据 ESP8266_Data 结构体中的 flag 进行判断
	if (esp8266_val.flag)
	{
		if (strstr((const char *)esp8266_val.data, ack))
		{
			return 0;
		}
		else
		{
			return 1;
		}
	}
	
	return 1;
}

void ESP8266_Connect(const char *ssid, const char *psk)
{
	printf("ESP8266 WiFi Connect!\n");
	
	// 1. 发送 AT 指令,判断当前设备是否正常工作
	ESP8266_Send_AT("AT\r\n", "OK", 2000);
	SysTick_Delay_ms(500);
	
	// 2. 设置当前 ESP8266 工作模式为 STA(Station) 模式
	ESP8266_Send_AT("AT+CWMODE=1\r\n", "OK", 2000);
	SysTick_Delay_ms(500);
	
	// 3. 扫描当前可以连接的 AP 热点信息,包括 SSID,信号强度
	ESP8266_Send_AT("AT+CWLAP\r\n", "OK", 2000);
	SysTick_Delay_ms(5000);
	
	// 4. 连接目标热点,提供 SSID 和 PSK,组装字符串时,必须将
	// AT 指令以 \r\n 结尾
	char connectCmd[128] = "";
	sprintf(connectCmd, "AT+CWJAP=\"%s\",\"%s\"\r\n", ssid, psk);
	ESP8266_Send_AT(connectCmd, "OK", 2000);
	SysTick_Delay_ms(5000);
	
	// 5. 网络连接情况
	ESP8266_Send_AT("AT+CIFSR\r\n", "OK", 2000);
	SysTick_Delay_ms(2000);
	
}
3. MQTT 协议

MQTT 参考文档

3.1 MQTT 概述
  • 广泛用于 物联网设备联网通信的传输协议,基于 TCP/IP 实现
  • MQTT 区分客户端和服务器,本地 STM32 + ESP8266 + MQTT 支持,可以认为是 MQTT 的客户端,同时云平台 (ThingsCloud Onenet Aliyun) 物联网平台可以认为是 MQTT 服务器。
  • MQTT 协议中,重点内容是**【服务器连接】【订阅主题】【发布消息】**
    • 服务器连接 : 当前 MQTT 客户端链接对应的 MQTT 服务器
    • **订阅主题 : ** MQTT 服务器一旦通过指定主题下发数据,MQTT 客户端可以收到服务器下发的数据内容,可以完成设备控制,例如 LED 亮灭,舵机控制。。。
    • 发布消息 : MQTT 客户端按照 MQTT 服务器要求,和云平台自定义内容,将本地数据发送到云平台。可以将传感器数据进行上传。。。
3.2 MQTT 相关技术内容

MQTT 技术特征

  • MQTT 版本有 5.0.0 和 3.1.1
    • 5.0.0 是最新版本,支持功能更多,使用更为方便
    • 3.1.1 是目前主流设备端使用的大面积版本,使用相对复杂。
3.3 MQTT 控制报文结构
3.3.1 MQTT 报文组成部分
  • Fixed header : 确定当前 MQTT 发送的数据目标,例如 连接服务器,发布数据,订阅主题
  • Variable header : 根据当前 MQTT Fixed header 目标任务需求,提供不同的报文参数
  • Payload :根据当前 MQTT 报文类型和目标数据需求,提供的用户有效载荷内容
组成部分 内容分析
Fixed header 固定报头,所有控制报文都包含
Variable header 可变报头,部分控制报文包含
Payload 有效载荷,部分控制报文包含
3.3.2 Fixed header 固定报头

格式内容

  • 主要有 MQTT 控制报文类型和报文类型指定标志
  • 剩余长度

MQTT 控制报文类型,在 Fixed Header 固定头中,对应的是第一个字节的 7 ~ 4 位

名字 报文流动方向 描述
Reserved 0 禁止 保留
CONNECT 1 客户端到服务端 客户端请求连接服务端
CONNACK 2 服务端到客户端 连接报文确认
PUBLISH 3 两个方向都允许 发布消息
PUBACK 4 两个方向都允许 QoS 1消息发布收到确认
PUBREC 5 两个方向都允许 发布收到(保证交付第一步)
PUBREL 6 两个方向都允许 发布释放(保证交付第二步)
PUBCOMP 7 两个方向都允许 QoS 2消息发布完成(保证交互第三步)
SUBSCRIBE 8 客户端到服务端 客户端订阅请求
SUBACK 9 服务端到客户端 订阅请求报文确认
UNSUBSCRIBE 10 客户端到服务端 客户端取消订阅请求
UNSUBACK 11 服务端到客户端 取消订阅报文确认
PINGREQ 12 客户端到服务端 心跳请求
PINGRESP 13 服务端到客户端 心跳响应
DISCONNECT 14 客户端到服务端 客户端断开连接
Reserved 15 禁止 保留

控制报文类型标志位

  • 重点是发布数据的标志内容
  • 其他控制报文类型,对应的标志位都是固定格式,按照当前表格要求提供

固定报头中的剩余长度,对应的

  • Variable Header 和 Payload 字节数。
  • 根据当前数据大小,可以选择剩余长度占用的字节数,通常情况下 MQTT 报文字节数数据不大。
3.4 CONNECT -- 连接服务端
3.4.1 CONNECT 主要作用

客户端到服务端的网络连接建立后,客户端发送给服务端的第一个报文必须是CONNECT报文 [MQTT-3.1.0-1]。

在一个网络连接上,客户端只能发送一次CONNECT报文。服务端必须将客户端发送的第二个CONNECT报文当作协议违规处理并断开客户端的连接 [MQTT-3.1.0-2]。有关错误处理的信息请查看4.8节。

有效载荷包含一个或多个编码的字段。包括客户端的唯一标识符,Will主题,Will消息,用户名和密码。除了客户端标识之外,其它的字段都是可选的,基于标志位来决定可变报头中是否需要包含这些字段。

3.4.2 CONNECT 数据包分析
c 复制代码
MQTT Connect 报文组成
	u8 MQTT_Connect_Data[256] = "";
Fixed_Header
	MQTT_Connect_Data[0] 是报文类型 + 报文标志位
		0001 0000 ==> 0x10
	MQTT_Connect_Data[1] 是报文剩余长度,对应 可变头 + 有效载荷
		可变头(10) + 有效载荷(19) ==> 0001 1101 ==> 29 ==> 0x1D
		
Variable_Header 
	【协议内容】
		可变头第一个组成部分是 协议名称数据提交方式为 【2 + N】 模式
		需要提供的数据是协议长度(2 Byte) + 协议内容,当前是使用 MQTT 协议,对应内容为 MQTT 字符串
		协议长度 => 4 个字节,协议内容 => MQTT
			MQTT_Connect_Data[2] 数据长度高位 MSB   4 / 256 ==> 0000 0000 ==>0x00
			MQTT_Connect_Data[3] 数据长度低位 LSB    4 % 256 ==> 0000 0100 ==> 0x04
			MQTT_Connect_Data[4] 'M' ==> 0100 1101 ==> 0x4D
			MQTT_Connect_Data[5] 'Q' ==> 0101 0001 ==> 0x51
			MQTT_Connect_Data[6] 'T' ==>  0101 0100 ==> 0x54
			MQTT_Connect_Data[7] 'T' ==>  0101 0100 ==> 0x54
	【协议版本】
		当前使用的协议版本是 MQTT 3.1.1 采用一个字节数据来告知 MQTT 服务器对应的版本信息
			MQTT_Connect_Data[8] ==> 0000 0100 ==> 0x04
	【连接标志 Connect Flags】
		组成部分是告知当前 MQTT 协议后续的载荷内容,每一个标志位告示后续的数据中,
		是否包含对应的数据内容
		Username(占1位) Password(占1位) Will Retain(占1位) Will QoS(占2位) Will Flag(占1位)  Clean Session(占1位) 保留(占1位)
		根据 ThingsCloud 分析,需要提供用户名和密码,同时按照常规内容,不需要返回,QoS=0 flag 不需要,Clean Session 需要
			MQTT_Connect_Data[9]  ==> 1100 0010 ==> 0xC2
	【Keep Alive 时间】
		MQTT 客户端和服务器之间发送数据的最大间隔,超出范围登录退出。
		需要两个字节 16 位来描述对应的时间
		分别对应 
			假设 Keep Alive ==> 60 
			Keep Alive 时间 MSB 高位 MQTT_Connect_Data[10] ==> 60 / 256 ==> 0000 0000 ==> 0x00
			Keep Alive 时间 LSB 低位  MQTT_Connect_Data[11] ==> 60 % 256 ==> 0011 1100 ==> 0x3CD

Payload
	Payload 字节数 = 2 + 客户端名称字节数 + 2 + 用户名字节数 + 2 + 密码字节数
				= 2 + 9 + 2 + 2 + 2 + 2 ==> 19
	根据当前报文分析和标志位分析,当前有效载荷的组成部分是,全部采用 2 + N 模式
	【客户端标识符】假设客户端标识符/客户端名称是 Client_GL
		2 + N 模式分析
		2 表示当前数据的字节个数 ==> 9 byte
			MQTT_Connect_Data[12] 数据长度高位 MSB ==> 9 / 256 ==> 0000 0000 ==> 0x00
			MQTT_Connect_Data[13] 数据长度低位 LSB ==> 9 % 256 ==> 0000 1001 ==> 0x09
		N 对应的数据,按照字节方式处理
			MQTT_Connect_Data[14] ==> 'C'
			MQTT_Connect_Data[15] ==> 'l'
			MQTT_Connect_Data[16] ==> 'i'
			MQTT_Connect_Data[17] ==> 'e'
			MQTT_Connect_Data[18] ==> 'n'
			MQTT_Connect_Data[19] ==> 't'
			MQTT_Connect_Data[20] ==> '_'
			MQTT_Connect_Data[21] ==> 'G'
			MQTT_Connect_Data[22] ==> 'L'
	【用户名】假设用户名 CG
		2 + N 模式分析
		2 表示当前数据的字节个数 ==> 2 byte
			MQTT_Connect_Data[23] 数据长度高位 MSB ==> 2 / 256 ==> 0000 0000 ==> 0x00
			MQTT_Connect_Data[24] 数据长度低位 LSB ==> 2 % 256 ==> 0000 0010 ==> 0x02
		N 对应的数据,按照字节方式处理
			MQTT_Connect_Data[25] ==> 'C'
			MQTT_Connect_Data[26] ==> 'G'

	【密码】假设密码 HL
		2 + N 模式分析
		2 表示当前数据的字节个数 ==> 2 byte
			MQTT_Connect_Data[27] 数据长度高位 MSB ==> 2 / 256 ==> 0000 0000 ==> 0x00
			MQTT_Connect_Data[28] 数据长度低位 LSB ==> 2 % 256 ==> 0000 0010 ==> 0x02
		N 对应的数据,按照字节方式处理
			MQTT_Connect_Data[29] ==> 'H'
			MQTT_Connect_Data[30] ==> 'L'
3.4.3 STM32 利用 ESP8266 连接 MQTT 流程
  • ESP8266 联网
  • ESP8266 利用 TCP 协议和 MQTT 云平台建立连接
  • ESP8266 开启【透传】模式 + 【数据直发】方式
  • 将 Connect 操作数据包发送到 MQTT 云平台,建立和项目的连接。
3.5 PUBLISH -- 发布消息
3.5.1 发布消息 Topic

MQTT 客户端到服务器或者服务器到客户端,都需要通过发布主题进行明确当前提交的信息内容是什么内容。

ThingsCloud 支持的发布主题 Topic。针对于 ThingsCloud 云端设备,选择 public_topic 对应 attributes。提交数据格式为 JSON 格式。

【注意】发布消息是在 MQTT 服务器连接之后

消息类型 主题
设备上报属性值 attributes
设备获取当前属性值 attributes/get/<id>
设备上报事件 event/report/<id>
设备回复命令 command/reply/<id>
设备自定义数据上报 data/<identifier>
设备上报离线主题 attributes/series{}

ThingsCloud 服务器数据属性名称

根据 ThingsCloud 要求的 JSON 格式数据形式,通过 MQTT 协议条件的数据【有效载荷】为

json 复制代码
{
    "Temp":25.3,
    "Hum":55
}
  • 注意,双引号是 JSON 格式键名 (Key) 对应的格式要求,在通过 MQTT 数发送时,需要提供对应的转义操作。
c 复制代码
char * data = "{\"Temp\":25.3,\"Hum\":55}";
3.5.2 发布数据包分析
c 复制代码
MQTT PUBLISH  报文组成
	u8 MQTT_Publish_Data[256] = "";
Fixed_Header
	MQTT_Publish_Data[0] 是报文类型 + 报文标志位
		0011 0000 ==> 0x30
	MQTT_Publish_Data[1] 是报文剩余长度,对应 可变头 + 有效载荷
		XXXX XXXX ==> 可变头(2 +  strlen("attributes")) +
		
Variable_Header 
	【发布主题】
	ThingsCloud 要求的发布主题为 attributes,首先可变头中的是 2 + N
	    发布主题名称字节长度高位和低位
	MQTT_Publish_Data[2] = strlen("attributes") / 256;
	MQTT_Publish_Data[3] = strlen("attributes") % 256;
	  memcpy(&MQTT_Publish_Data[4], "attributes", strlen("attributes"));
	
Payload
	有效载荷是当前提交的 JSON 格式字符串,直接在 Variable_Header 拼接即可
	"{\"Temp\":25.3,\"Hum\":55}"
	memcpy(&MQTT_Publish_Data[4 + strlen("attributes")], "{\"Temp\":25.3,\"Hum\":55}", strlen("{\"Temp\":25.3,\"Hum\":55}"))
3.6 SUBSCRIBE - 订阅主题
3.6.1 订阅主题 Topic

订阅主题,MQTT 服务器可以通过对应主题进行数据下发,MQTT 客户端可以收到对应的数据内容。数据形式一般都是【字符串形式】并且通常都是 JSON 格式数据。

在 ThingsCloud 中支持的订阅主题有

【注意】订阅主题是在 MQTT 服务器连接之后

消息类型 主题
接收属性上报的响应 attributes/response
接收属性获取的响应 attributes/get/response/+
接收下发的属性 attributes/push
接收事件上报的响应 event/response/+
接收下发的命令 command/send/+
接收命令回复的响应 command/reply/response/+
接收自定义数据下发 data/<identifier>/set
接收离线属性上报的响应 attributes/series/response

当前 STM32 + ESP8266 + MQTT 订阅主题 attributes/push,可以收到服务器下发的数据内容。

ESP8266 收到 MQTT 服务器下发的数据内容,通过 USART3 告知 MCU。可以通过程序,对 JSON 格式数据进行解析判断,从而满足硬件功能控制。

json 复制代码
{
    "Led0": false,
    "Led1": false,
    "SG90": "Turn_Clockwise",
    "Beep": false
} 
3.6.2 订阅主题数据包分析
c 复制代码
MQTT SUBSCRIBE  报文组成
	u8 MQTT_Subscirbe_Data[256] = "";
Fixed_Header
	MQTT_Subscirbe_Data[0] 是报文类型 + 报文标志位
		1000 0000 ==> 0x80
	MQTT_Subscirbe_Data[1] 是报文剩余长度,对应 可变头 + 有效载荷
		2 + 2 +  strlen("attributes/push") + 1
Variable_Header 
	2 个字节,订阅主题数据包 ID,因为当前使用的是 QoS=0 服务等级
	完全可以自定义
	MQTT_Subscirbe_Data[2] ==> 0x00
	MQTT_Subscirbe_Data[3] ==> 0x08
	
Payload
	2 + N + 1
	2 ==> MSB + LSB
		MQTT_Subscirbe_Data[4] ==> strlen("attributes/push") / 256
		MQTT_Subscirbe_Data[5] ==> strlen("attributes/push") % 256

        N ==> 订阅主题字符串数据
		memcpy(&MQTT_Subscirbe_Data[6],"attributes/push", strlen("attributes/push"));
        1 ==> QoS = 0
		MQTT_Subscirbe_Data[6 + strlen("attributes/push")] = 0x00
相关推荐
三佛科技-187366133977 小时前
FT8370A/B/C/CD/CP高性能次边同步整流芯片典型电路及管脚定义
stm32·单片机·嵌入式硬件
国科安芯7 小时前
光电传感器领域国产MCU芯片抗辐照技术考量
网络·人工智能·单片机·嵌入式硬件·安全
摆烂积极分子7 小时前
安卓开发学习10-中级控件
学习
少爷晚安。7 小时前
Java零基础学习完整笔记,基于Intellij IDEA开发工具,笔记持续更新中
java·笔记·学习
junziruruo7 小时前
半监督学习,少样本学习和零样本学习
python·学习·机器学习
学习和思考8 小时前
为什么我的vscode有的时候可以跳转,有的时候不能跳转
arm开发·ide·驱动开发·vscode·学习·1024程序员节
兔兔爱学习兔兔爱学习8 小时前
LangChain4j学习6:agent
人工智能·学习·语言模型
二进制coder9 小时前
BMC RTC:服务器硬件管理的“时间心脏”与系统协同核心
服务器·单片机·实时音视频
丰锋ff9 小时前
英一2016年真题学习笔记
笔记·学习