ESP32 MQTT对接巴法云平台
ESP32 MQTT对接巴法云平台
MQTT(Message Queuing Telemetry Transport)是一种轻量级的 发布/订阅(Publish/Subscribe) 消息传输协议,专为 低带宽、高延迟、不稳定网络环境 设计,是物联网(IoT)领域的核心通信协议之一。
MQTT 核心特性
| 特性 | 说明 |
|---|---|
| 轻量级 | 协议头最小仅 2字节,适合嵌入式设备 |
| 发布/订阅模型 | 设备不直接通信,通过 Broker(代理服务器) 中转,解耦性强 |
| 低功耗 | 适合电池供电设备,支持 心跳包(Keep Alive) 维持长连接 |
| QoS 质量等级 | 支持 0/1/2 三级消息可靠性保证 |
| 主题(Topic) | 分层式消息路由(如 home/living_room/temperature),支持通配符 + 和 # |
MQTT 与 HTTP 对比
| 对比维度 | MQTT | HTTP |
|---|---|---|
| 协议开销 | 极低(适合高频小数据) | 高(Header 冗余) |
| 通信模式 | 双向实时推送 | 单向请求-响应 |
| 连接开销 | 长连接(减少握手延迟) | 短连接(每次请求需重建连接) |
| 适用场景 | 物联网、移动推送、实时监控 | Web 服务、API 接口 |
MQTT 核心概念
- Broker(代理服务器)
- 核心枢纽,负责消息路由(如 Mosquitto、EMQX、HiveMQ)
- 实现消息存储转发、客户端管理、安全认证
- Topic(主题)
- 消息分类的层级路径(例如:
factory/machine1/status) - 通配符:
+:单级匹配(home/+/temperature匹配home/living_room/temperature)#:多级匹配(home/#匹配home/living_room/light)
- 消息分类的层级路径(例如:
- QoS(服务质量)
- QoS 0:最多一次(尽力交付,可能丢失)
- QoS 1:至少一次(确保送达,可能重复)
- QoS 2:恰好一次(严格保证,无重复)
micro python可行性先行验证
# 导入必要的库
from umqtt.simple import MQTTClient # MQTT协议客户端库
import time # 时间相关函数
from machine import Timer # 硬件定时器控制
#################### 用户可修改配置区域 ####################
wifiName = "jianzhiji02" # WiFi名称(仅支持2.4G网络)
wifiPassword = "8765432111" # WiFi密码
clientID = "87b4b37b92784dbebb4421b3a20d9f6f" # 设备密钥,从巴法云控制台获取
subTopic = 'OTALX' # 订阅的主题(接收指令)
pubTopic = 'bafa' # 发布的主题(发送数据)
#################### 固定配置区域 ########################
serverIP = "bemfa.com" # MQTT服务器地址
port = 9501 # MQTT端口号
ping_interval = 300 # 心跳包间隔(秒)
################# WiFi连接函数 ##########################
def do_connect():
"""连接WiFi网络"""
import network
sta_if = network.WLAN(network.STA_IF)
if not sta_if.isconnected():
print('正在连接网络...')
sta_if.active(True)
sta_if.connect(wifiName, wifiPassword)
while not sta_if.isconnected():
pass
print('WiFi连接成功')
print('网络配置:', sta_if.ifconfig())
################# MQTT消息回调函数 #######################
def msg_callback(topic, msg):
"""处理接收到的MQTT消息"""
global client # 声明全局客户端对象
print("[消息到达] 主题:", topic.decode(), "| 载荷:", msg.decode())
# 判断是否是订阅的主题
if topic.decode() == subTopic:
# 根据指令执行操作
if msg == b"on":
print("执行开机操作")
# 示例:控制GPIO输出高电平
# pin.value(1)
# 发送状态确认(推送消息)
client.publish(pubTopic, "设备已开启")
elif msg == b"off":
print("执行关机操作")
# 示例:控制GPIO输出低电平
# pin.value(0)
# 发送状态确认(推送消息)
client.publish(pubTopic, "设备已关闭")
################ MQTT连接与订阅函数 #####################
def connect_mqtt():
"""建立MQTT连接并订阅主题"""
global client # 声明全局客户端对象
try:
# 创建客户端实例
client = MQTTClient(clientID, serverIP, port)
client.set_callback(msg_callback) # 设置回调函数
# 建立连接
client.connect()
print(f"成功连接到MQTT服务器 {serverIP}:{port}")
# 订阅主题
client.subscribe(subTopic)
print(f"已订阅主题: {subTopic}")
# 设置心跳间隔(可选)
client.keepalive = ping_interval
return client
except Exception as e:
print("MQTT连接失败:", e)
restart_and_reconnect()
################ 异常处理函数 ##########################
def restart_and_reconnect():
"""重启设备并重连"""
print("10秒后重启设备...")
time.sleep(10)
machine.reset()
################ 定时推送函数 ##########################
def timed_publish(timer):
"""定时发布设备状态(示例)"""
global client
try:
# 示例数据(可替换为传感器数据)
status = "11"
client.publish(pubTopic, f" {status}")
print(f"定时推送: {status}")
except:
print("定时推送失败")
################# 主程序流程 ###########################
if __name__ == "__main__":
# 连接WiFi
do_connect()
# 初始化MQTT连接
connect_mqtt()
# 设置定时器(每30秒发送心跳)
timer = Timer(-1) # 创建虚拟定时器
timer.init(
period=3000, # 间隔3秒(3000毫秒)
mode=Timer.PERIODIC,
callback=timed_publish
)
print("定时推送已启用")
# 主循环
try:
while True:
try:
client.check_msg() # 检查新消息
time.sleep(1) # 降低CPU占用
except Exception as e:
print("运行错误:", e)
restart_and_reconnect()
except KeyboardInterrupt:
print("程序终止")
client.disconnect()
timer.deinit()
终端打印

成功连接云平台,成功推送,订阅主题。可行性验证成功。
云平台
推送内容控制led

接受ESP32推送内容

Esp-idf+C语言实现
重要代码段分析
MQTT推送
//----------------MQTT推送-----------------------------------------------------------------//
//推送字符
const char *status = "putting";
//mqtt句柄,推送目标主题,推送内容,长度,服务质量,发布消息的标志位(通常设置为0)
esp_mqtt_client_publish(mqtt_client, PUB_TOPIC, status, strlen(status), 0, 0);
//推送数字
num+=3;//推送运行时间
snprintf(num_str, sizeof(num_str), "%d", num); // 将整数转为字符串
esp_mqtt_client_publish(mqtt_client, PUB_TOPIC2, num_str, strlen(num_str), 0, 0);
MQTT推送函数
esp_mqtt_client_publish:这是ESP-IDF提供的函数,用于通过MQTT客户端发布消息。
mqtt_client:这是MQTT客户端的句柄,通常是在初始化MQTT客户端时创建的。
PUB_TOPIC:这是您要发布消息的主题名称,通常是一个字符串。
status:这是您要发布的消息内容,通常是一个字符串。
strlen(status):这是消息内容的长度,strlen函数用于计算字符串的长度。:这是QoS(Quality of Service)等级,表示服务质量。MQTT协议定义了三种QoS等级:
- 0:最多一次("fire-and-forget")
- 1:至少一次
- 2:只有一次
0:这是发布消息的标志位,通常设置为0。
MQTT订阅(MQTT成功连接)
// MQTT事件处理
static void mqtt_event_handler(void *handler_args, esp_event_base_t base,
int32_t event_id, void *event_data) {
esp_mqtt_event_handle_t event = event_data;
switch (event->event_id) {
case MQTT_EVENT_CONNECTED://<MQTT连接事件>---------->MQTT成功连接则订阅主题
ESP_LOGI(TAG, "MQTT Connected");
mqtt_connected = true;
//----------------MQTT订阅(MQTT成功后)-----------------------------------------
//mqtt句柄,订阅的主题,服务等级(0)
esp_mqtt_client_subscribe(mqtt_client, SUB_TOPIC, 0);//订阅主题SUB_TOPIC(ledctrl)
case MQTT_EVENT_DATA: {//<MQTT接收数据事件>
// 处理接收数据
//----------------判断接收主题-----------------------------------------------------------------//
char topic[event->topic_len + 1];
memcpy(topic, event->topic, event->topic_len);
topic[event->topic_len] = '\0';
//----------------判断接收数据-----------------------------------------------------------------//
char data[event->data_len + 1];
memcpy(data, event->data, event->data_len);
data[event->data_len] = '\0';
//----------------打印接收主题+数据-----------------------------------------------------------------//
ESP_LOGI(TAG, "Received: Topic=%s, Data=%s", topic, data);
if (strcmp(topic, SUB_TOPIC) == 0) {//判断接收主题(ledctrl)数据——>控制led灯->推送led状态信息
if (strcmp(data, "on") == 0) {
gpio_set_level(OUTPUT_PIN, 0);
//推送led状态信息到主题ledstate
esp_mqtt_client_publish(mqtt_client, PUB_TOPIC3, "led设备已开启", 0, 0, 0);//同时推送状态到主题ledstate
} else if (strcmp(data, "off") == 0) {
gpio_set_level(OUTPUT_PIN, 1);
esp_mqtt_client_publish(mqtt_client, PUB_TOPIC3, "led设备已关闭", 0, 0, 0);
}
}
break;
}
default:
break;
}
}
运行逻辑:
MQTT成功连接(MQTT事件)->订阅主题
MQTT接收数据事件->判断接收内容
MQTT订阅函数
esp_mqtt_client_subscribe(mqtt_client, SUB_TOPIC, 0); // 订阅主题SUB_TOPIC(ledctrl)
esp_mqtt_client_subscribe:这是ESP-IDF提供的函数,用于订阅MQTT主题。mqtt_client:这是MQTT客户端的句柄,通常是在初始化MQTT客户端时创建的。SUB_TOPIC:这是您要订阅的主题名称,通常是一个字符串。在这个例子中,主题名称是ledctrl,表示用于控制LED灯的主题。- 0:这是QoS(Quality of Service)等级,表示服务质量。MQTT协议定义了三种QoS等级:
- 0:最多一次("fire-and-forget")
- 1:至少一次
- 2:只有一次
终端现象分析
成功连接WIFI

成功连接MQTT服务器,并推送主题+内容

接受到MQTT服务器订阅的主题内容

完整代码:
#include <string.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_system.h"
#include "esp_log.h"
#include "esp_event.h"
#include "esp_netif.h"
#include "nvs_flash.h"
#include "protocol_examples_common.h"
#include "mqtt_client.h"
#include "driver/gpio.h"
#include "esp_timer.h"
#include "esp_wifi.h"
// 用户配置参数
#define WIFI_SSID "jianzhiji02"//wifi名称
#define WIFI_PASS "8765432111"//wifi密码
#define MQTT_CLIENT_ID ""//巴法云平台秘钥
#define SUB_TOPIC "ledctrl"//订阅主题(控制核心板led)
#define PUB_TOPIC "bafa"//推送主题1(测试推送字符)
#define PUB_TOPIC2 "Time"//推送主题2(测试推送数字)
#define PUB_TOPIC3 "ledstate"//推送主题2(推送led状态)
// #define BROKER_URI "mqtt://bemfa.com:9501"//服务器URL(需DNS解析)
#define BROKER_URI "mqtt://119.91.109.180:9501"//服务器ip地址+端口
static const char *TAG = "MQTT_DEMO";
static esp_mqtt_client_handle_t mqtt_client = NULL;//mqtt句柄
static esp_timer_handle_t status_timer;//状态定时器句柄
static bool mqtt_connected = false;//mqtt连接状态
#define OUTPUT_PIN GPIO_NUM_48//led 引脚(低电平点亮)
// GPIO初始化
static void init_gpio(void) {
gpio_config_t io_conf = {
.pin_bit_mask = (1ULL << OUTPUT_PIN),
.mode = GPIO_MODE_OUTPUT,
.pull_up_en = GPIO_PULLUP_DISABLE,
.pull_down_en = GPIO_PULLDOWN_DISABLE,
.intr_type = GPIO_INTR_DISABLE
};
gpio_config(&io_conf);
gpio_set_level(OUTPUT_PIN, 1);
}
// 定义静态变量 // 缓冲区用于存储转换后的字符串
static int num = 0;static char num_str[16];
// 定时器回调函数(1s周期)
//----------------MQTT推送-----------------------------------------------------------------//
static void publish_status(void *arg) {
if (mqtt_connected) {
const char *status = "putting";//推送主题
esp_mqtt_client_publish(mqtt_client, PUB_TOPIC, status, strlen(status), 0, 0);
ESP_LOGI(TAG, "Published status: %s", status);
num+=3;//推送运行时间
snprintf(num_str, sizeof(num_str), "%d", num); // 将整数转为字符串
esp_mqtt_client_publish(mqtt_client, PUB_TOPIC2, num_str, strlen(num_str), 0, 0);
ESP_LOGI(TAG, "num: %d", num); // 正确打印整型
}
}
// MQTT事件处理
static void mqtt_event_handler(void *handler_args, esp_event_base_t base,
int32_t event_id, void *event_data) {
esp_mqtt_event_handle_t event = event_data;
switch (event->event_id) {
case MQTT_EVENT_CONNECTED://<MQTT连接事件>
ESP_LOGI(TAG, "MQTT Connected");
mqtt_connected = true;
//----------------MQTT订阅-----------------------------------------------------------------//
esp_mqtt_client_subscribe(mqtt_client, SUB_TOPIC, 0);//订阅主题ledctrl
// 创建状态定时器(3秒周期)
esp_timer_create_args_t timer_cfg = {
.callback = &publish_status,
.name = "status_timer"
};
esp_timer_create(&timer_cfg, &status_timer);
esp_timer_start_periodic(status_timer, 3000000);
break;
case MQTT_EVENT_DISCONNECTED:
ESP_LOGI(TAG, "MQTT Disconnected");
mqtt_connected = false;
esp_timer_stop(status_timer);
break;
case MQTT_EVENT_DATA: {//<MQTT接收数据事件>
// 处理接收数据
//----------------判断接收主题-----------------------------------------------------------------//
char topic[event->topic_len + 1];
memcpy(topic, event->topic, event->topic_len);
topic[event->topic_len] = '\0';
//----------------判断接收数据-----------------------------------------------------------------//
char data[event->data_len + 1];
memcpy(data, event->data, event->data_len);
data[event->data_len] = '\0';
//----------------打印接收主题+数据-----------------------------------------------------------------//
ESP_LOGI(TAG, "Received: Topic=%s, Data=%s", topic, data);
if (strcmp(topic, SUB_TOPIC) == 0) {//判断接收主题(ledctrl)数据——>控制led灯->推送led状态信息
if (strcmp(data, "on") == 0) {
gpio_set_level(OUTPUT_PIN, 0);
//推送led状态信息到主题ledstate
esp_mqtt_client_publish(mqtt_client, PUB_TOPIC3, "led设备已开启", 0, 0, 0);//同时推送状态到主题ledstate
} else if (strcmp(data, "off") == 0) {
gpio_set_level(OUTPUT_PIN, 1);
esp_mqtt_client_publish(mqtt_client, PUB_TOPIC3, "led设备已关闭", 0, 0, 0);
}
}
break;
}
case MQTT_EVENT_ERROR:
ESP_LOGE(TAG, "MQTT Error");
break;
default:
break;
}
}
// WiFi事件处理
static void wifi_event_handler(void *arg, esp_event_base_t event_base,
int32_t event_id, void *event_data) {
if (event_id == IP_EVENT_STA_GOT_IP) {
// WiFi连接成功后启动MQTT
esp_mqtt_client_config_t mqtt_cfg = {
.broker.address.uri = BROKER_URI,
.credentials.client_id = MQTT_CLIENT_ID
};
mqtt_client = esp_mqtt_client_init(&mqtt_cfg);
esp_mqtt_client_register_event(mqtt_client, ESP_EVENT_ANY_ID, mqtt_event_handler, NULL);
esp_mqtt_client_start(mqtt_client);
}
}
void app_main(void) {
// 初始化NVS(堆栈存储wifi连接数据等。。。)
esp_err_t ret = nvs_flash_init();
if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) {
ESP_ERROR_CHECK(nvs_flash_erase());
ret = nvs_flash_init();
}
ESP_ERROR_CHECK(ret);
// 初始化网络接口
ESP_ERROR_CHECK(esp_netif_init());
ESP_ERROR_CHECK(esp_event_loop_create_default());
// 配置WiFi
esp_netif_create_default_wifi_sta();
wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
ESP_ERROR_CHECK(esp_wifi_init(&cfg));
// 注册WiFi事件
esp_event_handler_instance_t instance_any_id;
ESP_ERROR_CHECK(esp_event_handler_instance_register(IP_EVENT,
IP_EVENT_STA_GOT_IP,
&wifi_event_handler,
NULL,
&instance_any_id));
// 设置WiFi参数
wifi_config_t wifi_config = {
.sta = {
.ssid = WIFI_SSID,
.password = WIFI_PASS,
},
};
ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA));//设置为STA模式
ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_STA, &wifi_config));//设置WiFi参数
ESP_ERROR_CHECK(esp_wifi_start());//启动WiFi
ESP_ERROR_CHECK(esp_wifi_connect());//连接WiFi
// 初始化GPIO(led)
init_gpio();
// 保持主任务运行
while (1) {
vTaskDelay(pdMS_TO_TICKS(1000));
}
}
ESP32 MQTT对接巴法云平台的更多相关文章
- the5fire博客对接微信公众平台接口 | the5fire的技术博客
the5fire博客对接微信公众平台接口 | the5fire的技术博客 the5fire博客对接微信公众平台接口
- MVC下c#对接微信公众平台开发者模式
在ashx文件中进行HttpContext的处理: using System; using System.Collections.Generic; using System.Linq; using S ...
- ESA2GJK1DH1K基础篇: 阿里云物联网平台: 测试MQTT客户端接收云平台的数据
前言 有时候想想可能直接连接现成的感觉比较方便吧! 这种东西考验的是你底子是否够好,是否有很强的学习能力 因为咱就是看文档,理解文档.用文档. 测这节会感觉:这是啥呀...下一节更精彩,但是必须看这节 ...
- java对接短信平台
短信验证码目前是比较主流验证身份的一种方式,下面分享下我对接的几种短信平台 阿里云短信:https://api.alidayu.com/docs/api.htm?spm=a3142.7395905.4 ...
- c#对接每人计平台获取数据
使用c#对接到晓舟科技的客流统计设备.那么需要先注册一个平台的账号 地址:http://mrd.meirenji.cn/login;JSESSIONID=323cbd18-29ed-4232-8c04 ...
- 利尔达NB-IOT模块对接移动onenet平台步骤
1. 首先登陆浙江移动onenet网站,http://openiot.zj.chinamobile.com/,进入右上角的开发者中心,然后才能看到创建产品 2. 填写产品的信息,其他信息按照个人实际填 ...
- 【物联网云端对接-4】通过MQTT协议与百度云进行云端通信
百度云的天工物联网服务目前包括:物接入.物解析.物管理.时序数据库和规则引擎等5大部分,本篇文章仅介绍物接入. 天工物联网的物接入,从开发者的角度来说相对有些复杂,需要多步操作才能实现一个云设备的创建 ...
- .Net Core下使用MQTT协议直连IoT平台
[摘要] .Net平台通过原生MQTT接口,作为南向设备对接OceanConnect平台 因为种种历史原因吧,目前华为平台上对.net的支持案例SDK确实比较少,当看到各种语言的SDK和Demo,唯独 ...
- HelloX操作系统与中国移动OneNET物联网平台成功完成对接
HelloX成功与中国移动物联网平台对接 经过HelloX项目组同仁的努力,尤其是Tywin(@飓风)的努力下,HelloX最新版本V1.78已成功与中国移动OneNET(open.iot.10086 ...
- 【物联网云端对接-3】通过MQTT协议与微软Azure IoT Hub进行云端通信
在上一篇文章<通过MQTT协议与阿里云物联网套件进行云端通信>中,我们介绍了通过MQTT对接阿里云的物联网套件.其实同样的代码,稍加调整也可以对接到微软Azure IoT hub上,不过需 ...
随机推荐
- Vue3 数据响应式原理与高效数据操作全解析
一.Vue3 数据响应式原理 (一)Proxy 替代 Object.defineProperty 在 Vue2 中,数据响应式是通过 Object.defineProperty 实现的.这种方法虽然能 ...
- min-max 容斥(最值反演)学习笔记
min-max 容斥,又名最值反演(我其实更喜欢后面这个名字),是一种常用的反演思想. 引入 在皇后游戏一题中,我们曾经证明过 \(\max(a,b)-a-b=-\min(a,b)\). 我们尝试推广 ...
- 湖北电信创维E900-S机顶盒-精简系统装当贝桌面
一.打开机顶盒进入本地配置,输入密码:6321,然后打开其他设置-管理应用程序,连续按遥控器方向右键5次左右,这时会出现[USB调试]并打开: 二.从电脑里下载好当贝市场(点击立即下载).当贝桌面(点 ...
- LCP 11. 期望个数统计
地址:https://leetcode-cn.com/problems/qi-wang-ge-shu-tong-ji/ <?php /** 某互联网公司一年一度的春招开始了,一共有 n 名面试者 ...
- PHP中处理html相关函数集锦
1.html_entity_decode() 函数把 HTML 实体转换为字符. Html_entity_decode() 是 htmlentities() 的反函数. 例子: <?Php $s ...
- script crossorigin 属性
来源:https://juejin.cn/post/6969825311361859598 <script src="xxxx" crossorigin="anon ...
- pip 提示import error,cannot import name locations
出现这个问题的原因: 环境中没有安装年文件 安装了,环境路径错误 解决如下: 首先 执行升级命令 升级到最新 python -m pip install -U pip 再到site-packages目 ...
- Web前端入门第 6 问:HTML 的基础语法结构
HTML的全称为超文本标记语言(HyperText Markup Language),基础语法结构由标签.元素.属性和内容组成,遵循层级嵌套的树形结构. 关键语法规则 标签(Tags) 双标签语法 标 ...
- css 技巧:利用 after 伪对象和 background 属性实现 img 图片标签占位图
同步发布:https://blog.jijian.link/2020-04-15/css-img-after-placeholder/ 如图: 图片加载失败了,在浏览器会默认显示一张破图.受各种网速. ...
- SuiGo智能博客系统
一款由Golang+Vue开发的博客类网站,支持大模型对话编写智能博客,同时适配PC和移动端. 功能点说明 系统主要包括 1.博客功能:博客编写也可对话AI模型协助编写.查询.编辑页面.详情页面.分享 ...