Closed
Description
Describe the issue
I'm trying to write a struct with config data to a json file. But the last few characters (always the closing curly brackets) are always missing when I read the file again. My work around is to serialize the data to a json String buffer and then writing this buffer to the file. Why does serializeJson(doc, file) not work correctly?
The complete process looks like this:
- While setup of ESP a json file with default_config data is read from SPIFFS.
- The config data is deserialized an stored in config data struct.
- The user can change config data via web interface.
- The browser sends data of changed config as json to ESP8266Server.
- Changed config data is deserialized and written into existing config data struct.
- Config data struct is serialized and written to a user_config.json file.
Troubleshooter report
ArduinoJson Troubleshooter's report
- The issue happens at run time
- The issue concerns serialization
- Output contains garbage
serializeJson()
produces garbage- Program doesn’t call
deserializeJson()
- Program calls
serializeJson(const JsonDocument&, ...)
- Program uses
DynamicJsonDocument
- Program doesn’t use
String
Environment
Here is the environment that I'm using':
- Visual Studio Code & PlatformIO
- wemos d1 mini
- bblanchon/ArduinoJson@^6.19.1
PLATFORM: Espressif 8266 (3.2.0) > Espressif ESP8266 ESP-12E
HARDWARE: ESP8266 80MHz, 80KB RAM, 4MB Flash
PACKAGES:
- framework-arduinoespressif8266 3.30002.0 (3.0.2)
- tool-esptool 1.413.0 (4.13)
- tool-esptoolpy 1.30000.201119 (3.0.0)
- tool-mklittlefs 1.203.210628 (2.3)
- tool-mkspiffs 1.200.0 (2.0)
- toolchain-xtensa 2.100300.210717 (10.3.0)
LDF: Library Dependency Finder -> https://bit.ly/configure-pio-ldf
LDF Modes: Finder ~ chain, Compatibility ~ soft
Reproduction
This is the json structure
{
"wifi": {
"hostname": "ESP8266",
"mdns_host": "esp8266",
"ssid": "XYZABCAND",
"key": "123456789012345678901234"
},
"ntp": {
"server": "de.pool.ntp.org",
"timezone": "CET-1CEST,M3.5.0,M10.5.0/3"
},
"assigments": {
"LED1": 16,
"LED2": 15,
"LED3": 14,
"LED4": 2,
"LED5": 0,
"PIR1": 12,
"PIR2": 13
},
"pwm_level": {
"off": 0,
"low": 25,
"high": 100
},
"lux": {
"threshold": 5,
"readInterval": 10
},
"dim": {
"motionTimeout": 60,
"pwmStepUp": 8,
"pwmStepDown": 2,
"stepInterval": 15
},
"schedule": {
"SO": {
"on": "08:00",
"off": "23:30"
},
"MO": {
"on": "06:30",
"off": "23:15"
},
"DI": {
"on": "06:30",
"off": "23:15"
},
"MI": {
"on": "06:30",
"off": "23:15"
},
"DO": {
"on": "06:30",
"off": "23:15"
},
"FR": {
"on": "06:30",
"off": "23:30"
},
"SA": {
"on": "07:30",
"off": "23:30"
}
}
}
This is the config struct that holds the config data im memory:
struct WifiCfg {
char hostname[32];
char mdns_host[32];
char ssid[64];
char key[64];
};
struct NtpCfg {
char server[32];
char timezone[32];
};
struct DailySwitching {
char on[6];
char off[6];
};
struct GpioAssignments {
uint8_t ledGpioMapping[5];
uint8_t pirGpioMapping[2];
};
struct Config {
struct GpioAssignments assignments;
struct WifiCfg wifiCfg;
struct NtpCfg ntpCfg;
struct DailySwitching schedule[7];
int lux_threshold;
int lux_readInterval;
int pwm_off;
int pwm_low;
int pwm_high;
int dim_motionTimeout;
int dim_pwmStepUp;
int dim_pwmStepDown;
int dim_stepInterval;
};
extern struct Config globalCfg;
and this my function to serialize the struct into a DynamicJsonDocument:
void serializeConfig(Config &cfg, bool noCredentials, JsonDocument &doc) {
PRINTSLN(">> serializeConfig >>");
// wifi
doc["wifi"]["hostname"] = cfg.wifiCfg.hostname;
doc["wifi"]["mdns_host"] = cfg.wifiCfg.mdns_host;
doc["wifi"]["ssid"] = cfg.wifiCfg.ssid;
doc["wifi"]["key"] = (noCredentials)? KEY_PLACEHOLDER : cfg.wifiCfg.key;
//ntp
doc["ntp"]["server"] = cfg.ntpCfg.server;
doc["ntp"]["timezone"] = cfg.ntpCfg.timezone;
// gpio assignments
doc["assigments"]["LED1"]=cfg.assignments.ledGpioMapping[0];
doc["assigments"]["LED2"]=cfg.assignments.ledGpioMapping[1];
doc["assigments"]["LED3"]=cfg.assignments.ledGpioMapping[2];
doc["assigments"]["LED4"]=cfg.assignments.ledGpioMapping[3];
doc["assigments"]["LED5"]=cfg.assignments.ledGpioMapping[4];
doc["assigments"]["PIR1"]=cfg.assignments.pirGpioMapping[0];
doc["assigments"]["PIR2"]=cfg.assignments.pirGpioMapping[1];
// pwmLevel
doc["pwm_level"]["off"] = cfg.pwm_off;
doc["pwm_level"]["low"] = cfg.pwm_low;
doc["pwm_level"]["high"] = cfg.pwm_high;
// lux
doc["lux"]["threshold"] = cfg.lux_threshold;
doc["lux"]["readInterval"] = cfg.lux_readInterval;
// dim
doc["dim"]["motionTimeout"] = cfg.dim_motionTimeout;
doc["dim"]["pwmStepUp"] = cfg.dim_pwmStepUp;
doc["dim"]["pwmStepDown"] = cfg.dim_pwmStepDown;
doc["dim"]["stepInterval"] = cfg.dim_stepInterval;
// schedule
for (int i = 0; i < 7; i++)
{
doc["schedule"][weekdays[i]]["on"] = cfg.schedule[i].on;
doc["schedule"][weekdays[i]]["off"] = cfg.schedule[i].off;
}
serializeJsonPretty(doc, Serial);
PRINTSLN("\n<< serializeConfig() <<");
}
Program output
Expected output:
{"wifi":{"hostname":"ESP8266","mdns_host":"esp8266","ssid":"XYZABCAND","key":"123456789012345678901234"},"ntp":{"server":"de.pool.ntp.org","timezone":"CET-1CEST,M3.5.0,M10.5.0/3"},"assigments":{"LED1":2,"LED2":16,"LED3":0,"LED4":14,"LED5":15,"PIR1":12,"PIR2":13},"pwm_level":{"off":0,"low":25,"high":100},"lux":{"threshold":5,"readInterval":10},"dim":{"motionTimeout":60,"pwmStepUp":8,"pwmStepDown":2,"stepInterval":15},"schedule":{"SO":{"on":"08:00","off":"23:30"},"MO":{"on":"06:30","off":"23:15"},"DI":{"on":"06:30","off":"23:15"},"MI":{"on":"06:30","off":"23:15"},"DO":{"on":"06:30","off":"23:15"},"FR":{"on":"06:30","off":"23:30"},"SA":{"on":"07:30","off":"23:30"}}}
Actual output:
{"wifi":{"hostname":"ESP8266","mdns_host":"esp8266","ssid":"XYZABCAND","key":"123456789012345678901234"},"ntp":{"server":"de.pool.ntp.org","timezone":"CET-1CEST,M3.5.0,M10.5.0/3"},"assigments":{"LED1":2,"LED2":16,"LED3":0,"LED4":14,"LED5":15,"PIR1":12,"PIR2":13},"pwm_level":{"off":0,"low":25,"high":100},"lux":{"threshold":5,"readInterval":10},"dim":{"motionTimeout":60,"pwmStepUp":8,"pwmStepDown":2,"stepInterval":15},"schedule":{"SO":{"on":"08:00","off":"23:30"},"MO":{"on":"06:30","off":"23:15"},"DI":{"on":"06:30","off":"23:15"},"MI":{"on":"06:30","off":"23:15"},"DO":{"on":"06:30","off":"23:15"},"FR":{"on":"06:30","off":"23:30"},"SA":{"on":"07:30","off":"23:30"���