0

I got the below code generated this amazing tool.

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

This prints out the desired json properly. but when amend single line from the second array item, to take the on_state from my struct object 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;

the parsing gets quiet unexpected, and some of the keys from serialised string json gets missing. For above case, This gets printed in serial monitor;

>>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}]}}

NOTE in the second item of attachments, the key current_state is entirely missing. When I assign all values from this struct object, the serialised json misses many more keys... and the behaviour is quite unexpected. here is how I have defined my structs;

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;

I am not sure if its an issue during serialization or something else... :/ Any help would be highly appreciated :) .

UPDATE When I added three items inside attachments, then the serialized json string is missing some keys for only the last item. Seems like only the last item on the list is having problem getting serialized.

1 Answer 1

2

ArduinoJson stores strings differently depending on their types:

  • for const char*, it saves a pointer;
  • for other types (char*, String...) it copies the string.

Because ArduinoJson stores the copy of the string in the JsonDocument, you must increase the capacity of the JsonDocument.

In your case, you pass Peripheral::current_state, which is a String, so ArduinoJson makes a copy in the JsonDocument. Increasing capacity by a few bytes should solve the problem.

Note that the ArduinoJson Assistant also computes the number of bytes required to store all the strings. Look for "Additional bytes for strings duplication" on the right panel.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.