1. 连接公共MQTT代理

连接公共MQTT代理 学习卡片

任务目标

本案例将使用ESP32开发板连接公共MQTT代理 broker.hivemq.com(端口1883),完成以下闭环:连接代理 → 订阅主题 esp32/example/topic → 发布一条测试消息到同一主题 → 通过串口监视器观察消息是否成功回传,以此验证ESP32与MQTT代理之间的双向通信正常。

环境与依赖

  • 硬件:ESP32开发板(如ESP32-DevKitC)、USB数据线
  • 软件:Arduino IDE(已安装ESP32开发板支持包,版本2.x)
  • 库:PubSubClient(通过Arduino库管理器安装,作者Nick O'Leary)
  • 网络:ESP32需连接可访问公网的Wi-Fi热点

完整代码

#include <WiFi.h>
#include <PubSubClient.h>

// WiFi配置
const char* ssid = "YOUR_WIFI_SSID";
const char* password = "YOUR_WIFI_PASSWORD";

// MQTT代理配置
const char* mqtt_server = "broker.hivemq.com";
const int mqtt_port = 1883;
const char* mqtt_topic = "esp32/example/topic";

WiFiClient espClient;
PubSubClient client(espClient);

void setup_wifi() {
  delay(10);
  Serial.println();
  Serial.print("Connecting to WiFi: ");
  Serial.println(ssid);
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("\nWiFi connected, IP: ");
  Serial.println(WiFi.localIP());
}

void callback(char* topic, byte* payload, unsigned int length) {
  Serial.print("Message arrived on topic: ");
  Serial.println(topic);
  Serial.print("Payload: ");
  for (unsigned int i = 0; i < length; i++) {
    Serial.print((char)payload[i]);
  }
  Serial.println();
}

void reconnect() {
  while (!client.connected()) {
    Serial.print("Attempting MQTT connection...");
    // 使用唯一客户端ID避免冲突
    String clientId = "ESP32Client-" + String(random(0xffff), HEX);
    if (client.connect(clientId.c_str())) {
      Serial.println("connected");
      client.subscribe(mqtt_topic);
      Serial.print("Subscribed to: ");
      Serial.println(mqtt_topic);
    } else {
      Serial.print("failed, rc=");
      Serial.print(client.state());
      Serial.println(" retry in 5s");
      delay(5000);
    }
  }
}

void setup() {
  Serial.begin(115200);
  setup_wifi();
  client.setServer(mqtt_server, mqtt_port);
  client.setCallback(callback);
}

void loop() {
  if (!client.connected()) {
    reconnect();
  }
  client.loop();

  // 每5秒发布一次测试消息
  static unsigned long lastPublish = 0;
  if (millis() - lastPublish > 5000) {
    String payload = "Hello from ESP32, uptime: " + String(millis() / 1000) + "s";
    client.publish(mqtt_topic, payload.c_str());
    Serial.print("Published: ");
    Serial.println(payload);
    lastPublish = millis();
  }
}

运行与验证

  1. 在Arduino IDE中,将上述代码中的 YOUR_WIFI_SSID 和 YOUR_WIFI_PASSWORD 替换为实际可联网的Wi-Fi凭据。
  2. 选择开发板为 ESP32 Dev Module,正确选择COM端口,点击上传。
  3. 打开串口监视器(波特率115200),观察输出。

通过条件:串口输出依次出现以下内容即表示验证通过:

  • WiFi connected, IP: 192.168.x.x(实际IP)
  • Attempting MQTT connection...connected
  • Subscribed to: esp32/example/topic
  • 每5秒出现一次 Published: Hello from ESP32, uptime: Xs,随后紧跟 Message arrived on topic: esp32/example/topic 及相同Payload的回传信息。

最后一条回传信息证明ESP32发布的消息经公共代理路由后成功被自身订阅接收,双向通信链路完整。

常见问题

  • 连接代理失败(rc=-2或-4):确认Wi-Fi已连接且能访问外网;公共代理偶尔不稳定,可等待自动重连或更换为 test.mosquitto.org 测试。
  • 收不到回传消息:检查是否在 callback 中正确打印;确认订阅主题与发布主题完全一致(区分大小写)。
  • 客户端ID冲突:代码已使用随机后缀,若仍冲突可重启开发板重试。