Dateien auf dem ESP8266 speichern und lesen: Das LittleFS Dateisystem

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

Beim Speichern von Daten auf einem ESP8266 begegnen wir häufig denselben Schlüsselbegriffen: EEPROM, SPIFFS, LittleFS 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 LittleFS Dateisystem auf dem ESP8266.

Mit dem LittleFS Dateisystem können wir auf den Flash-Speicher zugreifen als wäre es ein Dateisystem auf dem Computer. Wir können Dateien und Verzeichnisse 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 Little File System.

Zum Kapitel springen Allgemeines

Die Speicherkapazität des LittleFS hängt vom spezifischen ESP8266-Modell ab. Der D1 Mini bietet beispielsweise eine FS-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 LittleFS eines ESP8266 D1 Mini.

Die Größe des Dateisystems 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 Dateisystem, 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 LittleFS voll ausschöpfen falls nötig.

Zum Kapitel springen Programmcode

Um auf die Funktionen des LittleFS 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 Dateisystems 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 "LittleFS.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( LittleFS.begin() ){
    Serial.println("Dateisystem: initialisiert");
  }else{
    Serial.println("Dateisystem: Fehler beim initialisieren");
  }

  // Dateisystem formatieren
  //LittleFS.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 = LittleFS.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 = LittleFS.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( LittleFS.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 = LittleFS.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 = LittleFS.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 = LittleFS.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 Dateiupload vom PC auf den ESP8266

Es ist bereits möglich, Dateien auf dem ESP8266 zu lesen und zu schreiben. Doch wie verfährt man mit Dateien, die auf dem PC vorhanden sind und auf den ESP8266 übertragen werden sollen? Ein praktisches Beispiel ist das Speichern von Konfigurationsdateien direkt vom PC auf den ESP8266, die anschließend im Programm verwendet oder angepasst werden können. Ein weiterer Anwendungsfall könnte das Hochladen von HTML- und CSS-Dateien für einen Webserver sein. Dies ermöglicht es, die Dateien am PC zu bearbeiten und zu gestalten, bevor sie auf das Dateisystem des ESP geladen werden, von wo aus der Webserver sie dann ausliefern kann.

Produktempfehlungen und -suche in Verbindung mit dem Amazon Partnerprogramm:

¹ Angaben ohne Gewähr. Bei einem Kauf über den Link erhalten wir eine Provision.

Es gibt sowohl für die Arduino Legacy IDE Version 1.8.x als auch für die neue Arduino IDE 2.x ein Plugin, mit welchem man Dateien auf den ESP8266 hochladen kann. Solltest du noch die Version 1.8x verwenden, kannst du dir eine Anleitung dazu direkt im Git-Repository anschauen. Die Suche nach einem Plugin für die neue Arduino IDE 2.x war etwas schwieriger, aber ich bin fündig geworden. Mit dem Plugin arduino-littlefs-upload lassen sich auch mit der Arduino IDE 2.x Dateien hochladen. Es wird dabei mindestens die Arduino IDE Version 2.2.1 benötigt.

Zum Kapitel springen Plugin in der Arduino IDE installieren

Zuerst muss die aktuelleste Version des arduino-littlefs-upload Plugin heuntergeladen werden. Genauer gesagt brauchen wir eine .vsix Datei. Über den Link kann diese Datei direkt heruntergeladen werden. Zum aktuellen Zeitpunkt ist die Version 1.1.4 die aktuellste.

Die Datei muss nun in den Plugin-Order der Arduino IDE kopiert werden. Je nach System ist der Ordner an einem anderen Ort gespeichert:

  • Windows: C:\Users\${BENUTZERNAME}\.arduinoIDE\plugins\
  • MacOS: ~/.arduinoIDE/plugins/
  • Linux : ~/.arduinoIDE/plugins/

Wie im Repository angemerkt, muss der Ordner unter Umständen erstellt werden, falls er noch nicht existiert. Das war auch bei mir der Fall. In den Ordner wird dann die .vsix Datei kopiert. Anschließend sollte die Arduino IDE neugestartet werden um die Installation des Plugins abzuschließen.

Zum Kapitel springen Dateien hochladen

