Daten in den Flash Speicher des ESP ablegen

Hallo und willkommen zu unserem heutigen Beitrag.

 

Die ESP Module erfreuen sich sehr großer Beliebtheit. Wir haben in der Vergangenheit schon gezeigt wie einfach es ist sich mit dem WLAN zu verbinden, Webseiten anzuzeigen, und Relais zu schalten.

Eine sehr nützliche Funktion ist jedoch das ablegen von Daten in den Flash Speicher des ESPs. So ist es möglich Dateien hochzuladen, auf die wir später mit unserem Sketch zugreifen können. Oder Informationen zu speichern die auch nach einem Neustart noch verfügbar sind.

Dateien auf den ESP hochladen

Wir benötigen das Tool "ESP8266FS" - eine Erweiterung die sich in die Arduino IDE integriert. Es fügt im Menü "Werkzeuge" den Eintrag "ESP8266 Sketch Data Upload" hinzu. 

Als erstes laden wir uns das Tool von der ESP8266 GitHub Seite herunter:

https://github.com/esp8266/arduino-esp8266fs-plugin/releases/download/0.1.3/ESP8266FS-0.1.3.zip

Wir erstellen nun einen Ordner mit dem Namen "tools" im gleichen Ordner wie unsere Arduino-Sketche. Normalerweise befindet sich dieser unter "C:\Users\<benutzername>\Documents\Arduino\".

Entpacken Sie die heruntergeladene .zip Datei und kopieren Sie den Ordner ESP8266FS in das "tools" Verzeichnis. Am Ende haben wir dann "C:\Users\<benutzername>\Documents\Arduino\tools\ESP8266FS\tool\esp8266fs.jar".

Nun starten wir die Arduino IDE neu, und machen einen neuen Sketch. Ich nenne meinen in diesem Beispiel "ESP-Data-Test". Diesen Sketch müssen wir nun speichern.

Wir navigieren nun in den neu erstellten Ordner "C:\Users\<Benutzername>\Documents\Arduino\ESP-Data-Test" und legen dort den Ordner "data" an. Alle Dateien die hier abgelegt werden, werden in den Flash-Speicher des ESPs hochgeladen, sobald wir den Upload durchführen. 

Ich lege eine neue Textdatei mit dem Namen test.txt an, schreibe ein Paar Zeilen Text hinein, und speichere diese in den neuen "data" Ordner.

Ich verwende einen ESP8266-01S mit USB-Adapter, also stelle ich unter Werkzeuge folgende Optionen ein:

  • Board: "Generic ESP8266 Module"
  • Flash Size: "1M (64K SPIFFS)
  • Upload Speed: "115200" 
  • Port: "COMx" - ihren COM-Port auswählen

Falls Sie die Speichergröße ihres Moduls nicht kennen, gibt es am Ende des Artikels einen Tipp wie Sie diese bestimmen können. 

Als Test versuchen wir nun den leeren Sketch (nur void setup() und void loop()) auf den ESP zu laden. Für meinen ESP muss ich dafür sicherstellen dass der Programmiermodus aktiviert ist.

Wenn das alles funktioniert hat, können wir versuchen den Inhalt des "data" Ordners auf den ESP zu laden. Dafür gehen wir auf "Werkzeuge" -> "ESP8266 Sketch Data Upload".

In der IDE erscheint "SPIFFS Uploading Image..." ... und nach kurzer Zeit erscheint:  "SPIFFS Image Uploaded":

 

Falls an dieser Stelle ein Fehler kommt ("SPIFFS Upload failed!"), dann vermutlich weil sich der ESP nicht mehr im Programmiermodus befindet. Einfach die USB Verbindung trennen und wieder verbinden, und dabei sicherstellen das der Programmiermodus aktiviert wird.

SPIFFS im Sketch verwenden 

Um SPIFFS im Sketch nutzen zu können, binden wir die Bibliothek FS.h ein:

#include "FS.h"

 

Nun stehen uns folgende Befehle zur Verfügung:

Filesystem Objekt (SPIFFS)

SPIFFS.begin()

Mountet das SPIFFS Filesystem. Muss immer vor allen anderen Befehlen ausgeführt werden. Gibt "true" zurück, falls das Mounten funktioniert hat, ansonsten "false".

SPIFFS.format()

Formatiert (löscht) das Filesystem. Gibt "true" zurück wenn die Formatierung erfolgreich war.

SPIFFS.open(path, mode)

Öffnet eine Datei. Als "path" geben sie den Dateinamen inklusive dem absoluten Pfad an (z.B. "/Ordnername/test.txt"). "mode"  gibt die Art des Zugriffs an. Kann folgende Optionen enthalten: "r", "w", "a", "r+", "w+", "a+".

  • "r" Öffnet die Datei zum Lesen. Die Datei muss existieren
  • "w" Erstellt eine neue Datei ohne Inhalt. Falls eine Datei mit gleichem Namen existiert wird deren Inhalt gelöscht, und die Datei wird als neue leere Datei gesehen.
  • "a" Hängt Daten an die Datei an ("append"). Die Daten werden am Ende der Datei angehängt. Falls die Datei nicht existiert, wird eine neue erstellt.
  • "r+" Öffnet eine Datei zum lesen und schreiben. Die Datei muss existieren.
  • "w+" Erstellt eine leere Datei zum lesen und schreiben.
  • "a+" Öffnet eine Datei zum lesen, sowie zum anhängen.
Es wird ein Datei-Objekt ("file" object) zurückgegeben. Um zu überprüfen ob eine Datei erfolgreich geöffnet werden konnte, verwendet man am besten einen boolschen Operator:
File f = SPIFFS.open("/test.txt", "w");
if (!f) {
Serial.println("file open failed");
}

