Второй элемент в массиве не назначается из объекта структуры, ArduinoJson

Я получил приведенный ниже код, сгенерированный этим замечательным инструментом.

const size_t capacity = JSON_ARRAY_SIZE(2) + JSON_OBJECT_SIZE(1) + JSON_OBJECT_SIZE(4) + 2*JSON_OBJECT_SIZE(7);
DynamicJsonDocument doc(capacity);

JsonObject config = doc.createNestedObject("config");
config["type"] = "power_plug";
config["chip_id"] = "12345";
config["mac_address"] = "abc";

JsonArray config_attachments = config.createNestedArray("attachments");

JsonObject config_attachments_0 = config_attachments.createNestedObject();
config_attachments_0["name"] = "socket";
config_attachments_0["input_type"] = "toggle_switch";
config_attachments_0["on_state"] = "on";
config_attachments_0["off_state"] = "off";
config_attachments_0["pin_type"] = "output";
config_attachments_0["pin"] = 15;
config_attachments_0["current_state"] = "on";

JsonObject config_attachments_1 = config_attachments.createNestedObject();
config_attachments_1["name"] = "socket_1";
config_attachments_1["input_type"] = "toggle_switch";
config_attachments_1["on_state"] = "on";
config_attachments_1["off_state"] = "off";
config_attachments_1["pin_type"] = "output";
config_attachments_1["pin"] = 12;
config_attachments_1["current_state"] = "off";

serializeJson(doc, Serial);

Это правильно распечатывает желаемый json. но при изменении одной строки из второго элемента массива, чтобы взять on_state из моего объекта структуры d_config,

Serial.println(">>" + d_configs.peripherals[1].current_state);
Serial.println(">>" + d_configs.peripherals[1].on_state);
config_attachments_1["on_state"] = d_configs.peripherals[1].on_state;

Синтаксический анализ становится неожиданным, и некоторые ключи из сериализованной строки json теряются. В приведенном выше случае это печатается в последовательном мониторе;

>>off
>>on
{"config":{"type":"power_plug","chip_id":"12345","mac_address":"abc","attachments":[{"name":"socket","input_type":"toggle_switch","on_state":"on","off_state":"off","pin_type":"output","pin":15,"current_state":"on"},{"name":"socket_1","input_type":"toggle_switch","on_state":"on","off_state":"off","pin_type":"output","pin":12}]}}

ПРИМЕЧАНИЕ во втором элементе вложений полностью отсутствует ключ current_state. Когда я присваиваю все значения из этого объекта структуры, сериализованный json пропускает гораздо больше ключей... и поведение довольно неожиданное. вот как я определил свои структуры;

typedef struct Peripheral{
    String name;
    String input_type;
    String on_state;
    String off_state;
    String pin_type;
    String current_state;
    int pin;
};

typedef struct {
  String type;
  String chip_id;
  String mac_address;
  Peripheral peripherals[10];    
} DeviceConfig;

Я не уверен, что это проблема во время сериализации или что-то еще... :/ Будем признательны за любую помощь :) .

ОБНОВЛЕНИЕ Когда я добавил три элемента во вложения, в сериализованной строке json отсутствуют некоторые ключи только для последнего элемента. Похоже, только последний элемент в списке имеет проблемы с сериализацией.

, 👍0


1 ответ


Лучший ответ:

2

ArduinoJson хранит строки по-разному в зависимости от их типа:

  • для const char* сохраняет указатель;
  • для других типов (char*, String...) копирует строку.

Поскольку ArduinoJson хранит копию строки в JsonDocument, вы должны увеличить емкость JsonDocument.

В вашем случае вы передаете Peripheral::current_state, который является String, поэтому ArduinoJson создает копию в JsonDocument. Увеличение capacity на несколько байтов должно решить проблему.

Обратите внимание, что ArduinoJson Assistant также вычисляет количество байтов, необходимых для хранения всех строк. Найдите «Дополнительные байты для дублирования строк» на правой панели.

,