如何使用带有 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++ 功能才能有效地使用它,请尝试花一些时间阅读所有文档。
我正在尝试通过 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++ 功能才能有效地使用它,请尝试花一些时间阅读所有文档。