I have edited the title of this since realizing where my issue really is. Simply put: My code runs fine when in RELEASE but fails in DEBUG:
CONFIGURATION: https://docs.platformio.org/page/boards/espressif8266/d1_mini.html
PLATFORM: Espressif 8266 2.3.3 > WeMos D1 R2 and mini
HARDWARE: ESP8266 80MHz, 80KB RAM, 4MB Flash
I noticed my sketch would fail to read a JSON file in SPIFFS correctly (using ArduinoJson) when build_type
is “debug,” but not when it is “release.” So, what’s going on internally with debug
vs release
? I have to admit - discovering this feels like a win, but it still means something weird is going on.
I’m just looking for a way forward here, something to tell the class developer. Any ideas?
For the sake of completeness, below is my test program:
main.cpp:
#include <FS.h>
#include "Config.h"
const char *filename = "/config.json";
Config config;
void printFile(const char *filename) {
File file = SPIFFS.open(filename, "r");
if (!file) {
Serial.println(F("Failed to open config file"));
return;
}
while (file.available()) {
Serial.print((char)file.read());
}
Serial.println();
}
bool loadFile(const char *filename, Config &config) {
File file = SPIFFS.open(filename, "r");
if (!SPIFFS.exists(filename) || !file) {
Serial.println(F("Failed to open config file"));
return false;
}
bool success = deserializeConfig(file, config);
if (!success) {
Serial.println(F("Failed to deserialize configuration, printing current file:"));
printFile(filename);
Serial.println(F("^^^^^^^^^^^^^^ config file"));
return false;
}
return true;
}
void saveFile(const char *filename, const Config &config) {
File file = SPIFFS.open(filename, "w");
if (!file) {
Serial.println(F("Failed to create config file"));
return;
}
bool success = serializeConfig(config, file);
if (!success) {
Serial.println(F("Failed to serialize configuration"));
}
}
void setup() {
Serial.begin(BAUD);
delay(1000);
if (!SPIFFS.begin()) {
Serial.println(F("Failed to mount SPIFFS"));
return;
}
bool loaded = loadFile(filename, config);
if (!loaded) {
Serial.println(F("Using default config"));
strcpy(config.accessPoint.ssid, "MySSID");
strcpy(config.accessPoint.passphrase, "s3cretp@$$word");
}
saveFile(filename, config);
printFile(filename);
if (!loaded)
Serial.println(F("Restart to load the config"));
else
Serial.println(F("Done!"));
}
void loop() {}
config.h:
#ifndef _CONFIG_H
#define _CONFIG_H
#include <ArduinoJson.h>
struct ApConfig
{
char ssid[32];
char passphrase[64];
void load(JsonObjectConst);
void save(JsonObject) const;
};
struct Config
{
ApConfig accessPoint;
void load(JsonObjectConst);
void save(JsonObject) const;
};
bool serializeConfig(const Config &config, Print &dst);
bool deserializeConfig(Stream &src, Config &config);
#endif // _CONFIG_H
config.cpp:
#include "config.h"
void ApConfig::save(JsonObject obj) const {
obj["ssid"] = ssid;
obj["passphrase"] = passphrase;
}
void ApConfig::load(JsonObjectConst obj) {
strlcpy(ssid, obj["ssid"] | "", sizeof(ssid));
strlcpy(passphrase, obj["passphrase"] | "", sizeof(passphrase));
}
void Config::load(JsonObjectConst obj) {
accessPoint.load(obj["access_point"]);
}
void Config::save(JsonObject obj) const {
accessPoint.save(obj.createNestedObject("access_point"));
}
bool serializeConfig(const Config &config, Print &dst) {
DynamicJsonDocument doc(512);
JsonObject root = doc.to<JsonObject>();
config.save(root);
return serializeJsonPretty(doc, dst) > 0;
}
bool deserializeConfig(Stream &src, Config &config) {
DynamicJsonDocument doc(1024);
DeserializationError err = deserializeJson(doc, src);
if (err)
return false;
config.load(doc.as<JsonObject>());
return true;
}
platformio.ini:
[platformio]
default_envs = d1_mini
[common_env_data]
upload_speed = 460800
monitor_speed = 74880
framework = arduino
build_flags =
-DBAUD=${common_env_data.monitor_speed}
lib_deps = ArduinoJson
build_type = release
[env:d1_mini]
upload_speed = ${common_env_data.upload_speed}
monitor_speed = ${common_env_data.monitor_speed}
framework = ${common_env_data.framework}
build_flags = ${common_env_data.build_flags}
lib_deps = ${common_env_data.lib_deps}
build_type = ${common_env_data.build_type}
platform = espressif8266
platform_packages =
framework-arduinoespressif8266 @ https://github.com/esp8266/Arduino.git
board = d1_mini