Прошивка зависает в obj.printto(клиенте) в esp32

esp32 json

Я использую ESP32 для сбора некоторых данных, а затем отправляю их с помощью ArduinoJson. Однако иногда прошивка застревает на линии передачи данных в obj.printTo(client). У меня есть журналы того же самого. Есть ли у вас какие-либо идеи относительно того, что может заставить его зависнуть? И любой способ избежать этого в будущем.

Журналы:

12:28:00.584 -> [V][ssl_client.cpp:276] send_ssl_data(): запись HTTP-запроса...

12:28:00.584 -> [V][ssl_client.cpp:276] send_ssl_data(): запись HTTP-запроса...
12:47:11.229 -> [E][ssl_client.cpp:33] handle_error(): НЕИЗВЕСТНЫЙ КОД ОШИБКИ (004E) 12:47:11.229 -> [E][ssl_client.cpp:35] handle_error(): сообщение MbedTLS код:-78

12:47:11.229 -> [V][ssl_client.cpp:245] stop_ssl_socket(): очистка SSL-соединения.
12:47:11.229 -> запрос отправлен
12:47:12.217 -> сбой esp32/Arduino CI
12:47:12.217 -> ответ был: 12:47:12.217-> ==========
12:47:12.217 ->
12:47:12.217 -> ==========
12:47:12.217 -> закрытие соединения

Код отправки:

jsonBuffer.clear();
JsonObject &rootObject = jsonBuffer.createObject();
JsonObject &dataObject = rootObject.createNestedObject("data");
JsonArray &X1dataObject = dataObject.createNestedArray("X1");
JsonArray &Y1dataObject = dataObject.createNestedArray("Y1");
JsonArray &Z1dataObject = dataObject.createNestedArray("Z1");
JsonArray &T1dataObject = dataObject.createNestedArray("T1");

vTaskDelay(10);

if (send_flag) {
  digitalWrite(2,0);
  send_flag = false;
  int connection_iterator = 0;
  int connection_iterator2 = 0;
  for (int iterator = 0; iterator < SAMPLE_SIZE; iterator++) {
    X1dataObject.add(X1dataArray[iterator]);
    Y1dataObject.add(Y1dataArray[iterator]);
    Z1dataObject.add(Z1dataArray[iterator]);
  }
  T1dataObject.add((float)(analogRead(NTC)*0.0244));

  rootObject["coreid"] = String(low, HEX) + String(high, HEX);
  //rootObject["coreid_high"] = String(high, HEX);
  rootObject["sample_time"] = int(time_taken);
  rootObject["firmware_version"] = FIRMWARE_UPDATE_VERSION;
  rootObject.prettyPrintTo(Serial);
  Serial.print("connecting to ");
  Serial.println(host);
  while ((!client.connect(host, httpsPort)) && !setup_mode) {
    connection_iterator++;
    Serial.println("connection failed! Retrying..");
    delay(5000);
    if (connection_iterator >= 10)
      ESP.restart();
  }
  if (client.verify(fingerprint, host)) {
    Serial.println("certificate matches");
  } else {
    Serial.println("certificate doesn't match");
  }
  digitalWrite(LED_BUILTIN, HIGH);
  Serial.print("requesting URL: ");
  Serial.println(url);
  client.println(String("POST ") + url + " HTTP/1.0");
  client.println(String("Host: ") + host);
  client.println("Cache-Control: no-cache");
  client.println("Content-Type: application/json");
  client.print("Content-Length: ");
  client.println(rootObject.measureLength());
  client.println();
  rootObject.printTo(client);
  Serial.println("NUMBER OF INTERRUPTS:");
  Serial.println(interruptCounter);
  Serial.println("request sent");
  while ((client.connected()) && !setup_mode) {
    connection_iterator2++;

    String line = client.readStringUntil('\n');
    if (line == "\r") {
      Serial.println("headers received");
      break;
    }
    Serial.println("Waiting for response");
    delay(500);
    if (connection_iterator2 >= 40)
      break;
  }
  String line = client.readStringUntil('\n');
  if (line.startsWith("{")) {
    Serial.println("esp32/Arduino CI successfull!");
  } else {
    Serial.println("esp32/Arduino CI has failed");
  }
  Serial.println("reply was:");
  Serial.println("==========");
  Serial.println(line);
  Serial.println("==========");
  Serial.println("closing connection");
  digitalWrite(LED_BUILTIN, LOW);
  // readRegister(INT_SOURCE, 1, &dummy_read);
}

, 👍0


2 ответа


2

Я вижу, что вы используете SSL. SSL использует много оперативной памяти, и возможно, что стек и куча конфликтуют, что приведет к повреждению работающего скетча. Я рекомендую вам добавить объем свободной кучи в ваши операторы журнала, чтобы вы могли видеть, как он меняется, и это поможет вам увидеть, происходит ли это.

Чтобы получить бесплатную кучу, вы можете использовать esp_get_free_heap_size() — дополнительную документацию по этой функции можно найти в онлайн-документация espressif.

,

Я обязательно запишу размер кучи, но, похоже, этого не происходит, поскольку код не повреждается и даже не дает сбоя. Просто через некоторое время он выдает handle_error и возобновляет работу. Однако я все равно буду регистрировать размер кучи и наблюдать за отклонениями., @peeyush tekriwal

Я провел тестирование, и куча, похоже, не проблема. После успешной передачи в куче все еще остается около 75% доступной памяти., @peeyush tekriwal

@peeyushtekriwal Я думаю, вам нужно опубликовать свой код, чтобы кто-нибудь мог вам помочь., @Phil Haigh

Понятно. добавлю код выше, @peeyush tekriwal


0

Итак, я обнаружил, что, по-видимому, существует некоторая проблема при работе с WiFiClientSecure при отправке больших пакетов данных. По защищенной линии данные отправляются небольшими пакетами, что занимает много времени, а также, если сервер в любой момент станет недоступен, программа зависнет на нем. Однако эта проблема не была столь заметной, когда я использовал тот же механизм в esp8266. Тем не менее, решением было бы использовать буфер для отправки данных.

Кроме того, эта версия кода была написана с использованием ArduinoJson V5. Но даже после перехода на ArduinoJson V6 проблема остается. Похоже, что какая бы новая функция JsonDocument ни была реализована в новой версии, она все еще далека от обеспечения эффективности буфера и откатывается назад.

Однако, если кто-то еще найдет лучшее решение, обновите его.

,

Последние разработки: я обнаружил эту проблему спустя долгое время после того, как не смог ее решить, и до сих пор не могу найти никаких зацепок. Чип, кажется, устанавливает соединение с сервером, но каким-то образом зависает и не может продолжить работу. Следует отметить, что тот же механизм работает и с ESP8266., @peeyush tekriwal