Open hasenradball opened 3 days ago
Hi Benoit,
watched your video, great stuff.
I want to buy the paperback version! Do you have one for me?
What is your suggestion working on the ESP-01? Stay on 6.19.4 or switch to 7?
Hi @hasenradball,
I'm overwhelmed these days, so I don't know when I'll be able to work on the paperback version.
For every 32-bit microcontroller, including ESP-01, I strongly recommend switching to ArduinoJson 7.
Best regards, Benoit
Maybee one final Question.
With v6 I used this code.
2 Functions for Websocket and Server.
There I use json_str
as a buffer is there actually a better choice to store the json?
Or is it actually needed?
void sendMessageJson(int id, bool state_relais, bool state_tor) {
char json_str[300];
// Reserve DynamicJsonDocument doc(500); --> Heap
// Reserve StaticJsonDocument<500> doc; --> Stack
StaticJsonDocument<280> doc;
// Uhrzeit
char timestrbuffer[6];
uhr.get_timeformatted(timestrbuffer, 6, "%R");
// Betriebszeit
char durationstrbuffer[29];
snprintf(durationstrbuffer, 29, "%02lld:%02u:%02u", esp_duration.get_hh(), esp_duration.get_mm(), esp_duration.get_ss());
doc["Version"] = webIf.version;
doc["Relais"] = state_relais;
doc["Tor_offen"] = state_tor;
doc["Temperature"] = sensor_BME280.Data.Messwert2;
doc["Humidity"] = sensor_BME280.Data.Messwert3;
doc["Pressure"] = sensor_BME280.Data.Messwert4;
doc["Time"] = timestrbuffer;
doc["Duration"] = durationstrbuffer;
serializeJson(doc, json_str);
// serializeJson(doc, Serial);
// DBG__PRINT("\n\tjson_str length:", "");
// DBG__PRINT(" ", String(measureJson(doc)));
// DBG__PRINT("\tdoc - Memory usage:", "");
// DBG__PRINT(" ", String(doc.memoryUsage()));
if (id >= 0) {
webSocket.sendTXT(id, json_str, measureJson(doc));
}
else {
webSocket.broadcastTXT(json_str, measureJson(doc));
}
}
void sendMessageJson_WifiConfig(bool wlan_user_req) {
// --> Funktion zum Senden der Daten an die Webside
char json_str[300];
//const size_t capacity = JSON_OBJECT_SIZE(12);
// Reserve DynamicJsonDocument doc(500); --> Heap
// Reserve StaticJsonDocument<500> doc; --> Stack
StaticJsonDocument<280> doc;
doc["Version"] = webIf.version;
doc["WLAN_USER_INPUT_Requested"] = wlan_user_req;
doc["MAC"] = WiFi.macAddress();
doc["Hostname"] = wlan.getHostname();
serializeJson(doc, json_str);
// serializeJson(doc, Serial);
// DBG__PRINT("json_str length: ", measureJson(doc));
// DBG__PRINT(" doc - Memory usage: ", doc.memoryUsage());
// wichtig! damit Daten nicht aus dem Browser cache kommen
server.sendHeader(F("Cache-Control"), "no-cache");
server.send(200, "application/json", json_str);
}
I replace the above code by this.
It would be nice if you can give a final confirm ;-)
void sendMessageJson(int id, bool state_relais, bool state_tor) {
char json_str[JSON_MAX_OUTPUT_SIZE];
// v6.x
// Reserve DynamicJsonDocument doc(500); --> Heap
// Reserve StaticJsonDocument<500> doc; --> Stack
// v7.x
JsonDocument doc;
// Uhrzeit
char timestrbuffer[6];
uhr.get_timeformatted(timestrbuffer, 6, "%R");
// Betriebszeit
char durationstrbuffer[29];
snprintf(durationstrbuffer, 29, "%02lld:%02u:%02u", esp_duration.get_hh(), esp_duration.get_mm(), esp_duration.get_ss());
doc["Version"] = webIf.version;
doc["Relais"] = state_relais;
doc["Tor_offen"] = state_tor;
doc["Temperature"] = static_cast<float>(ESP.getFreeHeap());
//doc["Temperature"] = sensor_BME280.Data.Messwert2;
doc["Humidity"] = sensor_BME280.Data.Messwert3;
doc["Pressure"] = sensor_BME280.Data.Messwert4;
doc["Time"] = timestrbuffer;
doc["Duration"] = durationstrbuffer;
doc.shrinkToFit();
serializeJson(doc, json_str);
// serializeJson(doc, Serial);
// DBG__PRINT("\n\tjson_str length:", "");
// DBG__PRINT(" ", String(measureJson(doc)));
// DBG__PRINT("\tdoc - Memory usage:", "");
// DBG__PRINT(" ", String(doc.memoryUsage()));
if (id >= 0) {
webSocket.sendTXT(id, json_str, measureJson(doc));
}
else {
webSocket.broadcastTXT(json_str, measureJson(doc));
}
}
My review:
Small stack buffers like timestrbuffer
and durationstrbuffer
are appropriate; however, for larger buffers (let's say >128B), you should allocate on the heap to prevent stack overflows (you can also use String
for simplicity).
serializeJson()
returns the length of the JSON document, so you can use the return value in place of measureJson()
, which will significantly improve speed and code size.
Calling shrinkToFit()
is unnecessary since you discard the JsonDocument
right after the serialization.
Dear Benoit,
thank you so much for the review and the hints.
For the return of serialize function I was unsure, looked up in the API but was not explizitly mentioned as length of JsonDocument.
Indeed in the past I prevented as much as possible to use the heap. I took nearly everything on stack. Is it good putting things on heap which don‘ t last long? An how to see a StackOverflow comming?
In the example below would it the also better to use std::Strings for the char arrays like timezone, password, etc. And directly do it with std:String?
StaticJsonDocument<JSON_DOC_SIZE> doc;
// Deserialize the JSON document
DeserializationError error = deserializeJson(doc, file);
if (error) {
DBG__PRINT(F(">>> ERROR: deserializeJson() of >config.txt< failed:"), "");
DBG__PRINT(error.f_str(), "!\n");
return false;
}
else {
// Ausgabe => Serial
//serializeJson(doc, Serial);
DBG__PRINT("\n");
}
// Copy values from the JsonDocument to the Config
strlcpy(wlan_host, doc["wifi"]["Hostname"], sizeof(wlan_host));
strlcpy(wlan_ssid, doc["wifi"]["SSID"], sizeof(wlan_ssid));
strlcpy(wlan_passwd, doc["wifi"]["Password"], sizeof(wlan_passwd));
strlcpy(time_zone, doc["time"]["TimeZone"], sizeof(time_zone));
strlcpy(time_server1, doc["time"]["TimeServer1"], sizeof(time_server1));
strlcpy(time_server2, doc["time"]["TimeServer2"], sizeof(time_server2));
strlcpy(time_server3, doc["time"]["TimeServer3"], sizeof(time_server3));
strlcpy(time_zone, doc["time"]["TimeZone"], sizeof(time_zone));
licht_schwelle = doc["licht"]["Schwellwert"];
licht_min = doc["licht"]["Min"];
licht_max = doc["licht"]["Max"];
farbe_r = doc["farbe"]["RGB-R"];
farbe_g = doc["farbe"]["RGB-G"];
farbe_b = doc["farbe"]["RGB-B"];
sprach_einstellung = doc["sprache"]["Wert"];
tim_wlan.active = doc["timerWLAN"]["active"];
strlcpy(tim_wlan.on_time, doc["timerWLAN"]["On"], sizeof(tim_wlan.on_time));
setTimer_struct(tim_wlan.on_time, &tim_wlan.on_time_struct);
strlcpy(tim_wlan.off_time, doc["timerWLAN"]["Off"], sizeof(tim_wlan.off_time));
setTimer_struct(tim_wlan.off_time, &tim_wlan.off_time_struct);
return true;
}
Can you please put me on the list for the book?
Hi,
having changed the lib from actual v6.19 to v7.latest and see some points to update. is there a general example how to setup code for Arduino JSON for v7. to be able to do a review with v7 in mind?