Domotique et objets connectés à faire soi-même

ESP32. Débuter avec la librairie SPIFFS.h pour lire, écrire, modifier des fichiers

spiffs.h esp32 arduino library

SPIFFS (Serial Peripheral Interface Flash File System) est un système de fichiers léger adapté (entre autre) aux micro-contrôleurs disposant d’une mémoire flash SPI tel que l’ESP32 et ESP8266. La librairie Arduino SPIFFS.h permet d’accéder à la mémoire flash comme s’il s’agissait d’un système de fichiers normal comme celui d’un ordinateur (en bien plus simple évidemment). On pourra lire, écrire et ajouter des données à un fichier et réaliser quelques opérations simples (formater, renommer, récupérer des informations…)

 

Attention, la mémoire flash est limitée à 10000 cycles d’écritures. Optimisez votre code pour réduire les opérations d’écritures afin de prolonger la durée de vie de vos projets ESP32.

Présentation du système de fichier SPIFFS (SPI Flash File System)

SPIFFS (pour Serial Peripheral Interface Flash File System) est un système de fichier développé par Peter Andersson (page du projet sur GitHub) qui peut fonctionner sur n’importe quel mémoire flash NOR ou flash SPI.

La librairie développée pour les modules ESP8266 reprend l’essentiel des fonctionnalités avec quelques limitations supplémentaires du fait des limitations des micro-contrôleurs :

Autres limitations utiles à connaître :

Découverte de la librairie SPIFFS.h, API et méthodes disponibles

La librairie SPIFFS.h est un portage de la librairie officielle pour Arduino qui est installée en même temps que le SDK ESP32.

Les méthodes proposées sont quasiment identiques à la librairie FS.h pour ESP8266.

Les méthodes suivantes ne sont pas disponibles

API librairie FS.h Méthode équivalente
SPIFFS.openDir(chemin) aucune
SPIFFS.info(fs_info) SPIFFS.totalBytes()

Renvoie le nombre total d’octets utilisés par le système de fichier SPIFFS.

SPIFFS.usedBytes()

Renvoie l’espace utilisé par le fichier spécifié en octets

Pour accéder au système de fichier, il suffit de la déclarer au début du croquis

#include "SPIFFS.h"

Comment formatter un nom (chemin) de fichier ?

SPIFFS ne gère pas l’arborescence.

On pourra toutefois créer une pseudo arborescence en utilisant le caractère “/” dans le nom de fichier sans dépasser la limite de 31 caractères utiles.

Le chemin de fichier doit toujours commencer par le caractère “/”, par exemple /fichier.txt

Les méthodes (API) de la librairie SPIFFS.h

SPIFFS.begin()

Cette méthode monte le système de fichiers SPIFFS et doit être appelée avant que n’importe quelle autre méthode FS ne soit utilisée. Renvoie true si le système de fichiers a été monté avec succès.

Il est conseillé de monter le système de fichier dans le setup

void setup() { 
  // Launch SPIFFS file system | Démarre le système de fichier SPIFFS 
  if(!SPIFFS.begin()){ 
    Serial.println("An Error has occurred while mounting SPIFFS");  
  }
}

SPIFFS.format()

Formate le système de fichier. Renvoie true si le formatage a réussi. Attention, si des fichiers sont présents dans la zone mémoire, ils seront supprimés de façon irréversible.

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)

Ouvre un fichier

path doit être un chemin absolu commençant par une barre oblique (par exemple /dir/nom_fichier.txt).

option est une chaîne spécifiant le mode d’accès. Il peut s’agir de

Renvoie l’objet File. Pour vérifier si le fichier a été ouvert avec succès, utilisez l’opérateur booléen.

Une fois que le fichier est ouvert, voici les méthodes qui permettent de le manipuler

file.seek(décalage, mode)

Cette fonction se comporte comme la fonction fseek du langage C. En fonction de la valeur de mode, le pointeur est positionné dans le fichier comme ceci

