MQTT(简单连接物联网平台上传数据)
MQTT 是。主要用于,或,广泛应用于低带宽、低功耗的嵌入式设备中。QoS 消息质量等级:0:最多传输一次 → 发送后不确认,丢包不重发(速度快、适合周期性传感器数据)1:至少传输一次 → 保证消息送达,未收到应答会重发(稳定、适合控制指令)2:仅传输一次 → 严格确保消息只送达一次(最安全、复杂度高,普通项目一般不使用)项目通常使用等网络模块,通过实现联网与 MQTT 通信。不同模块的 AT 指
MQTT 是基于发布 / 订阅模式的轻量级物联网通信协议,核心角色包括:服务端(Broker)、发布者(Publisher)、订阅者(Subscriber)。主要用于传感器数据上传至云平台,或从平台接收远程控制指令,广泛应用于低带宽、低功耗的嵌入式设备中。
QoS 消息质量等级:
0:最多传输一次 → 发送后不确认,丢包不重发(速度快、适合周期性传感器数据)
1:至少传输一次 → 保证消息送达,未收到应答会重发(稳定、适合控制指令)
2:仅传输一次 → 严格确保消息只送达一次(最安全、复杂度高,普通项目一般不使用)
项目通常使用 ESP8266/ESP32/4G/EC20/EC600 等网络模块,通过 串口 + AT 指令 实现联网与 MQTT 通信。不同模块的 AT 指令略有差异,但整体流程完全一致。
串口:串口通讯
串口通信要求
- 串口初始化必须正常,波特率匹配;
- 每条 AT 指令结尾必须加 \r\n(回车换行);
- 每发送一条指令,必须等待模块返回响应(OK/ERROR)。
void Send_AT_Command(uint8_t *at_cmd)
{
USART_SendStr_Reg(at_cmd); // 发送AT指令
USART_SendStr_Reg("\r\n"); // 添加回车换行符
}
流程(以ESP8266为例):
一、模块初始化
1.测试模块,串口发送AT
sprintf(cmd, "AT");
Send_AT_Command(cmd);
2.关闭回显(避免干扰数据解析)
sprintf(cmd, "ATE0");
Send_AT_Command(cmd);
3.恢复出厂/复位(可选)
sprintf(cmd, "AT+RST");
Send_AT_Command(cmd);
二、接入网络(WiFi类(ESP8266/ESP32)、4G类(EC20/EC600))
1.WiFi类
(1)设置STA模式
sprintf(cmd, "AT+CWMODE=1"); //1:STA 0:AP
Send_AT_Command(cmd);
(2)连接路由器
sprintf(cmd, "AT+CWJAP=\"%s\",\"%s\"", "wifi名", "WiFi密码");
Send_AT_Command(cmd);
三、建立传输链路
1.TCP连接
sprintf(cmd, "AT+CIPSTART=\"TCP\",\"%S\",%d",服务器IP,端口号);
Send_AT_Command(cmd);
2.开启透传模式
sprintf(cmd, "AT+CIPMODE=1");
Send_AT_Command(cmd);
3.进入透传(开启后不再解析AT指令,串口数据直接发送到网络)
sprintf(cmd, "AT+CIPSEND");
Send_AT_Command(cmd);
四、MQTT业务流程
1.配置MQTT信息
//0:链路编号(固定) 1:MQTT协议版本
//client123:客户端id user:用户名 pwd:用户密码
//0:标志位 60:心跳包(保活)
sprintf(cmd, "AT+MQTTUSERCFG=0,1,\"%s\",\"%s\",\"%s\",0,%d,\"\"",客户端id,用户名,用户密码,心跳包);
Send_AT_Command(cmd);
2.连接MQTT服务器
//0:链路编号 服务器ip 端口号 0:清理会话标志
sprintf(cmd, "AT+MQTTCONN=0,\"%s\",%d,0",服务器ip,端口号);
Send_AT_Command(cmd);
3.订阅主题(单片机发送数据到服务器)
// 0:链路编号 topic:主题名 1:Qos消息质量等级
sprintf(cmd, "AT+MQTTSUB=0,\"%s\",1",topic);
Send_AT_Command(cmd);
4.发布主题(发布JSON数据)
适合少量数据(和大量数据发送的AT指令不同):
//0:链路编号 发布主题 消息内容 Qos 保留
sprintf(cmd, "AT+MQTTPUB=0,\"%s\",\"{\\\"weight\\\":%d}\",1,0",发布主题,体重值);
Send_AT_Command(cmd);
适合大量数据:使用JSON官方库(cJSON)
/**********构建JSON数据*********/
// 创建JSON根对象
cJSON *root = cJSON_CreateObject();
if(root == NULL)
{
USART_SendStr_Reg((uint8_t *)"JSON创建失败\r\n");
return NULL;
}
//添加JSON字段
cJSON_AddStringToObject(root, "device_id", "stm32f103");
cJSON_AddNumberToObject(root, "temperature", temp);
//JSON转字符串
char *json_str = cJSON_PrintUnformatted(root);
if (json_str != NULL)
{
uint16_t payload_len = strlen(json_str); // 消息长度
uint8_t timeout = 0;
USART1_RX_LEN = 0;
memset(USART1_RX_BUF, 0, sizeof(USART1_RX_BUF));
// 格式:AT+MQTTPUBRAW=链路号,"主题",长度,Qos,保留
char at_cmd[256];
sprintf(at_cmd, "AT+MQTTPUBRAW=0,\"topic\",%d,0,0", payload_len);
Send_AT_Command((uint8_t *)at_cmd); // 发送指令
while(timeout < 100) // 1秒超时
{
HalCore_DelayMS(10);
if(strstr((char*)USART1_RX_BUF, ">") != NULL)
{
Send_AT_Command((uint8_t*)json_str);
break;
}
timeout++;
}
cJSON_free(json_str);
}
cJSON_Delete(root); // 释放JSON对象
五、JSON数据解析(订阅主题后服务器发送的数据),建议使用json库(容错性强),也可使用如下代码(容错性弱)
#include <string.h>
#include <stdio.h>
//键值解析函数
// 从JSON中,根据 键(key) 提取 值(value)
// json: 完整JSON字符串
// key: 要找的键名 如 "led"
// value: 提取到的值存这里
int GetJsonValue(char *json, char *key, char *value)
{
char buf[64];
char *start, *end;
// 1. 拼接查找键: "key"
sprintf(buf, "\"%s\":", key);
// 2. 查找键的位置
start = strstr(json, buf);
if(start == NULL) return -1; // 没找到
// 3. 跳过键,指向值开始
start += strlen(buf);
// 4. 去掉字符串的引号
if(*start == '"') start++;
// 5. 找值的结束位置
if(*start == '"')
{
start++;
end = strchr(start, '"');
}
else
{
end = strchr(start, ',');
if(end == NULL) end = strchr(start, '}');
}
if(end == NULL) return -2;
// 6. 把值复制出来
strncpy(value, start, end - start);
value[end - start] = '\0';
return 0; // 成功
}
GetJsonValue(rx_buf, "led", value);
printf("led = %s\n", value); // 输出 on
六、异常处理机制
当设备出现网络断开、MQTT 掉线、指令发送失败、模块无响应等异常时,执行自动重连:
1. 关闭旧的MQTT连接
sprintf(cmd, "AT+MQTTCLEAN=0"); // 关闭编号为0的MQTT连接
Send_AT_Command(cmd);
HAL_Delay(500); // 等待模块执行完成
2. 关闭TCP链路
sprintf(cmd, "AT+CIPCLOSE"); // 断开TCP连接
Send_AT_Command(cmd);
HAL_Delay(1000); // 等待断开完成
3. 重新连接WiFi/4G网络
4. 重新配置MQTT参数
5. 重新连接服务器并订阅主题
目前物联网设备主流通信方案为 MQTT + JSON:
- MQTT 负责稳定、低功耗的发布 / 订阅消息传输;
- JSON 负责标准化数据封装与解析;
- 配合 AT 指令控制网络模块,可快速实现设备上云、数据上传、远程控制等功能。
更多推荐
所有评论(0)