ESP32 Arduino PubSub publi sh ошибка для массива переменных? - PullRequest
0 голосов
/ 25 марта 2020

Я программирую ESP32 с Arduino и публикую MQTT-сообщения, используя стандартную библиотеку pubsubclient.

В моем l oop ниже я заметил, что опубликовано "Inside l oop", однако второе сообщение переменной jsonObjChar, похоже, никогда не публикуется в топи c? В последовательном мониторе нет ошибок.

void loop(){
  String temperature = String(readDHTTemperature());
  String humidity = String(readDHTHumidity());
  String light = String(readLDRLight());


  String jsonObj = "{";    
  jsonObj.concat("\"deviceId\":\"123456\"");
  jsonObj.concat(",");
  jsonObj.concat("\"messageType\":\"ambientSensorReading\"");
  jsonObj.concat(",");
  jsonObj.concat("\"temperature\":\"");
  jsonObj.concat(temperature);
  jsonObj.concat("\"");
  jsonObj.concat(",");
  jsonObj.concat("\"humidity\":\"");
  jsonObj.concat(humidity);
  jsonObj.concat("\"");
  jsonObj.concat(",");
  jsonObj.concat("\"light\":\"");
  jsonObj.concat(light);
  jsonObj.concat("\"}");

  delay(1000);

  int jsonObjCharLength = jsonObj.length() + 1;
  char jsonObjChar[jsonObjCharLength];
  jsonObj.toCharArray(jsonObjChar, jsonObjCharLength);

  Serial.println("PREPARED");  
  Serial.println(jsonObjChar);  

  const char topic[13] = "prototype001";

  client.publish(topic, "inside loop");
  client.publish(topic, jsonObjChar);

  // ... and resubscribe
  client.subscribe("prototype001");

  delay(5000);

}

Кажется, что переменная jsobObjChar в порядке, когда я распечатываю ее на последовательном мониторе, она выглядит как обычная строка (я структурирован в формате JSON для обработки на на стороне сервера)

20:13:41.494 -> PREPARED

20:13:41.494 -> {"deviceId":"123456","messageType":"ambientSensorReading","temperature":"25.10","humidity":"49.90","light":"2592"}

20:13:46.521 ->

Если это поможет, я использую cloudmqtt.

Любая помощь будет принята с благодарностью !!!

1 Ответ

1 голос
/ 25 марта 2020

Постарайтесь избавиться от строк, они сломают вашу кучу и вызовут сбои. Определите глобальные фиксированные charBuffers (достаточно большие, чтобы принять самое большое сообщение) и помощник (tmp chars) для преобразования и других вещей. Не определяйте const-символы в l oop, делайте это перед установкой, чтобы компилятор помещал их в стек и не использует кучу во время выполнения. Я изменил ваш код по этому принципу и добавил дополнительную задержку между сообщениями:

const char topic[13] = "prototype001"; // goes to the stack
char jsonObjChar [256] = '\0'; // set it large enough goes to the stack not heap!
char numBuffer [16] = '\0'; //tmpBuffer for conversion of ints to char

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


  strcpy (jsonObj, "{");    // Initialize/clear char by using strcpy
  strcat(jsonObj, "\"deviceId\":\"123456\"");   // strcat append
  strcat(jsonObj,",");
  strcat(jsonObj,"\"messageType\":\"ambientSensorReading\"");
  strcat(jsonObj,",");
  strcat(jsonObj,"\"temperature\":\"");
  // conversion only needed if temperature is an int, if its char use strcat(jsonObj,readDHTTemperature());
  itoa (readDHTTemperature(), numBuffer, 10); // Converts an int to a char array 
  strcat(jsonObj,numbuffer);
  strcat(jsonObj,"\"");
  strcat(jsonObj,",");
  strcat(jsonObj,"\"humidity\":\"");
  // if already char use strcat(jsonObj,readDHTHumidity());
  itoa (readDHTHumidity(), numBuffer, 10);
  strcat(jsonObj,numbuffer);
  strcat(jsonObj,"\"");
  strcat(jsonObj,",");
  strcat(jsonObj,"\"light\":\"");
  // if char strcat(jsonObj,readLDRLight());
  itoa (readLDRLight(),numBuffer. 10);
  strcat(jsonObj,numbuffer);
  strcat(jsonObj,"\"}");

  delay(1000);


  Serial.println("PREPARED");  
  Serial.println(jsonObjChar);  

  client.publish(topic, "inside loop");
  delay(1000); // for test onl<
  client.publish(topic, jsonObjChar);

  // ... and resubscribe
  client.subscribe("prototype001");

  delay(5000);
 client.loop();

}

Если это работает - хорошо. Если нет, то следующим шагом отладки будет посмотреть, что получено на сервере.

...