SeekSet la position est définie pour décaler les octets par rapport au début
SeekCur la position actuelle est déplacée par octets de décalage
SeekEnd la position est définie pour décaler les octets à partir de la fin du fichier

La fonction renvoie true si la position a été définie avec succès

file.position()

Renvoie la position actuelle dans le fichier en octets.

file.size()

Renvoie la taille du fichier en octets. Attention, il n’est pas possible de connaître la taille d’un dossier

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()

Renvoie le nom du fichier dans une constante au format const char *.

file.close()

Ferme le fichier

Opérations sur les dossiers

file.isDirectory()

Il n’y a pas de différence entre fichier et dossier. La méthode isDirectory() permet de savoir si le fichier est un dossier. Il n’est pas possible de connaître la taille d’un dossier

dir.openNextFile()

Ouvre le dossier suivant

SPIFFS.exists(chemin)

Renvoie true si un fichier avec un chemin donné existe, false dans le cas contraire.

SPIFFS.totalBytes()

Renvoie le nombre total d’octets utilisés par le système de fichier SPIFFS.

SPIFFS.usedBytes()

Renvoie l’espace utilisé par le fichier spécifié en octets

SPIFFS.remove(chemin)

Supprime le fichier en fonction de son chemin absolu. Renvoie vrai si le fichier a été supprimé avec succès.

SPIFFS.rename(pathFrom, pathTo)

Renomme le fichier de pathFrom à pathTo. Les chemins doivent être absolus. Renvoie true si le fichier a été renommé avec succès.

SPIFFS.end()

Démonte le système de fichier

Comment transférer des fichiers dans la zone mémoire SPIFFS ?

Il est possible de téléverser directement des fichiers dans le système de fichier SPIFFS à l’aide du plugin pour l’IDE Arduino ESP32 Sketch Data Upload.

 

Pour cela, il suffit de créer un dossier nommé data au même niveau que le fichier principal du projet Arduino. Il est préférable d’éviter de créer des sous-dossiers.

En effet, le système de fichier SPIFFS ne gère pas l’arborescence de fichier. Lors du transfert, les fichiers seront mis “à plat”, c’est à dire que le fichier prendra comme nom le chemin d’accès.

Pour en savoir plus, lisez ce tutoriel qui explique tout en détail.

Récupérer les informations de la zone SPIFFS et la liste des fichiers

Voici un petit exemple de code qui permet de récupérer les informations de la zone mémoire ainsi que la liste des fichiers présents dans la zone mémoire.

#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() {
 
} 

Ouvrez le Moniteur série pour visualiser l’occupation, l’espace disponible est les fichiers SPIFFS stockés sur la mémoire flash.

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

    /test.txt       11

Comment écrire dans un fichier par programmation avec SPIFFS.h

On a vu comment créer un fichier depuis un ordinateur puis le téléverser depuis l’IDE Arduino.

La librairie SPIFFS.h met à disposition plusieurs méthodes simples pour accéder et manipuler les fichiers depuis un programme Arduino. Vous pouvez utiliser toutes les méthodes listées précédemment.

Ajouter ce code juste après le ligne file.close();

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

Que fait ce code ?

Cette fois, on ouvre le fichier avec l’option “w” pour indiquer qu’on souhaite modifier le fichier. Le contenu précédent sera effacé

Pour écrire dans un fichier, on peut utiliser les méthodes print() ou println(). La méthode println() ajoute un retour à la ligne. On l’utilisera pour créer un tableau de données par exemple.

Ici, on actualise le contenu précédent

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

Téléverser pour visualiser ce qui se passe

Comment ajouter des données à un fichier par programmation ?

Pour ajouter des données à un fichier, il suffit d’ouvrir de fichier avec l’option “a” (append) pour ajouter des données à la fin du fichier.

Si le fichier n’existe pas, il sera automatiquement créé.

Voici un petit exemple qui enregistre un compteur chaque seconde.

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

Mises à jour

02/09/2020 Première publication de l’article

Avez-vous aimé cet article ?
[Total: 2 Moyenne: 4]
Quitter la version mobile