-->
Page 1 of 1

ESP8266 SPIFFS not saving correctly?

PostPosted: Sat Sep 29, 2018 9:47 pm
by stealthrt
Hey all I am having some issues with the SPIFFS for this Wemos D1 mini ESP8266 controller.

This is my Arduino sketch:

Code: Select all#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:

Code: Select allStarting...
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: 15
YAY!
===============
{"R":0,"G":0,"B":0,"L":0,"A":15}
===============
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:

Code: Select allOld 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:

Code: Select allR: 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.

Code: Select allR: 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:

Code: Select allR: 0
G: 0
B: 0
L: 0
AmbientLight: 25

it should be gathering the 4 previous old values:

Code: Select allR: 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:

Code: Select allR: 0
G: 0
B: 0
L: 0
AmbientLight: 25

Is incorrect. It should output:

Code: Select allR: 25
G: 77
B: 107
L: 250
AmbientLight: 25

Then after a reset it should have that and not the below for readSPIFFS 1:

Code: Select allR: 0
G: 0
B: 0
L: 0
AmbientLight: 25

So, where am I messing up here?

Re: ESP8266 SPIFFS not saving correctly?

PostPosted: Mon Oct 08, 2018 8:00 am
by grhhm
Try to add delay of few ms between writing to the file and closing it. Maybe MCU can't complete write operation in time.