ESP8266 SPIFFS Dateisystem

ESP8266 - Everything SPIFFS or what? Or also: An own file system on our microcontroller

Hello and welcome to my new blog. In a previous post we already talked briefly about SPIFFS. Today we want to take a closer look at what SPIFFS actually is, what possibilities it offers us and how we can use it with our all-rounder microcontroller ESP 8266. First of all what does SPIFFS actually mean? SPIFFS stands for (S)erial (P)eripheral (I)nterface (F)lash (F)ile (S)ystem and it means that our ESP can hold a simple file system in the SPI program memory, which also contains our program code. In this file system files can be created, modified or deleted. These files can be used or changed by our program code during runtime, or they can have been created by us before. We will come back to how this is done later. The biggest advantage, however, is that this memory area, once created, is preserved during code updates! I.e. an updated program can continue to work with the data which were stored as file on this directly under reference to the file name.

Setup

To be able to work with a file system, it must first be initialized on our ESP with a defined size. This size depends on the used ESP module (maximum size) as well as on our configuration.

By default the ESP-01 modules have 512 KB flash up to 1 MB flash. The ESP-12, ESP-12E and ESP-12F modules (also known as NodeMcu module) have at least 4 MB Flash up to 8 MB Flash. From this total flash we now reserve a memory area for our file system using the Arduino IDE:

Before we upload a sketch, we select the size of our future file system. In the above example, I chose a 2 MB size for my ESP8266-12. Now we can use the following code to format our file system for first use. This step is mandatory when creating a new file system or reconfiguring the SPIFFS size:



#include <SPI.h>
#include <FS.h>           // Include the SPIFFS library

boolean InitalizeFileSystem() {
  bool initok = false;
  initok = SPIFFS.begin();
  if (!(initok)) // Format SPIFS, of not formatted. - Try 1
  {
    Serial.println("SPIFFS Dateisystem formatiert.");
    SPIFFS.format();
    initok = SPIFFS.begin();
  }
  if (!(initok)) // Format SPIFS. - Try 2
  {
    SPIFFS.format();
    initok = SPIFFS.begin();
  }
  if (initok) { Serial.println("SPIFFS ist  OK"); } else { Serial.println("SPIFFS ist nicht OK"); }
  return initok;
}

void setup() {
    SPI.begin();                      // Initialisiere SPI Kommunikation
    bool Result  = InitalizeFileSystem(); 

}

void loop() {
  

}


After compiling and uploading, our file system is ready for use. We can create, modify and delete files. The files are opened with so-called "modes", which specify the desired access mode. Thereby stands

- W - for write (writing or creating a new file)
- R - for read (reading a file)
- A - for append (adding data to the end of a file)


Use:

Within the file, a data pointer is used to indicate the current read/write position within a file. To show a practical example and at the same time use as many commands around file operations as possible, in the following example we create a file and write a new entry every 5 seconds. The next time the controller is reset, we delete the file and start over. The file content is output sequentially on the serial interface. Finally the current file size in bytes. +



#include <SPI.h>
#include <FS.h>           // Nutze die SPIFFS library

File myfile;                   // erstelle ein SPIFFS Handling Variable

boolean InitalizeFileSystem() 
{
  bool initok = false;
  initok = SPIFFS.begin();
  if (!(initok)) // Format SPIFS, of not formatted. - Try 1
  {
    Serial.println("Format SPIFFS");
    SPIFFS.format();
    initok = SPIFFS.begin();
  }
  if (!(initok)) // Format SPIFS, of not formatted. - Try 2
  {
    SPIFFS.format();
    initok = SPIFFS.begin();
  }
  if (initok) { Serial.println("SPIFFS ist OK"); } else { Serial.println("SPIFFS ist nicht OK"); }
  return initok;
}

