Dateien auf dem ESP8266 speichern und lesen: Das SPIFFS Dateisystem

von cooper.bin
veröffentlicht am 24.02.2024 aktualisiert am 04.04.2024

Beim Speichern von Daten auf einem ESP8266 begegnen wir häufig denselben Schlüsselbegriffen: EEPROM, SPIFFS und RTC Memory. Jede dieser Methoden bietet eine Möglichkeit, Daten auf dem Gerät zu sichern. Eine Variante schauen wir uns heute genauer an: Das SPIFFS Dateisystem auf dem ESP8266.

Mit dem SPIFFS Dateisystem können wir auf den Flash-Speicher zugreifen als wäre es ein Dateisystem auf dem Computer. Wir können Dateien anlegen, Dateien lesen und auch Dateien schreiben. Das Beste an der ganzen Sache ist: die gespeicherten Dateien überleben sowohl einen Deep Sleep als auch einen Reboot. Die Daten die gespeichert werden, sind in einem nicht flüchtigen Speicher hinterlegt. Dem Serial Peripheral Interface Flash File System.

Zum Kapitel springen Allgemeines

Die Speicherkapazität des SPIFFS hängt vom spezifischen ESP8266-Modell ab. Der D1 Mini bietet beispielsweise eine SPIFFS-Kapazität von bis zu 3MB, während der ESP01-S maximal 512KB erreicht – was für zahlreiche Projekte aber auch völlig ausreichend ist.

In diesem Tutorial beschäftigen wir uns mit dem SPIFFS eines ESP8266 D1 Mini.

Die Größe des SPIFFS kann mithilfe der Arduino IDE eingestellt werden. Geht dazu über das Menü der IDE auf folgenden Punkt:

Arduino IDE
└── Werkzeuge
    └── Flash Size
        ├── 4M (FS:2MB OTA:~1019KB)
        ├── 4M (FS:3MB OTA:~512KB)
        ├── 4M (FS:1MB OTA:~1019KB)
        └── 4M (FS:none OTA:~1019KB)

Die Angaben zu den Flash Size-Optionen bieten Informationen zur Aufteilung des Speichers zwischen dem SPIFFS, den Platz für Over The Air Updates und der verbleibenden Kapazität für den Programmcode selbst.

Die Auswahl der richtigen Speicheraufteilung sollte immer auf basierend auf dem aktuellen Projekt getroffen werden. Werden keine Over The Air Updates benötigt, so kann man diese Kapazität beispielsweise so niedrig wie möglich halten. Hat man dazu noch einen sehr kleinen Programmcode, so könnte man die Größe des SPIFFs voll ausschöpfen falls nötig.

Zum Kapitel springen Programmcode

Um auf die Funktionen des SPIFFS zugreifen zu können, wird eine Bibliothek benötigt. Diese Bibliothek ist aber bereits standardmäßig installiert und kann sofort verwendet werden. Ich möchte an dieser Stelle direkt mit einem Beispiel zur Verwendung des SPIFFS starten. Das Beispiel öffnet eine Datei und liest deren Inhalt aus. Sollte die Datei nicht vorhanden sein, wird die Datei erstellt und mit einem Inhalt versehen:

// Code by cooper.bin@makesmart.net

// Filesystem-Libary einbinden
#include <FS.h>

// Name der Datei die wir speichern und auslesen möchten
const char* dateiname = "meine.txt";