Mit geöffneter Arduino IDE kann man mit der Tastenkombination [Strg] + [Shift] + [P] auf Windows und Linux bzw. [⌘] + [Shift] + [P] auf MacOS das Command-Menü aufrufen. Dort sollte nun ein neuer Eintrag Upload LittleFS to Pico/ESP8266/ESP32 zu finden sein.

Arduino IDE 2 UploadFS Menü ><

Wenn man diesen Befehl direkt ausführt, wird in der Konsole der Arduino IDE folgende Meldung ausgegeben:

LittleFS Filesystem Uploader

ERROR: No data folder found

Grund dafür ist die Art und Weise, wie die Dateien auf den ESP8266 geladen werden. Man muss im Ordner des Sketches einen neuen Ordner namens data anlegen. Alle Dateien in diesem Ordner werden dann beim Ausführen des Befehls auf den ESP hochgeladen. Wenn der Ordner nicht vorhanden ist, können logischerweise keine Dateien hochgeladen werden.

Produktempfehlungen und -suche in Verbindung mit dem Amazon Partnerprogramm:

¹ Angaben ohne Gewähr. Bei einem Kauf über den Link erhalten wir eine Provision.

Arduino IDE UploadFS data Ordner ><

Sobald dieser Ordner erstellt wurde, kann der Upload des Ordners erneut ausgeführt werden.

Building LittleFS filesystem
[...]
Uploading LittleFS filesystem
[...]
Auto-detected Flash size: 4MB
Compressed 2072576 bytes to 2161...
Writing at 0x00200000... (100 %)
Wrote 2072576 bytes (2161 compressed) at 0x00200000 in 0.1 seconds (effective 269555.0 kbit/s)...
Hash of data verified.

Leaving...
Hard resetting via RTS pin...

Completed upload.

Arduino IDE 2 data Ordner Beispiel ><

12:01:29.530 -> ESP gestartet
12:01:29.530 -> Dateisystem: initialisiert
12:01:29.530 -> Die Datei meine.txt wurde geöffnet!
12:01:29.530 -> Diese Datei wurde von meinem PC auf den ESP8266 hochgeladen! Nice!

Zum Kapitel springen Vorteile des LittleFS

Ein wesentlicher Nutzen des LittleFS liegt in der Fähigkeit, Konfigurationen dauerhaft zu speichern und dabei die Organisationsstruktur durch Verzeichnisse zu nutzen. Entweder sind diese bereits auf dem ESP abgelegt oder werden später über ein Webinterface oder eine ähnliche Schnittstelle geändert. Diese Konfigurationen bleiben auch nach Neustarts erhalten.

Ein weiterer Pluspunkt von LittleFS ist seine Robustheit und Effizienz im Vergleich zu SPIFFS. Die verbesserte Handhabung der Flash-Abnutzung und die Unterstützung von Metadaten für Dateien erweitern die Funktionalität erheblich und machen es ideal für Anwendungen, die eine höhere Datenintegrität erfordern.

Zum Kapitel springen Nachteile des LittleFS

Während LittleFS viele Vorteile bietet, nutzt es wie SPIFFS den Flash-Speicher des ESP8266, der für umfangreichere Daten geeignet ist, jedoch eine begrenzte Anzahl von Schreib- und Lesezyklen hat. Das kann ein Nachteil sein, besonders 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. LittleFS bietet zwar eine verbesserte Effizienz im Vergleich zu SPIFFS, aber die grundsätzlichen Herausforderungen des Flash-Speichers bleiben bestehen.

Abschließend lässt sich sagen, dass das LittleFS 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.


cooper.bin Avatar

cooper.bin

Unterstütze mich und meine Arbeit, so kann ich weiter meiner Leidenschaft nachgehen. Ich lege viel Wert auf Qualität und stecke daher sehr viel Zeit in meine Beiträge. Wenn sie dir gefallen kannst du dir gerne auch meine anderen Artikel anschauen.

Mit PayPal unterstützen

Ich bin auf dem makesmart Discord-Server aktiv. Dort bin ich auch relativ gut erreichbar.

Teile diesen Beitrag



Diese Artikel könnten dich auch interessieren

ESP8266 Webserver mit echten HTML Dateien

Mit dem ESPAsyncWebserver kann man einen dateibasierten Webserver auf dem ESP8266 realisieren. Dieser kann HTML, CSS, Javascript und jede andere Art von Datei ausliefern.

cooper.bin am 28.04.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

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

ESP8266 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