ESP8266 SPIFFS Dateisystem

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!

Einen Kommentar hinterlassen

Alle Kommentare werden vor der Veröffentlichung moderiert