Low-Level: EEPROM
Up until now and currently your best bet for data persistence in the stable release you could use the EEPROM interface to write and read your data so it would be available between reboots of the device. This persistence interface is pretty low-level: you have to define the range of the memory you want to use and then it’s all on you how to organize this stream of bytes. Of course, you could write yourself some code to write and read the data in a more accessible way but this is cumbersome and error-prone. Especially if the stored data has different formats, lets say one part is a JSON object and the next is HTML you have to create a table of content (TOC) and keep track of the sizes and start points of these blocks.
New: SPIFFS
But why re-invent the wheel? This organization of all the single blocks in a TOC is generally called a file system and the team around the ESP8266/Arduino environment is currently integrating the SPIFFS into their development branch. SPIFFS stands for SPI flash file system and is especially targeted for embedded devices such as the ESP8266. According to the Github page of the SPIFFS project the file system has the following features:
- Specifically designed for low ram usage
- Uses statically sized ram buffers, independent of number of files
- Posix-like api: open, close, read, write, seek, stat, etc
- Implements static wear leveling
- Built in file system consistency checks
There are also a few limitations but hey, what do you expect from anything especially targeted for small and embedded devices?
Hands-on
#include "FS.h" void setup() { Serial.begin(115200); // always use this to "mount" the filesystem bool result = SPIFFS.begin(); Serial.println("SPIFFS opened: " + result); // this opens the file "f.txt" in read-mode File f = SPIFFS.open("/f.txt", "r"); if (!f) { Serial.println("File doesn't exist yet. Creating it"); // open the file in write mode File f = SPIFFS.open("/f.txt", "w"); if (!f) { Serial.println("file creation failed"); } // now write two lines in key/value style with end-of-line characters f.println("ssid=abc"); f.println("password=123455secret"); } else { // we could open the file while(f.available()) { //Lets read line by line from the file String line = f.readStringUntil('n'); Serial.println(line); } } file.close(); } void loop() { // nothing to do for now, this is just a simple test }
You can also find the example here:
https://github.com/squix78/esp8266-projects/tree/master/arduino-ide/filesystem-example
Explanation
Summary
While other ESP8266 firmwares (NodeMCU, smart.js and frankenstein) already come with a filesystem it is great to see that the Arduino/ESP8266 environment soon will be blessed with this important feature. It is easy to apply and a huge improvement over the very low-level EEPROM persistence interface. Directories let you structure your files and you can freely create new files, delete or rename them.
Compared to the NodeMCU firmware you have worry how you can get the files onto the device. If you want to run a web server you cannot just transfer the html, css and js files from your PC to the ESP8266. There is no interface for such an operation yet. But you could store them on another webserver and store/update them in flash when the device connects to WiFi.
Thank you for this post! I tried it and it actually works 🙂
RSS added to feedly!
7 Amazing Recent Posts Widgets for Blogger visit: http://www.mytrickspedia.blogspot.com
Thanks for the info!
I suggest replacing file.close(); with f.close(); in order for compilation to succeed 🙂
Thanks for the information and sample code. I tested it out on the latest version of Arduino and it failed, could not find the includes for "FS.h". I looked in the libraries and they were not there, so I manually loaded them and it failed on the "file.close();" the error is "file" was not declared in this scope. So i figured for testing I did not need to close the file. The code works! If you have any ideas on how to fix the file.close()?
Well… look through code my friend. There's no "file". In 11. line there is definition File f. That means you have to use f.close().
Yes, line 33 says file.close() and it should be f.close()
Nice guide, thanks.
Thanks alot!
Amazing work…
Do you know of a way to list all files stored in flash?
Thank you for your simple example.
Instead of “/f.txt”, we can also put “f.txt” for simplicity.
/ is not required before file name. It is considered as a part of filename itself.