SPIFFS.exists(path)

Gibt "true" zurück falls der Pfad existiert, ansonsten "false".

SPIFFS.openDir(path)

Öffnet das angegebene Verzeichnis. Gibt ein "dir" Objekt zurück.

SPIFFS.remove(path)

Löscht den angegebenen Pfad. Gibt ein "true" zurück falls die Löschung erfolgreich war.

SPIFFS.rename(pathFrom, pathTo)

Nennt eine Datei um von "pathFrom" nach "PathTo". Der Pfad muss absolut sein. Gibt ein "true" zurück falls das Umbenennen erfolgreich war.

 

Filesystem Info Struktur

FSInfo fs_info;
SPIFFS.info(fs_info);

Füllt die FSInfo Struktur mit Informationen zum Filesystem. Gibt ein "true" zurück bei Erfolg, ansonsten ein "false".

Struktur:

struct FSInfo {
  size_t totalBytes;
  size_t usedBytes;
  size_t blockSize;
  size_t pageSize;
  size_t maxOpenFiles;
  size_t maxPathLength;
};

 

Verzeichnis Objekt (Dir)

Das "Dir" Objekt ermöglicht es uns Dateien innerhalb eines Verzeichnisses anzusprechen mittels den Methoden "next()", "filename()" und "openFile(mode)".

Dir dir = SPIFFS.openDir("/data");
while (dir.next()) {
Serial.print(dir.fileName());
File f = dir.openFile("r");
Serial.println(f.size());
}

dir.next() ist "true" solange es Dateien in dem Verzeichnis findet. Es muss vor "fileName" oder "openFile" aufgerufen werden.

"openFile" nimmt das "mode" Argument, welches identisch ist wie bei SPIFFS.open.

 

Datei Objekt (file) 

SPIFFS.open und dir.openFile geben ein "file" Objekt zurück. Dieses ist ein Streamobjekt und unterstützt alle Funktionen wie "readbytes", "findUntil", "parseInt", "println" und alle anderen Stream Methoden.

Es gibt aber auch einige die für das Datei Objekt (file) spezifisch sind.

file.seek(offset, mode)

Funktioniert wie die fseek Funktion in C. Die aktuelle Position verschiebt sich je nach dem Wert von "mode" wie folgt:

    • SeekSet -> Position wird auf "offset" Bytes vom Anfang gesetzt
    • SeekCur -> aktuelle Position wird um "offset" Bytes verschoben
    • SeekEnd -> Position wird auf "offset" Bytes vom Ende der Datei desetzt
 Gibt "true" zurück wenn die Position gesetzt werden konnte.

 

file.position()

Gibt Aktuelle Position innerhalb der Datei als Wert in Bytes wieder

file.size()

Gibt die Dateigröße in Bytes wieder.

file.name();

Gibt den Dateinamen als "const char*" wieder. Kann mittels "String name = file.name();" in einen String gespeichert werden.

file.close()

Schließt die Datei.

 

Praxisbeispiel

Nun schreiben wir einen kleinen Sketch um das ganze zu testen: wir wollen unsere Textdatei "test.txt" welche wir am Anfang erstellt und mit ein Paar Zeilen Text befüllt haben auf den seriellen Monitor ausgeben.

 

 

#include "FS.h" // Hier binden wir die benötigte Bibliothek ein

void setup() {
  Serial.begin(9600); // Serielle Ausgabe aktivieren
  delay(1000); // Kurze Pause, damit wir Zeit haben den Seriellen Monitor zu öffnen.
  
  SPIFFS.begin(); // Filesystem mounten
  File f = SPIFFS.open( "/test.txt", "r"); // Datei zum lesen öffnen
  if (!f) {
    Serial.println("file open failed");
  }
  String data = f.readString(); // Inhalt der Textdatei wird gelesen...
  Serial.println("Inhalt der geöffneten Datei:");
  Serial.println(data); // ... und wieder ausgegeben
  f.close(); // Wir schließen die Datei
}
void loop() {
}

 

 Nach dem hochladen erscheint dann die Ausgabe auf dem seriellen Monitor:

 

Bonus Tipp: Wie groß ist der Flash-Speicher meines ESP 8266?

Je nachdem welches ESP8266-Modul Sie verwenden, kann sich die Größe des flash Speichers  unterscheiden. Zwar kann man anhand der Beschriftung auf dem Chip nach dem Datenblatt suchen, aber um ganz sicher zu gehen gibt es einen kleinen Sketch der die Größe, Geschwindigkeit und den Modus Ihres Moduls überprüft. Den Sketch gibt es auf https://github.com/esp8266/Arduino/tree/master/libraries/esp8266/examples/CheckFlashConfig

Diesen Sketch einfach hochladen, und den Seriellen Monitor auf 115200 Baud stellen, schon wird uns die Größe des Chips angezeigt.

 

 

 

Ich hoffe unser heutiger Blog-Beitrag hat Ihnen gefallen, und ihre Kreativität angeregt. Ab sofort können Sie die SPIFFS Funktion ihres ESP nutzen um z.B. HTML Textbausteine abzulegen, Sensordaten dauerhaft zu speichern, und vieles mehr.

Wir freuen uns sehr über Lob, Kritik und Anregungen zu unserem Blog.

Ihr Markus Neumann

Letzter Artikel USB-Adapter erweitern mit Flash Jumper und Reset Taster

Hinterlasse einen Kommentar

Kommentare müssen vor der Veröffentlichung überprüft werden

Erforderliche Angabe