-
-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Description
Describe the issue
Deserialisation is changing source data, and producing unexpected results.
Troubleshooter report
Here is the report generated by the ArduinoJson Troubleshooter:
- The program uses ArduinoJson 6
- The issue happens at run time
- The issue concerns deserialization
deserializeJson()returnsOk- Some values are missing
- The JSON document is not large
Environment
Here is the environment that I'm using':
- Microconroller: ESP32
- Core/runtime: ESP32 core for Arduino v2.0.10
- IDE: Arduino IDE 1.8.19
Reproduction
I have a program which captures some data as a short JSON string and stores in logHistory[i].logDataString e.g.
{"dbAverage":36.1,"dbMin":36.1,"dbMax":36.1,"timestamp":"2025-11-03 15:45:14"}
I have a webpage to monitor all values in the array logHistory[i].logDataString and want it to show them as a single JSON document e.g.
{"logHistory":[{"logData":{"dbAverage":36.1,"dbMin":36.1,"dbMax":36.1,"timestamp":"2025-11-03 15:45:30"},"submitted":true},{"logData":{"dbAverage":43,"dbMin":35.3,"dbMax":56.6,"timestamp":"2025-11-03 15:45:35"},"submitted":true},{"logData":{"dbAverage":40.2,"dbMin":35.4,"dbMax":52.2,"timestamp":"2025-11-03 15:45:40"},"submitted":true},{"logData":{"dbAverage":40.4,"dbMin":35.7,"dbMax":48.9,"timestamp":"2025-11-03 15:45:45"},"submitted":true}]}#define LOG_HISTORY_SIZE 30 // number of historic log values to store
struct LogHistory
{
char logDataString[80];
bool submitted;
};
struct LogHistory logHistory[LOG_HISTORY_SIZE];
server.on("/logHistory", HTTP_GET, [](AsyncWebServerRequest *request)
{
AsyncResponseStream *response = request->beginResponseStream("application/json");
DynamicJsonDocument doc(4096);
char buff[80];
for (int i = 0; i < LOG_HISTORY_SIZE; i++)
{
PRINTS(i);
PRINTS(" ");
PRINTLN(logHistory[i].logDataString)
strlcpy(buff, logHistory[i].logDataString, 80); //if not sent via a buttfer, logDataString seems to get modified when deserialized
if (logHistory[i].logDataString[0] !='\0')
{
// Create a temporary document to parse the embedded JSON string
DynamicJsonDocument temp(768);
DeserializationError error = deserializeJson(temp, buff);
if (!error) {
// Copy parsed object into main document
doc["logHistory"][i]["logData"] = temp.as<JsonObject>();
doc["logHistory"][i]["submitted"] = logHistory[i].submitted;
} else {
PRINTS("JSON parse error at index ");
PRINTS(i);
PRINTS(": ");
PRINTLN(error.c_str());
}
}
}
//serializeJson(doc, Serial);
serializeJson(doc, *response);
request->send(response); });Before adding strlcpy(buff, logHistory[i].logDataString, 80); I was using deserializeJson(temp, logHistory[i].logDataString); but found that after deserialisation the value of logHistory[i].logDataString was null
The above code does not modify logHistory[i].logDataString but does not produce the desired output.
dbAverage key is missing, and all values of timestamp are the same
Actual output:
These 4 values of logHistory[i].logDataString
15:45:32:987 -> 0 {"dbAverage":36.1,"dbMin":36.1,"dbMax":36.1,"timestamp":"2025-11-03 15:45:14"}
15:45:32:993 -> 1 {"dbAverage":43,"dbMin":35.3,"dbMax":56.6,"timestamp":"2025-11-03 15:45:19"}
15:45:33:002 -> 2 {"dbAverage":40.2,"dbMin":35.4,"dbMax":52.2,"timestamp":"2025-11-03 15:45:25"}
15:45:33:007 -> 3 {"dbAverage":40.4,"dbMin":35.7,"dbMax":48.9,"timestamp":"2025-11-03 15:45:30"}
result in doc like this
{"logHistory":[{"logData":{"":36.1,"dbMin":36.1,"dbMax":36.1,"timestamp":"2025-11-03 15:45:30"},"submitted":true},{"logData":{"":43,"dbMin":35.3,"dbMax":56.6,"timestamp":"2025-11-03 15:45:30"},"submitted":true},{"logData":{"":40.2,"dbMin":35.4,"dbMax":52.2,"timestamp":"2025-11-03 15:45:30"},"submitted":true},{"logData":{"":40.4,"dbMin":35.7,"dbMax":48.9,"timestamp":"2025-11-03 15:45:30"},"submitted":true}]}