今天来搞一个ESP8266连接阿里云项目,编译上传开发板成功后发现设备一直未成功激活上线,ESP8266连接上WIFI后有马上断开,在查看串口信息后发现
Connecting to MQTT Server ...
MQTT connect failed, error code:2
No need to try again.
{"id":"123","version":"1.0","method":"thing.event.property.post","params":{"LightSwitch":0}}
中文翻译:正在连接到MQTT服务器...MQTT连接失败,错误代码:2 ,不需要再试一次。
在提交工单后得到的回复是
阿里云工程师 ***** 号 :
你好, 返回值2表示客户端标识符不正确, -4表示用户名或者密码错误。 请做以下检查:
1、先检查一下PubSubClient.h文件中定义的 MQTT_MAX_PACKET_SIZE的值, 最好要大于1024, MQTT_KEEPALIVE 大于60;
2、检查一下你的签名和接入参数的设置,可以参考文档
https://help.aliyun.com/document_detail/73742.html?spm=a2c4g.11186623.6.650.3820619bBWPshh
一波操作之后终于把它“变绿”啦!
完整参考代码
#include <ESP8266WiFi.h>
#include <ArduinoJson.h>
#include <aliyun_mqtt.h>
//定义LED灯
#define LED0 D0
//初始化次态
int redLedState0 = 0;
//初始化现态
int last0 = 0;
//上云时间现态
unsigned long lastSend = 0;
//你的wifi
#define WIFI_SSID "智定义科技提示您:此处填写WIFI名称"
#define WIFI_PASSWD "智定义科技提示您:此处填写WIFI密码"
//阿里云三元组
#define PRODUCT_KEY "智定义科技提示您:此处填写 PRODUCT KEY"
#define DEVICE_NAME "智定义科技提示您:此处填写 DEVICE NAME"
#define DEVICE_SECRET "智定义科技提示您:此处填写 DEVICE SECRET"
//订阅和发布时所需的主题
#define ALINK_BODY_FORMAT "{\"id\":\"123\",\"version\":\"1.0\",\"method\":\"%s\",\"params\":%s}"
#define ALINK_TOPIC_PROP_POST "/sys/" PRODUCT_KEY "/" DEVICE_NAME "/thing/event/property/post"
#define ALINK_TOPIC_PROP_POSTRSP "/sys/" PRODUCT_KEY "/" DEVICE_NAME "/thing/event/property/post_reply"
#define ALINK_TOPIC_PROP_SET "/sys/" PRODUCT_KEY "/" DEVICE_NAME "/thing/service/property/set"
#define ALINK_METHOD_PROP_POST "thing.event.property.post"
//创建WiFiClient实例
WiFiClient espClient;
//创建MqttClient实例
PubSubClient mqttClient(espClient);
//连接Wifi
void initWifi(const char *ssid, const char *password)
{
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED)
{
Serial.println("WiFi does not connect, try again ...");
delay(3000);
}
Serial.println("Wifi is connected.");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
}
//监听云端下发指令并处理
void callback(char *topic, byte *payload, unsigned int length)
{
Serial.println();
Serial.println();
Serial.print("Message arrived [");
Serial.print(topic);
Serial.print("] ");
Serial.println();
//云端下发属性设置topic = "[/sys/a10PnXZBgsl/7L9EUbLv113EkYkF7fpD/thing/service/property/set]"
payload[length] = '\0';
Serial.println((char *)payload);
//const char *payload = "{"method":"thing.service.property.set","id":"282860794","params":{"LightSwitch":1},"version":"1.0.0"}"
if (strstr(topic, ALINK_TOPIC_PROP_SET))
{
//json解析payload
StaticJsonBuffer<400> jsonBuffer;
JsonObject &root = jsonBuffer.parseObject(payload);
//判断json解析是否成功
if (!root.success())
{
Serial.println("parseObject() failed");
}
else
{
Serial.println("parseObject() success");
//redLedState0 = json解析后的"LightSwitch"的值
redLedState0 = root["params"]["LightSwitch"];
Serial.print(redLedState0);
Serial.println(" set sucess");
Serial.println();
Serial.print("LED0 State: ");
Serial.println(redLedState0);
digitalWrite(LED0, redLedState0);
}
}
}
//连接Mqtt订阅属性设置Topic
void mqttCheckConnect()
{
bool connected = connectAliyunMQTT(mqttClient, PRODUCT_KEY, DEVICE_NAME, DEVICE_SECRET);
if (connected)
{
Serial.println("MQTT connect succeed!");
//订阅属性设置Topic
mqttClient.subscribe(ALINK_TOPIC_PROP_SET);
Serial.println("subscribe done");
}
}
// 上报属性Topic数据
void mqttIntervalPost()
{
char param[256];
char jsonBuf[512];
sprintf(param, "{\"LightSwitch\":%d}", digitalRead(LED0));
sprintf(jsonBuf, ALINK_BODY_FORMAT, ALINK_METHOD_PROP_POST, param);
//jsonBuf = "{\"id\":\"123\",\"version\":\"1.0\",\"method\":\"thing.event.property.post\",\"params\":"\{\"LightSwitch\":%d}\"}"
Serial.println(jsonBuf);
mqttClient.publish(ALINK_TOPIC_PROP_POST, jsonBuf);
}
void setup()
{
Serial.begin(115200);
pinMode(LED0, OUTPUT);
digitalWrite(LED0, 0);
initWifi(WIFI_SSID, WIFI_PASSWD);
Serial.println();
Serial.println();
mqttCheckConnect(); //初始化首次链接
mqttIntervalPost(); //上报初始化数据
Serial.println();
mqttClient.setCallback(callback); // 回调,监听云端下发指令,当ESP8266收到订阅Topic后调用callback函数
}
void loop()
{
//每隔1s尝试连接一次云
if (millis() - lastSend >= 10000)
{
mqttCheckConnect();
lastSend = millis();
}
//判断三灯现态与次态的关系,减少无意义的上报
if (last0 != redLedState0)
{
last0 = redLedState0;
mqttIntervalPost();
Serial.println();
}
mqttClient.loop();
}