DIY Projects

ESP32. Get started with the SPIFFS.h library to read, write, modify files

spiffs esp32 arduino library

SPIFFS (Serial Peripheral Interface Flash File System) is a lightweight file system suitable (among others) for microcontrollers with SPI flash memory such as the ESP32 and ESP8266. The Arduino SPIFFS.h library allows access to flash memory as if it were a normal file system like that of a computer (and much simpler of course). We can read, write and add data to a file and perform some simple operations (format, rename, retrieve information, etc.)

Warning, the flash memory is limited to 10,000 write cycles. Optimize your code to reduce write operations to extend the life of your ESP32 projects.

Introducing the SPIFFS (SPI Flash File System)

SPIFFS (for Serial Peripheral Interface Flash File System) is a file system developed by Peter Andersson (project page on GitHub) that can run on any NOR flash or SPI flash.

The library developed for ESP8266 modules includes most of the functionalities with some additional limitations due to the limitations of microcontrollers:

Other useful limitations to know:

Discovery of the SPIFFS.h library, API and available methods

The SPIFFS.h library is a port of the official library for Arduino which is installed at the same time as the ESP32 SDK.

The proposed methods are almost identical to the FS.h library for ESP8266.

The following methods are not available

FS.h library API Equivalent Method
SPIFFS.openDir(path) none
SPIFFS.info(fs_info) SPIFFS.totalBytes()

Returns the total number of bytes used by the SPIFFS file system.

SPIFFS.usedBytes()

Returns the space used by the specified file in bytes

To access the file system, all you have to do is declare it at the start of the sketch

#include "SPIFFS.h"

How to format a file name (path)?

SPIFFS does not manage the tree.

However, we can create a pseudo tree using the “/” character in the file name without exceeding the limit of 31 useful characters.

The file path must always start with the character “/”, for example /fichier.txt

The methods (API) of the SPIFFS.h library

SPIFFS.begin()

This method mounts the SPIFFS file system and must be called before any other FS method is used. Returns true if the file system was mounted successfully.

It is advisable to mount the file system in the setup

void setup() { 
  // Launch SPIFFS file system  
  if(!SPIFFS.begin()){ 
    Serial.println("An Error has occurred while mounting SPIFFS");  
  }
}

SPIFFS.format()

Format the file system. Returns true if formatting was successful. Attention, if files are present in the memory area, they will be irreversibly deleted.

if (!SPIFFS.begin(true)) {
    Serial.println("An Error has occurred while mounting SPIFFS");
  return;
}

bool formatted = SPIFFS.format();
 if ( formatted ) {
  Serial.println("SPIFFS formatted successfully");
} else {
  Serial.println("Error formatting");
}

SPIFFS.open(path, option)

Open a file

path must be an absolute path starting with a forward slash (eg /dir/file_name.txt).

option is a string specifying the access mode. It can be

Returns the File object. To check if the file was opened successfully, use the Boolean operator.

Once the file is open, here are the methods that allow you to manipulate it

file.seek(offset, mode)

This function behaves like the fseek function of the C language. Depending on the value of mode, the pointer is positioned in the file like this

SeekSet position is set to offset bytes from the start

SeekCur current position is moved by offset bytes

SeekEnd position is set to shift bytes from end of file

The function returns true if the position was set successfully

file.position()

Returns the current position in the file in bytes.

file.size()

Returns the size of the file in bytes. Please note, it is not possible to know the size of a folder

File file = SPIFFS.open("/test.txt"); 
if(!file){ 
  Serial.println("Failed to open file for reading"); 
  return; 
} 
Serial.print("File size: "); 
Serial.println(file.size()); 
file.close();

file.name()

Returns the name of the file in a constant in the format const char *

file.close()

Close the file

Folder operations

file.isDirectory()

There is no difference between file and folder. The isDirectory() method lets you know if the file is a folder. It is not possible to know the size of a folder

dir.openNextFile()

Open following folder

SPIFFS.exists(path)

Returns true if a file with a given path exists, false otherwise.

SPIFFS.totalBytes()

Returns the total number of bytes used by the SPIFFS file system.

SPIFFS.usedBytes()

Returns the space used by the specified file in bytes

