Как поместить JsonArray в JsonObject, используя createNestedArray () с Arduino Json? - PullRequest
0 голосов
/ 24 февраля 2020

Я пытаюсь отправить JSON -данные из ESP32 через TCP другому клиенту. Это должно происходить многократно. Строка JSON содержит массив. Однако, когда я пытаюсь поместить массив в JSON -документ, как в примере документации Arduino, используя функцию createNestedArray (), он работает несколько раз, пока не начнет создавать пустые массивы ,

Минимальный код такой:

#include "ArduinoJson.h"

StaticJsonDocument<3000> doc;
JsonObject root = doc.to<JsonObject>();

void insertJsonArray(JsonObject root) {
    JsonArray arr = root.createNestedArray("arrValues");
    arr.add(42);
    arr.add(77); 
}

void setup() {
    Serial.begin(115200);
}

void loop() {
    insertJsonArray(root);

    // Print values
    serializeJsonPretty(root, Serial);

    // Print size of Json-Document
    Serial.print("Json-Size: ");
    Serial.println(root.memoryUsage());

    delay(250);
}

Вывод выглядит ожидаемым для первых 92 итераций:

{
  "arrValues": [
    42,
    77
  ]
}
Json-Size: 48

Но после этого он отправляет только пустые массивы:

{
  "arrValues": []
}
Json-Size: 16

Кто-нибудь знает, почему он вдруг перестает работать в этот момент?

1 Ответ

1 голос
/ 25 февраля 2020

Прежде всего, прежде чем говорить о проблеме, давайте поговорим о емкости (т.е. размере) требуемого объекта json. Если вы используете Arduino Json Assistant , для объекта json

{
  "arrValues": [
    42,
    77
  ]
}

потребуется около 58 байт (с дополнительным выделением 10 байт для ESP32, как предлагает Arduino Json Assistant ), поэтому выделение 3000 байтов для doc приведет к потере большого количества памяти, в то время как для цели вашего json объекта будет достаточно 60 байтов.

StaticJsonDocument<60> doc;

Теперь о проблеме, с которой вы столкнулись. описано. У вас есть StaticJsonDocument doc из 3000 байтов, и вы постоянно вставляете JsonArray root в doc, это похоже на бесконечное добавление root в doc, поэтому он рано или поздно переполнится. Я не вижу причин, почему вам нужно делать это постоянно, если вам нужно создать json объект в al oop, переместите объявление StaticJsonDocument в ваш l oop и создайте его, когда вам нужно it.

void loop() {
    StaticJsonDocument<60> doc;
    JsonObject root = doc.to<JsonObject>();

    JsonArray arr = root.createNestedArray("arrValues");
    arr.add(42);
    arr.add(77); 
    ...
}

Вы также можете использовать DynamicJsonDocument вместо StaticJsonDocument:

    // use ArduinoJson Assistant tool to get the capacity
    const size_t capacity = JSON_ARRAY_SIZE(2) + JSON_OBJECT_SIZE(1) + 20;
    DynamicJsonDocument doc(capacity);
    JsonObject root = doc.to<JsonObject>();

    JsonArray arr = root.createNestedArray("arrValues");
    arr.add(42);
    arr.add(77); 

Arduino Json - мощная библиотека, но требует немного лучшего понимания возможности C ++ для его эффективного использования, попробуйте потратить некоторое время на go через всю документацию.

...