#include <ESP8266WiFi.h> #include <PubSubClient.h> #include <ArduinoJson.h> #define deviceId "60ee4a31f4b59002868e7677_202soil" #define deviceSecret "123456" /* 连接您的WIFI SSID和密码 */ #define WIFI_SSID "renyang" #define WIFI_PASSWD "renyang123" /* 线上环境域名和端口号,不需要改 */ //华为云地址 #define MQTT_SERVER "25d9de223f.st1.iotda-device.cn-north-4.myhuaweicloud.com" #define MQTT_PORT 8883 #define MQTT_USRNAME "67e23f542902516e866abf9c_speed_1" //硬件的ID和密码 #define CLIENT_ID "67e23f542902516e866abf9c_speed_1_0_0_2025032505" #define MQTT_PASSWD "d41125c3c6587e8cb0179d2d8b12bdd5385f0c3e96e2b0937bd33b9c2a29882c" //硬件发送消息的格式 #define ALINK_BODY_FORMAT "{\"services\":[{\"service_id\":\"soilData\",\"properties\":%s}]}" #define ALINK_TOPIC_PROP_POST "$oc/devices/{"deviceId"/sys/properties/report" #define sensor_Pin 0 //获取土壤数据的引脚 unsigned long lastMs = 0; //用于连接WiFi WiFiClient espClient; //用于连接华为的mqtt服务器 PubSubClient client(espClient); //储存土壤湿度数据 float soil_data = 0; //连接wifi void wifiInit() { WiFi.mode(WIFI_STA); WiFi.begin(WIFI_SSID, WIFI_PASSWD); while (WiFi.status() != WL_CONNECTED) { delay(1000); Serial.println("WiFi not Connect"); } Serial.println("WiFi is Connected"); client.setServer(MQTT_SERVER, MQTT_PORT); /* 连接WiFi之后,连接MQTT服务器 */ } //保持mqtt连接 void mqttCheckConnect() { while (!client.connected()) { client.connect(CLIENT_ID, MQTT_USRNAME, MQTT_PASSWD); } } //上报数据到华为云 void mqttIntervalPost() { //获取土壤数据 soil_data = analogRead(sensor_Pin); //模拟数据读取(A0脚输入的数据)385-1024 // soil_data -= 385; //0-639 // soil_data /= 6.39; //0.00-100.00,变为百分比 // soil_data = 100 - soil_data; //修改为百分比越大湿度越大 // char properties[32]; // char jsonBuf[128]; // ////上报数据 // sprintf(properties, "{\"humidity\":%2f}", soil_data); // sprintf(jsonBuf, ALINK_BODY_FORMAT, properties); // boolean d = client.pu
时间: 2025-07-11 11:43:55 浏览: 11
<think>好的,我现在需要帮助用户解决ESP8266与华为云MQTT通信的代码问题。首先,我得回顾一下用户提供的引用内容,看看有没有相关的代码示例或配置步骤。用户提到了三个引用,其中引用[1]和[2]提到了使用Arduino IDE和ESP8266接入华为云,引用[3]提到了WiFi连接和PubSubClient库的使用。
首先,用户的问题是关于ESP8266使用WiFi、PubSubClient和ArduinoJson库进行华为云MQTT通信的代码问题。常见的代码问题可能包括连接失败、订阅主题错误、JSON数据格式不正确等。我需要根据引用中的信息,构建一个基本的代码框架,并指出常见问题的解决方案。
根据引用[2],配置步骤包括设置Wi-Fi的SSID和密码,华为云服务器地址,客户端ID,主题等。引用[3]提到使用WiFi.begin来连接Wi-Fi,以及接入IoTDA(可能是华为云物联网平台)。PubSubClient库用于MQTT通信,而ArduinoJson用于处理JSON数据。
接下来,我需要确保代码中的参数正确,比如服务器地址应该是华为云的MQTT地址,客户端ID需要符合华为云的设备标识,通常包括设备ID和密钥。用户可能需要使用TLS加密,但PubSubClient默认可能不支持,需要确认是否使用安全连接。如果华为云要求SSL/TLS,可能需要使用ESP8266的WiFiClientSecure库,但PubSubClient可能需要调整。
此外,订阅主题和发布主题的格式是否正确,比如华为云的主题结构是否为$oc/devices/{device_id}/sys/properties/report。JSON数据格式是否正确,比如属性上报需要特定的结构,可能要用ArduinoJson库来构建。
常见的问题可能包括WiFi连接失败,这时候需要检查SSID和密码是否正确,网络是否可用。MQTT连接失败可能是服务器地址、端口、客户端ID或用户名密码错误。华为云MQTT的端口可能是1883(非加密)或8883(加密)。用户名可能包括设备ID、密钥和时间戳,密码可能是加密后的token,需要按照华为云的规则生成。
JSON数据构建错误也是一个常见问题,用户需要确保使用ArduinoJson正确创建JSON对象,序列化后作为消息内容发送。订阅主题后,需要在回调函数中处理下发的命令,解析JSON数据并执行相应操作。
综上所述,我需要提供一个示例代码框架,包含连接WiFi、连接MQTT服务器、发布和订阅主题,以及处理JSON数据的部分,并指出常见问题点和解决方法。同时,需要引用用户提供的参考资料,特别是配置步骤和库的使用,确保用户能正确设置参数和处理数据。</think>以下是基于ESP8266的华为云MQTT通信代码解决方案及常见问题分析:
---
### 一、基础代码框架
```cpp
#include <ESP8266WiFi.h>
#include <PubSubClient.h>
#include <ArduinoJson.h>
const char* ssid = "your_SSID";
const char* password = "your_PASSWORD";
const char* mqtt_server = "iot-xxx.cn-north-4.myhuaweicloud.com"; // 华为云服务器地址[^2]
const int mqtt_port = 1883; // 非加密端口(若使用加密需改为8883)
const char* clientId = "your_device_id"; // 华为云设备ID
const char* topic_pub = "$oc/devices/{device_id}/sys/properties/report"; // 属性上报主题[^2]
WiFiClient espClient;
PubSubClient client(espClient);
void setup() {
Serial.begin(115200);
setup_wifi();
client.setServer(mqtt_server, mqtt_port);
client.setCallback(callback);
}
void setup_wifi() {
WiFi.begin(ssid, password); // 连接WiFi[^3]
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
}
void callback(char* topic, byte* payload, unsigned int length) {
// 处理平台下发命令
StaticJsonDocument<256> doc;
deserializeJson(doc, payload);
String command = doc["command"];
// 执行设备操作逻辑
}
void reconnect() {
while (!client.connected()) {
if (client.connect(clientId, "token", NULL)) { // 华为云鉴权方式
client.subscribe("$oc/devices/{device_id}/sys/commands/#"); // 订阅命令主题
} else {
delay(5000);
}
}
}
void loop() {
if (!client.connected()) reconnect();
client.loop();
// 构建属性上报JSON
StaticJsonDocument<200> doc;
doc["temperature"] = 25.5;
doc["humidity"] = 60;
char buffer[256];
serializeJson(doc, buffer);
client.publish(topic_pub, buffer); // 发布属性数据[^1]
delay(5000);
}
```
---
### 二、关键问题解决方案
#### 1. MQTT连接失败
- **现象**:`client.connect()`始终返回`false`
- **排查步骤**:
1. 确认设备三元组(设备ID/密钥)正确性
2. 检查网络是否开放1883/8883端口(企业网络可能拦截)
3. 尝试将`client.connect()`参数改为:
```cpp
client.connect(clientId, "设备ID", "设备密钥")
```
#### 2. JSON数据格式错误
- **华为云要求属性上报格式**:
```json
{
"services": [{
"service_id": "BasicData",
"properties": {
"temperature": 25.5,
"humidity": 60
}
}]
}
```
- **修正代码**:
```cpp
JsonObject service = doc.createNestedObject("services")[0];
service["service_id"] = "BasicData";
JsonObject properties = service.createNestedObject("properties");
properties["temperature"] = 25.5;
```
---
### 三、进阶优化建议
1. **安全连接**:使用`WiFiClientSecure`和CA证书(华为云提供下载)
2. **断线重连**:在`reconnect()`函数中添加心跳包检测
3. **QoS设置**:重要数据使用`client.publish(topic, payload, retained, QoS)`的QoS=1级别
---
阅读全文
相关推荐

















