Hey all I am having some issues with the SPIFFS for this Wemos D1 mini ESP8266 controller.
This is my Arduino sketch:
#include <FS.h>
#include <ArduinoJson.h>
struct RGBLA {
uint8_t R;
uint8_t G;
uint8_t B;
uint8_t L;
uint8_t A;
};
void setup() {
if (!SPIFFS.begin()) {
Serial.println("error while mounting filesystem!");
} else {
// put your setup code here, to run once:
RGBLA returnedVars = readSPIFFS();
Serial.begin(115200);
Serial.println();
Serial.println("Starting...");
Serial.println("readSPIFFS 1");
Serial.print("R: ");
Serial.println(returnedVars.R);
Serial.print("G: ");
Serial.println(returnedVars.G);
Serial.print("B: ");
Serial.println(returnedVars.B);
Serial.print("L: ");
Serial.println(returnedVars.L);
Serial.print("AmbientLight: ");
Serial.println(returnedVars.A);
Serial.println("==================================");
returnedVars = saveToSPIFFS(25,77, 107, 250, 155, false);
Serial.println("saveToSPIFFS #1");
Serial.print("R: ");
Serial.println(returnedVars.R);
Serial.print("G: ");
Serial.println(returnedVars.G);
Serial.print("B: ");
Serial.println(returnedVars.B);
Serial.print("L: ");
Serial.println(returnedVars.L);
Serial.print("AmbientLight: ");
Serial.println(returnedVars.A);
Serial.println("==================================");
returnedVars = saveToSPIFFS(205,17, 68, 50, 15, true);
Serial.println("saveToSPIFFS #2");
Serial.print("R: ");
Serial.println(returnedVars.R);
Serial.print("G: ");
Serial.println(returnedVars.G);
Serial.print("B: ");
Serial.println(returnedVars.B);
Serial.print("L: ");
Serial.println(returnedVars.L);
Serial.print("AmbientLight: ");
Serial.println(returnedVars.A);
returnedVars = readSPIFFS();
Serial.println("readSPIFFS 2");
Serial.print("R: ");
Serial.println(returnedVars.R);
Serial.print("G: ");
Serial.println(returnedVars.G);
Serial.print("B: ");
Serial.println(returnedVars.B);
Serial.print("L: ");
Serial.println(returnedVars.L);
Serial.print("AmbientLight: ");
Serial.println(returnedVars.A);
Serial.println();
Serial.println("END!");
}
}
void loop() {
// put your main code here, to run repeatedly:
}
RGBLA saveToSPIFFS(uint8_t R, uint8_t G, uint8_t B, uint8_t L, uint8_t A, bool saveA) {
File configFile = SPIFFS.open("/config.json", "w+");
if (configFile.size() > 3072) {
Serial.println("Config file size is too large.");
} else {
Serial.print("Writing json to Config file...");
StaticJsonBuffer<200> jsonBuffer;
JsonObject& json = jsonBuffer.createObject();
//Get the old value and save it
RGBLA returnedVars = readSPIFFS();
Serial.println("Old Values?");
Serial.print("R: ");
Serial.println(returnedVars.R);
Serial.print("G: ");
Serial.println(returnedVars.G);
Serial.print("B: ");
Serial.println(returnedVars.B);
Serial.print("L: ");
Serial.println(returnedVars.L);
Serial.print("AmbientLight: ");
Serial.println(returnedVars.A);
if (saveA) {
//Save Ambient Light data
json["R"] = returnedVars.R;
json["G"] = returnedVars.G;
json["B"] = returnedVars.B;
json["L"] = returnedVars.L;
json["A"] = A;
//Now save the new data
returnedVars.A = A;
} else {
//Save RGBL data
json["R"] = R;
json["G"] = G;
json["B"] = B;
json["L"] = L;
json["A"] = returnedVars.A;
//Now save the new data
returnedVars.R = R;
returnedVars.G = G;
returnedVars.B = B;
returnedVars.L = L;
}
json.printTo(configFile);
configFile.close();
//Read new saved values into struct
//returnedVars = readSPIFFS();
return returnedVars;
}
}
RGBLA readSPIFFS() {
bool exist = SPIFFS.exists("/config.json");
if (exist) {
Serial.println("YAY!");
} else {
Serial.println("Boo!");
}
File configFile = SPIFFS.open("/config.json", "r");
std::unique_ptr<char[]> buf(new char[configFile.size()]);
configFile.readBytes(buf.get(), configFile.size());
DynamicJsonBuffer jsonBuffer;
JsonObject& json = jsonBuffer.parseObject(buf.get());
RGBLA returnedVars;
String debugLogData;
json.printTo(debugLogData);
Serial.println("===============");
Serial.println(debugLogData);
Serial.println("===============");
returnedVars.R = json["R"];
returnedVars.G = json["G"];
returnedVars.B = json["B"];
returnedVars.L = json["L"];
returnedVars.A = json["A"];
configFile.close();
return returnedVars;
}
And this is the console output:
Starting...
readSPIFFS 1
R: 0
G: 0
B: 0
L: 0
AmbientLight: 25
==================================
Writing json to Config file...YAY!
===============
{}
===============
Old Values?
R: 0
G: 0
B: 0
L: 0
AmbientLight: 0
saveToSPIFFS #1
R: 25
G: 77
B: 107
L: 250
AmbientLight: 0
==================================
Writing json to Config file...YAY!
===============
{}
===============
Old Values?
R: 0
G: 0
B: 0
L: 0
AmbientLight: 0
saveToSPIFFS #2
R: 0
G: 0
B: 0
L: 0
AmbientLight: 25
YAY!
===============
{"R":0,"G":0,"B":0,"L":0,"A":25}
===============
readSPIFFS 2
R: 0
G: 0
B: 0
L: 0
AmbientLight: 25
END!
As you can see, the first old values has all 0's which is incorrect. AmbientLight should be 25 at that point since readSPIFFS 1 has 25. So this should read:
Old Values?
R: 0
G: 0
B: 0
L: 0
AmbientLight: 25
saveToSPIFFS #1 is sending values 25, 77, 107, 250, 155 and false which then outputs correctly as:
R: 25
G: 77
B: 107
L: 250
AmbientLight: 0
But this time AmbientLight should still be 25 since it was sent false. It should have taken the old value (25) and placed it into the newer save.
R: 25
G: 77
B: 107
L: 250
AmbientLight: 25
Moving on to saveToSPIFFS #2 the values again are incorrect. The AmbientLight however is correct here. Instead of this output:
R: 0
G: 0
B: 0
L: 0
AmbientLight: 25
it should be gathering the 4 previous old values:
R: 25
G: 77
B: 107
L: 250
AmbientLight: 25
The json after this should not be this:
{"R":0,"G":0,"B":0,"L":0,"A":25}
It should be this:
{"R":250,"G":77,"B":107,"L":250,"A":25}
And lastly, the output of readSPIFFS 2:
R: 0
G: 0
B: 0
L: 0
AmbientLight: 25
Is incorrect. It should output:
R: 25
G: 77
B: 107
L: 250
AmbientLight: 25
Then after a reset it should have that and not the below for readSPIFFS 1:
R: 0
G: 0
B: 0
L: 0
AmbientLight: 25
So, where am I messing up here?
UPDATE
struct RGBLA {
uint8_t R;
uint8_t G;
uint8_t B;
uint8_t L;
uint8_t A;
};
void setup() {
RGBLA returnedValues = readSPIFFS();
Serial.println("readSPIFFS 1");
Serial.print("R: ");
Serial.println(returnedVars.R);
Serial.print("G: ");
Serial.println(returnedVars.G);
Serial.print("B: ");
Serial.println(returnedVars.B);
Serial.print("L: ");
Serial.println(returnedVars.L);
Serial.print("AmbientLight: ");
Serial.println(returnedVars.A);
returnedValues = saveToSPIFFS(205, 17, 68, 50, 15, false);
Serial.println("saveToSPIFFS 1");
Serial.print("R: ");
Serial.println(returnedVars.R);
Serial.print("G: ");
Serial.println(returnedVars.G);
Serial.print("B: ");
Serial.println(returnedVars.B);
Serial.print("L: ");
Serial.println(returnedVars.L);
Serial.print("AmbientLight: ");
Serial.println(returnedVars.A);
}
RGBLA readSPIFFS() {
RGBLA returnedVars;
File configFile = SPIFFS.open("/config.json", "r");
if (configFile ) {
Serial.println("YAY!");
configFile.readBytes((byte*) &returnedValues, sizeof(RGBLA));
configFile.close();
} else {
Serial.println("Boo!");
}
return returnedValues;
}
RGBLA saveToSPIFFS() {
File configFile = SPIFFS.open("/config.json", "w+");
if (configFile.size() > 3072) {
Serial.println("Config file size is too large.");
} else {
Serial.print("Writing to Config file...");
//Get the old value and save it
RGBLA returnedVars = readSPIFFS();
Serial.println("Old Values:");
Serial.print("R: ");
Serial.println(returnedVars.R);
Serial.print("G: ");
Serial.println(returnedVars.G);
Serial.print("B: ");
Serial.println(returnedVars.B);
Serial.print("L: ");
Serial.println(returnedVars.L);
Serial.print("AmbientLight: ");
Serial.println(returnedVars.A);
if (saveA) {
//Save Ambient Light data
returnedVars.A = A;
} else {
//Save RGBL data
returnedVars.R = R;
returnedVars.G = G;
returnedVars.B = B;
returnedVars.L = L;
}
configFile.write((byte*) &returnedVars, sizeof(RGBLA));
configFile.close();
return returnedVars;
}
1 Answer 1
You can write a struct to file as binary data. This example is from my project.
global data:
struct Stats {
int heatingTime; // minutes
int consumedPower; // watts
};
Stats statsData;
snippet from setup():
File file = SPIFFS.open(STATS_FILENAME, "r");
if (file) {
file.readBytes((byte*) &statsData, sizeof(statsData));
file.close();
}
snippet from statsSave() function:
File file = SPIFFS.open(STATS_FILENAME, "w");
if (file) {
file.write((byte*) &statsData, sizeof(statsData));
file.close();
}
your updated readSPIFFS should be:
RGBLA readSPIFFS() {
RGBLA returnedVars;
File configFile = SPIFFS.open("/config.json", "r");
if (configFile ) {
Serial.println("YAY!");
configFile.readBytes((byte*) &returnedValues, sizeof(RGBLA));
configFile.close();
} else {
Serial.println("Boo!");
}
return returnedValues;
}
-
So I can still return RGBLA like RGBLA returnedVars = readSPIFFS();?StealthRT– StealthRT2018年10月01日 14:32:09 +00:00Commented Oct 1, 2018 at 14:32
-
Check out my updated OP.StealthRT– StealthRT2018年10月01日 14:41:17 +00:00Commented Oct 1, 2018 at 14:41
-
configFile.readBytes((byte*) &returnedValues, sizeof(returnedValues));
orconfigFile.readBytes((byte*) &returnedValues, sizeof(RGBLA));
2018年10月01日 14:43:48 +00:00Commented Oct 1, 2018 at 14:43 -
Alright corrected that in the update. Do I still need to use return returnedVars; or is it already populating the strut?StealthRT– StealthRT2018年10月01日 14:47:00 +00:00Commented Oct 1, 2018 at 14:47
-
file.write((byte*) rgbla, sizeof (RGBLA))
andfile.read((byte*) rgbla, sizeof (RGBLA))
would work