使用 ESP8266 进行 mqtt 发布时出现异常
Exception during mqtt publish using ESP8266
我正在使用其 mqttAPI 将传感器读数发布到 thingSpeak。我已经在 Huzzah esp8266 板上部署了我的项目。在发布一个值之后,我得到了 ESP 异常 9、28。我想我在使用 loop() 函数时遇到了问题。这是我的代码
void loop() {
if(!mqttCli.connected()){
reconnectMQTT();
}
mqttCli.loop();
if(millis()-mqttTimer>mqttInterval){
taskWiFiCallback();
}
}
void taskWiFiCallback(){
Serial.println("task WiFi Started");
if(!mqttCli.connected()){
Serial.println("mqtt not connected");
reconnectMQTT();
return;
}
Serial.println("mqtt Connection established");
Serial.println("State:" + mqttCli.connected());
String topicString ="channels/"+String(channelID)+"/publish/"+String(writeAPIKey);
int topicLength = topicString.length();
char topicBuffer[topicLength];
topicString.toCharArray(topicBuffer,topicLength+1);
Serial.println(topicBuffer);
String dataString = String("field1="+ String(tempC,1) + "&field2=" + String(tempF,1) + "&field3=" + String(humid,1));
int dataLength = dataString.length();
char dataBuffer[dataLength];
dataString.toCharArray(dataBuffer,dataLength+1);
Serial.println(dataBuffer);
Serial.println(mqttCli.publish(topicBuffer,dataBuffer) ? "Published" : "Not Published Bawa, Do Something");
mqttTimer = millis();
}
void reconnectMQTT(){
Serial.println("setting up mqtt");
WiFiClient wifiClient;
mqttCli.setServer(mqtt_server,1883);
mqttCli.setClient(wifiClient);
mqttCli.setCallback(&callback);
// Creating a random client ID
String clientId = "ESP8266Client-";
clientId += String(random(0xffff), HEX);
while(!mqttCli.connected()){
if(mqttCli.connect(clientId.c_str())){
String subTopic = String("channels/"+ String(channelID) +
"/subscribe/json/" + String(readAPIKey));
int subTopicLength = subTopic.length();
char subTopicBuffer[subTopicLength];
subTopic.toCharArray(subTopicBuffer,subTopicLength);
String pubTopic ="channels/" + String( channelID ) +
"/publish/"+String(writeAPIKey);
char pubTopicBuffer[pubTopic.length()];
pubTopic.toCharArray(pubTopicBuffer,pubTopic.length()+1);
String message = String("field1=" + String(tempC,1) + "&field2=" +
String(tempF,1) + "&field3=" + String(humid,1));
char messageBuffer[message.length()];
message.toCharArray(messageBuffer,message.length()+ 1);
Serial.println(messageBuffer);
Serial.println(mqttCli.publish(pubTopicBuffer,messageBuffer) ? "Published" : "Unpublished");
Serial.println(mqttCli.subscribe(subTopicBuffer) ? "Subscribed" : "Unsubscribed");
}else{
Serial.print("failed, rc=");
Serial.println(mqttCli.state());
delay(1000);
}
}
}
我已经订阅了该主题,它给出了正确的结果,甚至在 reconnectMQTT() 函数中发布。
可能还有其他问题,但要开始:
int topicLength = topicString.length();
char topicBuffer[topicLength];
topicString.toCharArray(topicBuffer,topicLength+1);
您正在声明 topicLength
字节的缓冲区,然后将 topicLength + 1
字节复制到其中。您总是会超出缓冲区一个字节。您需要将其声明为 topicLength + 1
字节长,以便为 C 语言 [=16=]
字符串终止符留出空间。所以:
int topicLength = topicString.length();
char topicBuffer[topicLength+1];
topicString.toCharArray(topicBuffer,topicLength+1);
或者,更好:
int topicLength = topicString.length()+1;
char topicBuffer[topicLength];
topicString.toCharArray(topicBuffer,topicLength);
以后 dataBuffer
以及 pubTopic
、messageBuffer
和任何其他将 String
转换为 char
数组的地方也是如此。
此外,请注意您的行
subTopic.toCharArray(subTopicBuffer,subTopicLength);
不会在您在其他地方的长度上加 1 的地方加 1。
我正在使用其 mqttAPI 将传感器读数发布到 thingSpeak。我已经在 Huzzah esp8266 板上部署了我的项目。在发布一个值之后,我得到了 ESP 异常 9、28。我想我在使用 loop() 函数时遇到了问题。这是我的代码
void loop() {
if(!mqttCli.connected()){
reconnectMQTT();
}
mqttCli.loop();
if(millis()-mqttTimer>mqttInterval){
taskWiFiCallback();
}
}
void taskWiFiCallback(){
Serial.println("task WiFi Started");
if(!mqttCli.connected()){
Serial.println("mqtt not connected");
reconnectMQTT();
return;
}
Serial.println("mqtt Connection established");
Serial.println("State:" + mqttCli.connected());
String topicString ="channels/"+String(channelID)+"/publish/"+String(writeAPIKey);
int topicLength = topicString.length();
char topicBuffer[topicLength];
topicString.toCharArray(topicBuffer,topicLength+1);
Serial.println(topicBuffer);
String dataString = String("field1="+ String(tempC,1) + "&field2=" + String(tempF,1) + "&field3=" + String(humid,1));
int dataLength = dataString.length();
char dataBuffer[dataLength];
dataString.toCharArray(dataBuffer,dataLength+1);
Serial.println(dataBuffer);
Serial.println(mqttCli.publish(topicBuffer,dataBuffer) ? "Published" : "Not Published Bawa, Do Something");
mqttTimer = millis();
}
void reconnectMQTT(){
Serial.println("setting up mqtt");
WiFiClient wifiClient;
mqttCli.setServer(mqtt_server,1883);
mqttCli.setClient(wifiClient);
mqttCli.setCallback(&callback);
// Creating a random client ID
String clientId = "ESP8266Client-";
clientId += String(random(0xffff), HEX);
while(!mqttCli.connected()){
if(mqttCli.connect(clientId.c_str())){
String subTopic = String("channels/"+ String(channelID) +
"/subscribe/json/" + String(readAPIKey));
int subTopicLength = subTopic.length();
char subTopicBuffer[subTopicLength];
subTopic.toCharArray(subTopicBuffer,subTopicLength);
String pubTopic ="channels/" + String( channelID ) +
"/publish/"+String(writeAPIKey);
char pubTopicBuffer[pubTopic.length()];
pubTopic.toCharArray(pubTopicBuffer,pubTopic.length()+1);
String message = String("field1=" + String(tempC,1) + "&field2=" +
String(tempF,1) + "&field3=" + String(humid,1));
char messageBuffer[message.length()];
message.toCharArray(messageBuffer,message.length()+ 1);
Serial.println(messageBuffer);
Serial.println(mqttCli.publish(pubTopicBuffer,messageBuffer) ? "Published" : "Unpublished");
Serial.println(mqttCli.subscribe(subTopicBuffer) ? "Subscribed" : "Unsubscribed");
}else{
Serial.print("failed, rc=");
Serial.println(mqttCli.state());
delay(1000);
}
}
}
我已经订阅了该主题,它给出了正确的结果,甚至在 reconnectMQTT() 函数中发布。
可能还有其他问题,但要开始:
int topicLength = topicString.length();
char topicBuffer[topicLength];
topicString.toCharArray(topicBuffer,topicLength+1);
您正在声明 topicLength
字节的缓冲区,然后将 topicLength + 1
字节复制到其中。您总是会超出缓冲区一个字节。您需要将其声明为 topicLength + 1
字节长,以便为 C 语言 [=16=]
字符串终止符留出空间。所以:
int topicLength = topicString.length();
char topicBuffer[topicLength+1];
topicString.toCharArray(topicBuffer,topicLength+1);
或者,更好:
int topicLength = topicString.length()+1;
char topicBuffer[topicLength];
topicString.toCharArray(topicBuffer,topicLength);
以后 dataBuffer
以及 pubTopic
、messageBuffer
和任何其他将 String
转换为 char
数组的地方也是如此。
此外,请注意您的行
subTopic.toCharArray(subTopicBuffer,subTopicLength);
不会在您在其他地方的长度上加 1 的地方加 1。