void setup() {
  delay(1000);
  Serial.begin(115200);
  Serial.println();
  Serial.println("ESP gestartet");

  // Dateisystem initialisieren
  if( SPIFFS.begin() ){
    Serial.println("Dateisystem: initialisiert");
  }else{
    Serial.println("Dateisystem: Fehler beim initialisieren");
  }

  // Dateisystem formatieren
  //SPIFFS.format();

  // Öffnen der von uns definierten Datei nur mit Leserechten
  // r - Read - nur Leserechte
  // w - Write - Schreibrechte
  
  // Vorhandensein der Datei überprüfen und öffnen
  File file = SPIFFS.open(dateiname, "r");

  if ( !file ) {
    // Die Datei ist nicht vorhanden
    Serial.println("Die Datei " + String(dateiname) + " existiert nicht!");

    // Datei mit Schreibrechten öffnen, wird erstellt wenn nicht vorhanden
    file = SPIFFS.open(dateiname, "w");
    if ( file ) {
      Serial.println("Datei " + String(dateiname) + " wurde erstellt!");

      // Daten in die Datei schreiben
      file.print("Der Inhalt meiner Datei.");

      // Schließen der Datei
      file.close();
    }
  } else {

    // Die Datei ist vorhanden
    Serial.println("Die Datei " + String(dateiname) + " wurde geöffnet!");

    // Inhalt der Datei in eine String-Variable lesen
    String fileContent = "";
    while ( file.available() ) {
      fileContent += (char)file.read();
    }

    // Ausgabe des Dateiinhalts
    Serial.println(fileContent);

    // Schließen der Datei
    file.close();

  }
  

}

void loop() {

  delay(20000);

  // Hier wird einfach nur der Inhalt der Datei in Dauerschleife ausgegeben
  File file = SPIFFS.open(dateiname, "r");
  
  // Inhalt der Datei in eine String-Variable lesen
  String fileContent = "";
  while ( file.available() ) {
    fileContent += (char)file.read();
  }

  // Ausgabe des Dateiinhalts
  Serial.println(fileContent);

  // Schließen der Datei
  file.close();

      
}

Die Ausgabe im seriellen Monitor sieht wie folgt aus:

ESP gestartet
Dateisystem: initialisiert
Die Datei meine.txt existiert nicht!
Datei meine.txt wurde erstellt!
Der Inhalt meiner Datei.

Zum Kapitel springen Erläuterungen des Programmcodes

Zum Kapitel springen Dateisystem initialisieren

Das Dateisystem muss vor der Verwendung immer initialisiert werden. Ansonsten kann weder Lese- noch Schreibzugriff erfolgen. Diese Initialisierung erfolgt am besten direkt im Setup, so hat man danach an jeder Stelle im Programmcode zugriff auf das Dateisystem.

if( SPIFFS.begin() ){
  Serial.println("Dateisystem: initialisiert");
}else{
  Serial.println("Dateisystem: Fehler beim initialisieren");
}

Zum Kapitel springen Das File-Objekt

In dem Beispiel wird der Name der Datei in einer Variable gespeichert. Mithilfe dieser Variable erstellen wir ein neues File-Objekt mit dem Namen file. Über dieses Objekt greifen wir dann auf die einzelnen Funktionen der Bibliothek zu:

const char* dateiname = "meine.txt";

// Öffnen der von uns definierten Datei
// r - Read - nur Leserechte
// w - Write - Schreibrechte
  
File file = SPIFFS.open(dateiname, "r");

Zum Kapitel springen Datei anlegen

Beim ersten Start existiert die Datei noch nicht. Die Verfügbarkeit einer Datei lässt sich mit dem soeben erstellten file-Objekt überprüfen.

if ( !file ) {
    // Die Datei ist nicht vorhanden
    Serial.println("Die Datei " + String( dateiname ) + " existiert nicht!");

    // Datei mit Schreibrechten öffnen, wird erstellt wenn nicht vorhanden
    file = SPIFFS.open( dateiname, "w" );
    if ( file ) {
      Serial.println("Datei " + String( dateiname ) + " wurde erstellt!");

      // Daten in die Datei schreiben
      file.print( "Der Inhalt meiner Datei." );

      // Schließen der Datei
      file.close();
    }
}

In diesem Teil wird die Datei meine.txt angelegt, da sie zuvor noch nicht existiert hat. Gleichzeitig wird der Text Der Inhalt meiner Datei. in ihr abgespeichert.
Nach einem Neustart des ESPs wird der Codeabschnitt übergangen. Die Datei liegt dann bereits vor und die Bedingung der If-Abfrage wird dementsprechend nicht erfüllt.

Zum Kapitel springen Datei lesen

Für die weitere Verwendung des Dateiinhalts kann der nachfolgende Codeabschnitt sowohl im Setup als auch in der Loop-Funktion eingesetzt werden.

File file = SPIFFS.open(dateiname, "r");
  