void setup() 
{
  Serial.begin(9600);  
  SPI.begin();                     
  bool Result  = InitalizeFileSystem(); 
  if (!(SPIFFS.exists ("/usage_log.csv") ))  //Prüfe ob Datei usage_log.csvschon exisiert.
  {   
    myfile = SPIFFS.open("/usage_log.csv", "w");  //Öffne die Datei usage_log.csv im Root Verzeichnis zum schreiben (w – write)
    if (!myfile) 
      {
      Serial.println("Fehler beim schreiben der Datei");
      }
    Result = myfile.println("01.01.1980  12:00:00;Log cleared or deleted"); 
    Result = myfile.println("01.01.1980  12:00:01;First Entry, second Line");
    myfile.close();
  } else
  {
   SPIFFS.remove("/usage_log.csv");  //Lösche Datei  
   Serial.println("Datei usage_log.csv exisierte schon ! Sie wurde gelöscht.");
  }
}

void loop() 
{
  myfile = SPIFFS.open("/usage_log.csv", "r");  //Öffne die Datei usage_log.csv im Root Verzeichnis zum lesen (r - read)
  String content=myfile.readStringUntil('\n');
  Serial.println("Methode: readStringUntil:");
  while (myfile.position()<myfile.size())            // lese Dateiinhbalt Zeile für Zeile bis um Ende der Datei
        {
          content =myfile.readStringUntil('\n');
          Serial.println(content);
        } 
  int FileSize = myfile.size();
  myfile.close();
  Serial.print("Dateigroesse in Bytes:");           // gebe die aktuelle Dateigröße in Bytes aus
  Serial.println(FileSize);                                     // gebe die aktuelle Dateigröße in Bytes aus
  delay (5000);
  yield();               // interne ESP8266 Funktionen aufrufen
  myfile = SPIFFS.open("/usage_log.csv", "a");  // Öffne Datei um Daten anzuhängen ! (a - append)
  myfile.println("01.01.1980  12:00:xx;Zeile wurde hinzugefügt.");
  myfile.close();
}


We copy the code into our DIE and upload the sketch to our ESP.

The ESP starts adding entries to the internal file "usage_log.csv". We should get an output like this:

The most important commands are

SPIFFS.open("/filename", "r"); // Read a file

SPIFFS.open("/filename", "w"); // Write or create a new file

SPIFFS.open("/filename", "a"); // add data to the end of a file

For a complete reference of possible commands related to SPIFFS and file handling, see the following link:

http://arduino.esp8266.com/Arduino/versions/2.0.0/doc/filesystem.html#file-system-object-spiffs


Spiffs plugin

The ESP Arduino IDE Plugin is an Arduino IDE plugin that uploads files from the "data" subfolder of a sketch to an existing SPIFFS file system. This is done by deleting the existing SPIFFS files IM ESP, and replacing them with the files from the "data" folder. We do this by downloading the zip file from https://github.com/esp8266/arduino-esp8266fs-plugin and unzipping it to a location of our choice. The now unpacked "esp8266fs.jar" we put now under the following folder structure, which we created before: My Documents->Documents->Arduino->Tools->ESP8266FS->Tool. After a restart, new subitem will be created under Tools -> ESP8266 Sketch Data Upload":

Have fun experimenting & until the next post!

Esp-8266Grundlagen software

3 comments

georg

georg

hallo,
ich habe mit interesse Ihre erklärungen zum SPIFFS system gelesen, es wäre übertrieben wenn ich behaupten würde alles verstanden zu haben…
diesen code habe ich mir nach einem beispiel hier für meine bedürfnisse angepasst, er funktioniert auch:
-———————————
//board: ESP8266 Boards /node mcu 1.0

#include
#include // Nutze die SPIFFS library
int FileSize_frequency;

String sliderValue_frequency = “4”;
String sliderValue_frequency_alt;

File myfile_frequency; // erstelle eine SPIFFS Handling Variable

