第五章:5.1 ESP32物联网应用 - MQTT协议深度教程

一、MQTT协议简介

1.1 发布/订阅模式

MQTT(Message Queuing Telemetry Transport)是一种轻量级物联网通信协议,采用发布/订阅模式

  • 发布者(Publisher) :发送消息到指定主题(如:home/light

  • 订阅者(Subscriber):订阅感兴趣的主题接收消息

  • 代理(Broker):负责消息路由的中枢服务器

1.2 协议优势

  • 低带宽消耗(最小消息仅2字节)

  • 支持离线消息(QoS质量等级)

  • 适合不稳定网络环境

  • 一对多通信效率高


二、MQTT服务器搭建

2.1 本地搭建(Mosquitto)

复制代码
# Ubuntu安装
sudo apt-get install mosquitto mosquitto-clients

# 启动服务
sudo systemctl start mosquitto

# 测试订阅(新终端)
mosquitto_sub -h localhost -t "test"

# 测试发布(另开终端)
mosquitto_pub -h localhost -t "test" -m "Hello World"

2.2 云平台方案(EMQX)

  1. 访问EMQX Cloud

  2. 创建免费实例(15天试用)

  3. 获取连接信息:

    复制

    复制代码
    地址: mqtt.emqx.io
    端口: 1883

三、ESP32客户端开发

3.1 开发环境准备

  1. Arduino IDE安装

  2. 添加ESP32支持:文件 > 首选项 > 附加开发板管理器

    复制

    复制代码
    https://dl.espressif.com/dl/package_esp32_index.json
  3. 安装库:工具 > 管理库 > 搜索安装PubSubClient

3.2 完整代码(逐行解析)

复制代码
#include <WiFi.h>
#include <PubSubClient.h>

// WiFi配置
const char* ssid = "Your_WiFi_SSID";
const char* password = "Your_WiFi_Password";

// MQTT配置
const char* mqttServer = "mqtt.emqx.io"; // 代理地址
const int mqttPort = 1883;               // 非加密端口
const char* clientID = "ESP32Client";     // 客户端唯一ID
const char* subTopic = "device/control";  // 订阅主题
const char* pubTopic = "device/status";   // 发布主题

WiFiClient espClient;           // WiFi客户端对象
PubSubClient client(espClient); // MQTT客户端实例

void setup_wifi() {
  delay(10);
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(ssid);

  WiFi.begin(ssid, password); // 启动WiFi连接

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }

  Serial.println("");
  Serial.println("WiFi connected");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());
}

void callback(char* topic, byte* payload, unsigned int length) {
  Serial.print("Message arrived [");
  Serial.print(topic);
  Serial.print("] ");
  
  // 将字节数组转换为字符串
  String message;
  for (int i=0; i<length; i++) {
    message += (char)payload[i];
  }
  Serial.println(message);

  // 根据消息内容执行操作
  if(message == "ON"){
    digitalWrite(LED_BUILTIN, LOW); // ESP32内置LED低电平触发
  }
  else if(message == "OFF"){
    digitalWrite(LED_BUILTIN, HIGH);
  }
}

void reconnect() {
  while (!client.connected()) {
    Serial.print("Attempting MQTT connection...");
    
    if (client.connect(clientID)) { // 尝试连接
      Serial.println("connected");
      client.subscribe(subTopic);   // 订阅主题
    } else {
      Serial.print("failed, rc=");
      Serial.print(client.state()); // 打印错误代码
      Serial.println(" retry in 5 seconds");
      delay(5000);
    }
  }
}

void setup() {
  pinMode(LED_BUILTIN, OUTPUT);     // 初始化LED引脚
  Serial.begin(115200);             // 启动串口通信
  setup_wifi();                     // 连接WiFi
  client.setServer(mqttServer, mqttPort); // 配置MQTT服务器
  client.setCallback(callback);      // 设置消息回调函数
}

void loop() {
  if (!client.connected()) {        // 断线重连机制
    reconnect();
  }
  client.loop();                    // 维持MQTT连接

  // 定时发布状态(示例)
  static unsigned long lastMsg = 0;
  if (millis() - lastMsg > 5000) {
    lastMsg = millis();
    String msg = "Alive: " + String(millis()/1000);
    client.publish(pubTopic, msg.c_str()); // 发布消息
  }
}

四、远程控制实现

4.1 手机APP控制(MQTT Dash)

  1. 应用商店下载"MQTT Dash"

  2. 创建新连接:

    复制

    复制代码
    Host: mqtt.emqx.io
    Port: 1883
  3. 添加控制面板:

    • 开关组件:绑定到device/control主题

    • 文本组件:订阅device/status主题

4.2 网页控制(Node-RED)

复制代码
// 流程配置示例
[
  {
    "id": "switch",
    "type": "ui_switch",
    "z": "flow1",
    "name": "LED控制",
    "topic": "device/control",
    "layout": "row-center"
  },
  {
    "id": "status",
    "type": "ui_text",
    "z": "flow1",
    "name": "设备状态",
    "topic": "device/status",
    "layout": "row-center"
  }
]

五、常见问题排查

5.1 连接失败分析

错误代码 含义 解决方案
-2 网络不可达 检查WiFi连接
-1 连接被拒绝 检查端口/防火墙设置
2 无效客户端标识 修改clientID
4 用户名/密码错误 检查认证信息

5.2 消息不达的可能原因

  1. 主题名称不一致(注意大小写)

  2. QoS等级不匹配

  3. 未成功订阅主题

  4. 消息载荷格式错误


六、进阶技巧

  1. 保留消息client.publish(topic, message, true)

  2. 遗嘱消息:配置断开时自动发布状态

  3. QoS等级

    • 0:最多一次

    • 1:至少一次

    • 2:精确一次

  4. TLS加密:使用8883端口+CA证书

复制代码
// 启用SSL示例
WiFiClientSecure espClient;
espClient.setCACert(root_ca); // 添加根证书
PubSubClient client(mqttServer, 8883, callback, espClient);

七、项目扩展建议

  1. 添加温湿度传感器(DHT11)

  2. 实现OTA无线升级

  3. 接入Home Assistant平台

  4. 设计JSON消息格式

    复制代码
    {
      "device": "ESP32-001",
      "timestamp": 1629782400,
      "temperature": 25.5,
      "humidity": 60
    }

通过本教程,您已掌握ESP32通过MQTT协议实现物联网通信的核心技能。建议在实际项目中逐步加入异常处理、安全机制等要素,打造稳定可靠的物联网系统。

相关推荐
喜欢便码2 小时前
JS小练习0.1——弹出姓名
java·前端·javascript
南泽兆3 小时前
MCU选型的五大维度--助力嵌入式产品设计
单片机·嵌入式硬件
王磊鑫3 小时前
重返JAVA之路-初识JAVA
java·开发语言
半兽先生3 小时前
WebRtc 视频流卡顿黑屏解决方案
java·前端·webrtc
南星沐4 小时前
Spring Boot 常用依赖介绍
java·前端·spring boot
代码不停5 小时前
Java中的异常
java·开发语言
SuperW5 小时前
蓝桥杯嵌入式十五届模拟二(串口DMA,占空比的另一种测量方式)
单片机·职场和发展·蓝桥杯
何似在人间5756 小时前
多级缓存模型设计
java·jvm·redis·缓存
多云的夏天6 小时前
ubuntu24.04-MyEclipse的项目导入到 IDEA中
java·intellij-idea·myeclipse
Fanxt_Ja6 小时前
【数据结构】红黑树超详解 ---一篇通关红黑树原理(含源码解析+动态构建红黑树)
java·数据结构·算法·红黑树