// Inhalt der Datei in eine String-Variable lesen
String fileContent = "";
while ( file.available() ) {
  fileContent += (char)file.read();
}

// Ausgabe des Dateiinhalts
Serial.println(fileContent);

// Schließen der Datei
file.close();

Zum Kapitel springen Vorteile des SPIFFS

Ein wesentlicher Nutzen des SPIFFS liegt in der Fähigkeit, Konfigurationen dauerhaft zu speichern. Entweder sind diese bereits auf dem ESP abgelegt oder werden später über ein Webinterface oder eine ähnliche Schnittstellen geändert. Diese Konfigurationen bleiben auch nach Neustarts erhalten.

Ein weiterer Pluspunkt von SPIFFS ist seine Benutzerfreundlichkeit im Vergleich zu anderen Speicheroptionen. Die einfache Handhabung erleichtert die Entwicklung erheblich.

Zum Kapitel springen Nachteile des SPIFFS

Das SPIFFS nutzt den Flash-Speicher des ESP8266, der für umfangreichere Daten geeignet ist, jedoch eine begrenzte Anzahl von Schreib-/Lesezyklen hat. Das kann ein Nachteil sein besondern im Vergleich zum RTC-Speicher, der von dieser Einschränkung nicht betroffen ist.

Der Zugriff auf den Flash-Speicher kann energieintensiver sein als der Zugriff auf den EEPROM oder den RTC-Speicher, was in batteriebetriebenen Anwendungen ein Nachteil sein kann.

Das Spiffs bietet eine höhere Komplexität und mehr Overhead durch das Dateisystem, was im Vergleich zu den direkten Speicherzugriffen von EEPROM und RTC unnötig sein kann, besonders wenn nur einfache Konfigurationsdaten oder Zustände gespeichert werden müssen.

Abschließend lässt sich sagen, dass das SPIFFS trotz einiger Nachteile im Vergleich zu Alternativen wie EEPROM und RTC-Speicher eine wertvolle Ressource darstellt. Die Fähigkeit ein einfaches Dateisystem direkt auf dem Flash-Speicher zu implementieren, bietet eine flexible und benutzerfreundliche Möglichkeit zur Datenspeicherung und -verwaltung. Dies ist besonders nützlich für Anwendungen die eine Vielzahl von Konfigurationsdaten benötigen, welche über das einfache Key-Value-Speichern hinausgehen.

Das Thema arduino-ide gibt es auch auf dem makesmart Discord-Server!

mehr erfahren

Teile diesen Beitrag



Diese Artikel könnten dich auch interessieren

ESP8266 D1 Mini programmieren - Der Start mit der Arduino IDE

Erfahre, wie du den ESP8266 D1 Mini mit der Arduino IDE programmierst. Dank den kostenlosen Entwicklungswerkzeugen und der microUSB-Buchse ist das für jeden ein Kinderspiel.

cooper.bin am 10.02.2024

Der DS18B20 Temperatursensor am ESP8266 D1 Mini - Einfache Temperaturmessung

Lerne, wie du mit der Arduino IDE, dem ESP8266 und einem DS18B20 Temperatursensor einfache und schnelle Temperaturmessungen durchführen kannst.

cooper.bin am 05.03.2024

HC-SR04 und JSN-SR04T - Entfernungen messen mit Ultraschallsensoren am ESP8266

Lerne in diesem Tutorial, wie die Ultraschallsensoren HC-SR04 und JSN-SR04T mit ESP8266 D1 Mini für Distanzmessungen eingesetzt werden, die Grundlagen, Anwendungen und mehr.

cooper.bin am 09.03.2024

Der DHT22 am ESP8266 - Wie man die Temperatur und Luftfeuchtigkeit misst

In diesem Tutorial lernst du, wie du mit einem DHT22 und einem ESP8266 D1 Mini die Luftfeuchtigkeit und die Temperatur einfach messen kannst.

cooper.bin am 12.03.2024

ESP8266 - Ein einfacher Webserver mit mDNS

Während Webserver wie Apache2 oder NGNIX auf Rechnern laufen, kann man auch auf einem ESP8266 einen Webserver verwenden. In diesem Tutorial werden wir ein Grundgerüst implementieren.

cooper.bin am 13.02.2024