void setup()
{
Serial.begin(115200);
SPI.begin();

bool Result_frequency = InitalizeFileSystem(); if (!(SPIFFS.exists (“/frequency_config.csv”) )) //Prüfe ob Datei frequency_config.csv schon exisiert. { myfile_frequency = SPIFFS.open(“/frequency_config.csv”, “w”); //Öffne die Datei frequency_config.csv im Root Verzeichnis zum schreiben (w – write) if (!myfile_frequency) { Serial.println(“Fehler beim schreiben der Datei”); } Result_frequency = myfile_frequency.println(“sliderValue_frequency”); Result_frequency = myfile_frequency.println(sliderValue_frequency); myfile_frequency.close(); } else { SPIFFS.remove(“/frequency_config.csv”); //Lösche Datei Serial.println(“Datei frequency_config.csv war schon vorhanden, sie wurde gelöscht.”); }

}

void loop()
{
myfile_frequency = SPIFFS.open(“/frequency_config.csv”, “r”); //Öffne die Datei usage_log.csv im Root Verzeichnis zum lesen (r – read)

while (myfile_frequency.position() < myfile_frequency.size()) // lese Dateiinhalt Zeile für Zeile bis um Ende der Datei { String content = myfile_frequency.readStringUntil(‘\n’); Serial.println(content); } FileSize_frequency = myfile_frequency.size(); myfile_frequency.close(); Serial.print(“Dateigroesse in Bytes:”); // gebe die aktuelle Dateigröße in Bytes aus Serial.println(FileSize_frequency); // gebe die aktuelle Dateigröße in Bytes aus delay (5000); yield(); // interne ESP8266 Funktionen aufrufen if (sliderValue_frequency != sliderValue_frequency_alt) //die config_frequency soll nur einmal bei sich änderndem “sliderValue_frequency” geändert werden { myfile_frequency = SPIFFS.open(“/frequency_config.csv”, “a”); // Öffne Datei um Daten anzuhängen ! (a – append) //myfile_frequency.println(“sliderValue_frequency”); myfile_frequency.println(sliderValue_frequency); myfile_frequency.close(); sliderValue_frequency_alt = sliderValue_frequency; }

}boolean InitalizeFileSystem()
{
bool initok = false;
initok = SPIFFS.begin();
if (!(initok)) // Format SPIFS, if not formatted. – Try 1
{
Serial.println(“Format SPIFFS”);
SPIFFS.format();
initok = SPIFFS.begin();
}
if (!(initok)) // Format SPIFS, if not formatted. – Try 2
{
SPIFFS.format();
initok = SPIFFS.begin();
}
if (initok)
{
Serial.println(“SPIFFS ist OK”);
}
else
{
Serial.println(“SPIFFS ist nicht OK”);
}
return initok;
}
-———————————————
nun muss ich zwei variable in zwei dateien ins SPIFFS schreiben: frequency und power. Die beiden sketsche funktionieren einzeln sehr gut. Der versuch, die beiden sketche in eines zu integrieren scheitern mit einer Exception 9. Ich habe alle stellen, wo es mir notwendig schien entsprechend geändert und wie gesgt – einzeln funktionieren die sketche. Könnten Sie mir bitte einen tipp geben, woran das liegen könnte? Ich würde vermuten es liegt an diesen beiden zeilen:
-—————————-
bool Result_power = InitalizeFileSystem();
bool Result_frequency = InitalizeFileSystem();
-———————————-
ich kann ein system nicht 2x initialiseren, ohne dass was durcheinander gerät, denke ich…

vielen dank
gruss georg

Andre

Andre

Hallo,
in der neusten Arduino IDE funktiniert SPIFFS nicht mehr, es wird im Moment auch nicht weiterentwickelt und soll zuküntig aus dem ESP2866 core entfernt werden. LittleFS dient als Ersatz und ich konnte es mit der neusten Arduino IDE verwenden. Unter folgendem Link findet ihr weitere Infos.
https://arduino-esp8266.readthedocs.io/en/latest/filesystem.html

Viele Grüße,
André

Stumpfbrumme

Stumpfbrumme

Danke das war hilfreich!

Leave a comment

All comments are moderated before being published