ESP32 的 Arduino MQTT Client 使用指南
1. 安装必要的库
首先需要安装 PubSubClient 库:
2. 基础连接示例
#include <WiFi.h>
#include <PubSubClient.h>
const char* ssid = "你的WiFi名称";
const char* password = "你的WiFi密码";
const char* mqtt_server = "broker.hivemq.com";
const int mqtt_port = 1883;
const char* mqtt_user = "";
const char* mqtt_password = "";
WiFiClient espClient;
PubSubClient client(espClient);
void setup_wifi() {
delay(10);
Serial.println();
Serial.print("正在连接: ");
Serial.println(ssid);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.println("WiFi 连接成功");
Serial.println("IP 地址: ");
Serial.println(WiFi.localIP());
}
void callback(char* topic, byte* payload, unsigned int length) {
Serial.print("收到消息 [");
Serial.print(topic);
Serial.print("]: ");
for (int i = 0; i < length; i++) {
Serial.print((char)payload[i]);
}
Serial.println();
}
void reconnect() {
while (!client.connected()) {
Serial.print("尝试 MQTT 连接...");
String clientId = "ESP32Client-";
clientId += String(random(0xffff), HEX);
if (client.connect(clientId.c_str(), mqtt_user, mqtt_password)) {
Serial.println("连接成功");
client.subscribe("esp32/test");
client.subscribe("esp32/control");
} else {
Serial.print("失败,错误代码: ");
Serial.print(client.state());
Serial.println(" 5秒后重试...");
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();
static unsigned long lastMsg = 0;
if (millis() - lastMsg > 5000) {
lastMsg = millis();
String message = "Hello from ESP32 - " + String(millis());
client.publish("esp32/status", message.c_str());
Serial.println("消息已发布: " + message);
}
}3. 高级功能示例
3.1 带 QoS 和保留消息的发布
void publishWithQoS() {
client.publish("esp32/temp", "25.5");
client.publish("esp32/humidity", "60.2", true);
}
void publishRetainedMessage() {
boolean retained = true;
client.publish("esp32/device/status", "online", retained);
}3.2 完整的主题管理
const char* TOPIC_STATUS = "esp32/status";
const char* TOPIC_TEMP = "esp32/sensor/temperature";
const char* TOPIC_HUMIDITY = "esp32/sensor/humidity";
const char* TOPIC_CONTROL = "esp32/control/#";
void setupTopics() {
client.subscribe(TOPIC_CONTROL);
client.subscribe("esp32/command/#");
}
void callback(char* topic, byte* payload, unsigned int length) {
String message;
for (int i = 0; i < length; i++) {
message += (char)payload[i];
}
Serial.print("主题: ");
Serial.print(topic);
Serial.print(" | 消息: ");
Serial.println(message);
if (String(topic) == "esp32/control/led") {
if (message == "ON") {
digitalWrite(LED_BUILTIN, HIGH);
client.publish("esp32/status/led", "ON");
} else if (message == "OFF") {
digitalWrite(LED_BUILTIN, LOW);
client.publish("esp32/status/led", "OFF");
}
}
}3.3 带 JSON 的数据发布
#include <ArduinoJson.h>
void publishSensorData() {
StaticJsonDocument<200> doc;
doc["device"] = "ESP32_001";
doc["temperature"] = readTemperature();
doc["humidity"] = readHumidity();
doc["timestamp"] = millis();
String jsonString;
serializeJson(doc, jsonString);
client.publish("esp32/sensor/data", jsonString.c_str());
}4. 安全连接 (TLS/SSL)
#include <WiFiClientSecure.h>
WiFiClientSecure espClient;
PubSubClient client(espClient);
void setup() {
espClient.setCACert(root_ca);
client.setServer(mqtt_server, 8883);
}
const char* root_ca = \
"-----BEGIN CERTIFICATE-----\n" \
"你的 CA 证书内容\n" \
"-----END CERTIFICATE-----\n";5. 完整的物联网应用示例
#include <WiFi.h>
#include <PubSubClient.h>
#include <DHT.h>
#define DHT_PIN 4
#define DHT_TYPE DHT22
DHT dht(DHT_PIN, DHT_TYPE);
const char* ssid = "你的WiFi";
const char* password = "你的密码";
const char* mqtt_server = "broker.hivemq.com";
WiFiClient espClient;
PubSubClient client(espClient);
unsigned long lastSensorRead = 0;
const long sensorInterval = 30000;
void readAndPublishSensorData() {
float temperature = dht.readTemperature();
float humidity = dht.readHumidity();
if (!isnan(temperature) && !isnan(humidity)) {
char tempStr[8];
char humStr[8];
dtostrf(temperature, 6, 2, tempStr);
dtostrf(humidity, 6, 2, humStr);
client.publish("iot/sensor/temperature", tempStr);
client.publish("iot/sensor/humidity", humStr);
Serial.printf("传感器数据已发布: 温度=%s°C, 湿度=%s%%\n", tempStr, humStr);
}
}
void setup() {
Serial.begin(115200);
dht.begin();
setup_wifi();
client.setServer(mqtt_server, 1883);
client.setCallback(callback);
pinMode(LED_BUILTIN, OUTPUT);
}
void loop() {
if (!client.connected()) {
reconnect();
}
client.loop();
if (millis() - lastSensorRead > sensorInterval) {
lastSensorRead = millis();
readAndPublishSensorData();
}
}6. 常见问题解决
连接失败:检查 WiFi 和 MQTT 服务器配置
频繁断开:调整 client.setKeepAlive(60) 和 client.setSocketTimeout(30)
内存不足:减少消息大小或发布频率
QoS 问题:确认服务器支持的 QoS 级别
7. 重要配置参数
void setupMqtt() {
client.setServer(mqtt_server, mqtt_port);
client.setCallback(callback);
client.setKeepAlive(60);
client.setSocketTimeout(30);
client.setBufferSize(1024);
}这个指南涵盖了 ESP32 Arduino MQTT Client 的主要用法,你可以根据具体需求进行调整和扩展。