ESP8266 SPIFFS Dateisystem - AZ-Delivery

ESP8266 – Alles SPIFFS oder was? Oder auch: Ein eigenes Dateisystem auf unserem Microcontroller

Hallo und willkommen zu meinem neuen Blog. In einem vorhergehenden Beitrag haben wir schon einmal kurz über das SPIFFS gesprochen. Heute wollen wir uns einmal genauer anschauen, was SPIFFS eigentlich ist, welche Möglichkeiten es uns bietet und wie wir dieses mit unserem Allrounder Microcontroller ESP 8266 es nutzen können. Zunächst einmal was bedeutet eigentlich SPIFFS? SPIFFS steht für (S)erial (P)eripheral (I)nterface (F)lash (F)ile (S)ystem und gemeint ist dabei, dass unser ESP im SPI Programmspeicher, der auch unseren Programmcode enthält, ein einfaches Dateisystem halten kann. In diesem Dateisystem können Dateien erstellt, verändert oder gelöscht werden. Diese Dateien können von unserem Programmcode während der Laufzeit genutzt oder verändert werden, als auch bereits vorher durch uns angelegt worden sein. Wie dies gemacht wird, darauf kommen wir später zurück. Der größte Vorteil ist jedoch, dass dieser Speicherbereich, einmal erzeugt, bei Code Updates erhalten bleibt! D.h. kann ein upgedatetes Programm mit den Daten die als Datei hierauf abgelegt wurden direkt unter Bezug auf den Dateinamen weiterarbeiten.

Einrichtung

Um mit einem Dateisystem arbeiten zu können, muss es erst einmal auf unserem ESP mit einer definierten Größe initialisiert werden. Diese Größe richtet zum einen nach dem verwendeten ESP Modul (maximale Größe) als auch nach unserer Konfiguration.

Standardmäßig haben die ESP-01 Module 512 KB Flash bis hin zu 1 MB Flash. Die ESP-12, ESP-12E und ESP-12F Module (auch bekannt als NodeMcu Modul) haben mindestens 4 MB Flash bis zu 8 MB Flash. Von diesem gesamten Flash reservieren wir uns nun mithilfe der Arduino IDE einen Speicherbereich für unser Filesystem:

Bevor wir einen Sketch hochladen, wählen wir die Größe unseres zukünftigen Dateisystems aus. In den o.g. Beispiel habe ich bei meinem ESP8266-12 eine 2 MB Größe gewählt. Nun können wir mit folgendem Code unser Dateisystem für die erste Verwendung formatieren. Dieser Schritt ist bei Neuanlage oder bei Rekonfiguration der SPIFFS Größe zwingend erforderlich:

 

#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() {
  

}

 

Nach dem kompilieren und hochladen ist unser Dateisystem einsatzbereit. Wir können Dateien anlegen, verändern und löschen. Die Dateien werden mit sog. „Modes“ geöffnet, die die gewünschte Zugriffsart angeben. Dabei steht

• W – für write (Schreiben oder Neuanlage einer Datei)
• R – für read (Lesen einer Datei)
• A – für append (Hinzufügen von Daten an das Ende einer Datei)

Verwendung:

Innerhalb der Datei wird mit einem Datenpointer gearbeitet, der die aktuelle lese/Schreibposition innerhalb einer Datei angibt. Um ein praktisches Beispiel zu zeigen und gleichzeitig möglichst viele Befehle rund um Dateioperationen zu verwenden, legen wir in folgendem Beispiel eine Datei an und schreiben alle 5 Sekunden einen neuen Eintrag hinzu. Beim nächsten Reset des Controllers löschen wir die Datei und fangen wieder von vorne an. Der Dateiinhalt wird sequentiell auf der seriellen Schnittstelle ausgegeben. Zuletzt die aktuelle Dateigröße 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();
}

 

Wir kopieren den Code in unsere DIE und laden den Sketch auf unseren ESP hoch.
Der ESP fäng an, in die interne Datei „usage_log.csv“ Einträge hinzuzufügen. Wir sollten eine Ausgabe wie diese erhalten:

Die wichtigsten Befehle sind dabei

SPIFFS.open("/Dateiname", "r"); // Lesen einer Datei

SPIFFS.open("/Dateiname", "w"); // Schreiben oder Neuanlage einer Datei

SPIFFS.open("/Dateiname", "a"); // Hinzufügen von Daten an das Ende einer Datei

Eine vollständige Referenz der möglichen Befehle rund um SPIFFS und das Dateihandling findest du unter folgendem Link:

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

 

SPIFFS Plugin

Das ESP Arduino IDE Plugin ist ein Arduino-IDE Plugin, das Dateien des Unterordners "Data" eines Sketches in ein vorhandenes SPIFFS-Dateisystem hochlädt. Dazu werden die vorhandenen SPIFFS Dateien IM ESP gelöscht, und mit den Dateien aus dem Ordner “data“ ersetzt. Wir laden dazu die Zip Datei unter https://github.com/esp8266/arduino-esp8266fs-plugin herunter und entpacken diese an einem beliebigen Ort. Die nun ausgepackte „esp8266fs.jar“ legen wir nun unter folgender Ordnerstruktur ab, die wir vorher angelegt haben: Eigene Dateien->Dokumente->Arduino->Tools->ESP8266FS->Tool. Nach einem Neustart wird neuer Unterpunkt unter Werkzeuge -> ESP8266 Sketch Data Upload“ erzeugt:

Viel Spaß beim Experimentieren & bis zum nächsten Beitrag!

Esp-8266Grundlagen software

3 Kommentare

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!

Kommentar hinterlassen

Alle Kommentare werden von einem Moderator vor der Veröffentlichung überprüft

Empfohlene Blogbeiträge

  1. ESP32 jetzt über den Boardverwalter installieren - AZ-Delivery
  2. Internet-Radio mit dem ESP32 - UPDATE - AZ-Delivery
  3. Arduino IDE - Programmieren für Einsteiger - Teil 1 - AZ-Delivery
  4. ESP32 - das Multitalent - AZ-Delivery