SPIFFS.remove(path)

Deletes the file based on its absolute path. Returns true if the file was deleted successfully.

SPIFFS.rename(pathFrom, pathTo)

Renames the file from pathFrom to pathTo. The paths must be absolute. Returns true if the file was renamed successfully.

SPIFFS.end()

Unmounts the filesystem

How to transfer files to the SPIFFS memory area?

It is possible to directly upload files to the SPIFFS file system using the plugin for the Arduino ESP32 Sketch Data Upload IDE.

To do this, simply create a folder named data at the same level as the main Arduino project file. It is better to avoid creating subfolders.

This is because the SPIFFS file system does not manage the file tree. During the transfer, the files will be “flat”, ie the file will take the access path as name.

To learn more, read this tutorial which explains everything in detail.

Retrieve information from the SPIFFS and list of files

Here is a small example of code which allows you to retrieve information from the memory area as well as the list of files found in the memory area.

#include "SPIFFS.h" 

void listFilesInDir(File dir, int numTabs = 1);

void setup() {
    Serial.begin(112500);
 
    delay(500);
 
    Serial.println(F("Inizializing FS..."));
    if (SPIFFS.begin()){
        Serial.println(F("SPIFFS mounted correctly."));
    }else{
        Serial.println(F("!An error occurred during SPIFFS mounting"));
    }

    // Get all information of SPIFFS
 
    unsigned int totalBytes = SPIFFS.totalBytes();
    unsigned int usedBytes = SPIFFS.usedBytes();
 
    Serial.println("===== File system info =====");
 
    Serial.print("Total space:      ");
    Serial.print(totalBytes);
    Serial.println("byte");
 
    Serial.print("Total space used: ");
    Serial.print(usedBytes);
    Serial.println("byte");
 
    Serial.println();
 
    // Open dir folder
    File dir = SPIFFS.open("/");
    // List file at root
    listFilesInDir(dir);
}

void listFilesInDir(File dir, int numTabs) {
  while (true) {
 
    File entry =  dir.openNextFile();
    if (! entry) {
      // no more files in the folder
      break;
    }
    for (uint8_t i = 0; i < numTabs; i++) {
      Serial.print('\t');
    }
    Serial.print(entry.name());
    if (entry.isDirectory()) {
      Serial.println("/");
      listFilesInDir(entry, numTabs + 1);
    } else {
      // display zise for file, nothing for directory
      Serial.print("\t\t");
      Serial.println(entry.size(), DEC);
    }
    entry.close();
  }
}

void loop() {
 
} 

Open the Serial Monitor to view the occupancy, the available space is the SPIFFS files stored on the flash memory.

Inizializing FS...
SPIFFS mounted correctly.
File system info.
Total space:      1374476byte
Total space used: 502byte

    /test.txt       11

How to write to a file programmatically with SPIFFS.h

We saw how to create a file from a computer and then upload it from the Arduino IDE.

The SPIFFS.h library provides several simple methods for accessing and handling files from an Arduino program. You can use any of the methods listed above.

Add this code just after the file.close(); line

file = SPIFFS.open("/test.txt", "w");
if(!file){
  // File not found
  Serial.println("Failed to open test file");
  return;
} else {
  file.println("Hello From ESP32 :-)");
  file.close();
}

What does this code do?

This time, we open the file with the option “w” to indicate that we want to modify the file. Previous content will be erased

To write to a file, you can use the print() or println() methods. The println() method adds a newline. We will use it to create a data table for example.

Here, we update the previous content

file.println("Hello From ESP32 :-)");

Upload to see what’s going on

How to add data to a file programmatically?

To add data to a file, just open a file with the “a” (append) option to append data to the end of the file.

If the file does not exist, it will be automatically created.

Here is a small example that records a counter every second.

void loop(){
  File file = SPIFFS.open("/counter.txt", "a");
  if(!file){
    // File not found 
    Serial.println("Failed to open counter file");
    return;
  } else {
    counter+=1;
    file.println(counter);
    file.close();
  }
  delay(1000);
}

Updates

02/09/2020 First publication of the post

Click to rate this post!
[Total: 3 Average: 5]
Exit mobile version