如何使用带有 ArduinoJson 的 createNestedArray() 将 JsonArray 放入 JsonObject 中?

How to put an JsonArray in a JsonObject using createNestedArray() with ArduinoJson?

我正在尝试通过 TCP 将 JSON-数据从 ESP32 发送到另一个客户端。这应该反复发生。 JSON-String 包含一个数组。但是,当我尝试使用函数 createNestedArray() 在 Arduino 文档的 example 中将数组放入 JSON 文档时,它会工作几次,直到它开始创建空数组.

最小代码是这样的:

#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

有人知道为什么它此时突然停止工作吗?

首先,在说问题之前,先说说json对象需要的容量(即大小)。如果使用 ArduinoJson Assistant,则 json 对象

{
  "arrValues": [
    42,
    77
  ]
}

将需要大约 58 个字节(按照 ArduinoJson 助手的建议为 ESP32 额外分配 10 个字节),因此您将 3000 个字节分配给 doc 会浪费大量内存,而 60 个字节将是足以满足您 json 对象的目的。

StaticJsonDocument<60> doc;

现在关于你描述的问题。您有一个 3000 字节的 StaticJsonDocument doc,并且不断地将 JsonArray root 插入 doc,这就像将 root 无限追加到 doc,所以迟早会溢出。我看不出有任何理由需要经常这样做,如果您需要在循环中创建一个 json 对象,请将 StaticJsonDocument 的声明移到您的循环中并在需要时创建它.

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); 

ArduinoJson 是一个强大的库,但它需要更好地了解 C++ 功能才能有效地使用它,请尝试花一些时间阅读所有文档。