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

ESP8266. Comment lire, écrire, effacer l’EEPROM. Calculer l’espace nécessaire en bytes

L’ESP8266 dispose d’une zone mémoire réservée pour simuler l’EEPROM interne de l’Arduino. Initialement, cette zone était présente pour mimer le fonctionnement de l’Arduino et rendre plus facile la migration des programmes. On peut s’en servir pour stocker certains paramètres, tels qu’une adresse IP ou les paramètres Wi-Fi. La taille peut varier de 4 à 4096 bytes sur un ESP8266.

 

L’organisation de la mémoire Flash d’un module ESP8266

Comme un ordinateur, le module ESP8266 dispose d’une petite quantité de RAM utilisable par l’utilisateur (80ko) et d’un espace de stockage constitué d’un élément à  mémoire flash (similaire aux clés USB) accessible via le bus SPI.

La taille de la mémoire flash varie d’un fabricant à l’autre mais la norme est de 4Mo.

L’accès à la mémoire flash est entièrement géré par le SDK ESP-IDF du fabricant Espressif et se fait via le bus SPI.

La mémoire flash est découpée et chaque espace est réservée pour chaque fonction :

|--------------|-------|---------------|--|--|--|--|--|
^              ^       ^               ^     ^
Sketch    OTA update   File system   EEPROM  WiFi config (SDK)

Comment calculer la dimension en byte à réserver ?

C’est tout simple, il suffit de réserver un byte par caractère.

Prenons un exemple d’identifiant et de mot de passe au réseau WiFi que l’on souhaite stocker dans la zone EEPROM de l’ESP8266.

Voici ce que ça donne de façon plus visuelle.

-------------------------------------------------------
|0|1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|...|511|
|s|s|i|d|w|i|f|i| | |p |a |s |s |w |o |r |d |  |...|   |
-------------------------------------------------------
^                   ^
index_ssid (0)      index_password (10)

Un exemple d’écrire et de lecture dans la zone EEPROM

Voici un petit exemple qui enregistre l’identifiant réseau et le mot de passe.

Il est possible d’effacer l’EEPROM au démarrage en passant la variable RESET_EEPROM à true.

#include <EEPROM.h> 

int addr_ssid = 0;         // ssid index
int addr_password = 20;    // password index
String ssid = "wifi_ssid"; // wifi ssid
String password = "wifi_password_demo"; // and password

// Set to true to reset eeprom before to write something
#define RESET_EEPROM false

void setup() {
  Serial.begin(115200);
  EEPROM.begin(512);
  Serial.println("");
  
  if ( RESET_EEPROM ) {
    for (int i = 0; i < 512; i++) {
      EEPROM.write(i, 0);
    }
    EEPROM.commit();
    delay(500);
  }
 
  Serial.println("");
  Serial.print("Write WiFi SSID at address "); Serial.println(addr_ssid);
  Serial.print("");
  for (int i = 0; i < ssid.length(); ++i)
  {
    EEPROM.write(addr_ssid + i, ssid[i]);
    Serial.print(ssid[i]); Serial.print("");
  }

  Serial.println("");
  Serial.print("Write WiFi Password at address "); Serial.println(addr_password);
  Serial.print("");
  for (int j = 0; j < password.length(); j++)
  {
    EEPROM.write(addr_password + j, password[j]);
    Serial.print(password[j]); Serial.print("");
  }

  Serial.println("");
  if (EEPROM.commit()) {
    Serial.println("Data successfully committed");
  } else {
    Serial.println("ERROR! Data commit failed");
  }

  Serial.println("");
  Serial.println("Check writing");
  String ssid;
  for (int k = addr_ssid; k < addr_ssid + 20; ++k)
  {
    ssid += char(EEPROM.read(k));
  }
  Serial.print("SSID: ");
  Serial.println(ssid);

  String password;
  for (int l = addr_password; l < addr_password + 20; ++l)
  {
    password += char(EEPROM.read(l));
  }
  Serial.print("PASSWORD: ");
  Serial.println(password);
}

void loop() {

}

Comment écriture dans l’EEPROM ?

On déclare la libraire qui permet de gérer la zone mémoire

#include <EEPROM.h>

Des variables contiennent l’index et le contenu à enregistrer, par exemple pour l’identifiant du réseau WiFi.

int addr_ssid = 0;         // ssid index
String ssid = "wifi_ssid"; // wifi ssid

Avant de pouvoir utiliser l’EEPROM, il faut l’initialiser en lui attribuant une taille en byte. La taille peut varier de 4 à 4096 bytes. Ici, on attribue 512 bytes mais c’est arbitraire.

EEPROM.begin(512);

On parcours la chaine de caractère contenant l’identifiant réseau et celle du mot de passe. On écrit avec la commande EEPROM.write() chaque caractère de la chaîne à l’aide d’une boucle for.

Remarquez le décalage qui permet de se positionner dans la bonne case mémoire addr_password + j à chaque itération de la boucle for.

for (int j = 0; j < password.length(); j++) { 
  EEPROM.write(addr_password + j, password[j]);  
}

La commande write n’écrit pas directement dans l’EEPROM. Elle prépare juste un tableau de bytes qu’il faut ensuite enregistrer dans la zone mémoire à l’aide de la commande commit().

EEPROM.commit()

Comment lire dans l’EEPROM ?

On lit dans l’EEPROM chaque bytes successivement à l’aide de la méthode read(position). On ajoutera successivement chaque caractère (char) à une chaîne (String)

String password;

Pour récupérer le mot de passe, on va lire de addr_password à addr_password + 20 puisqu’on a réservé 20 bytes pour le mot de passe, ce qui donne

for (int l = addr_password; l < addr_password + 20; ++l) { 
 password += char(EEPROM.read(l)); 
}

Comment effacer l’EEPROM en cas de problème ?

Tout simplement en écrivant 0 pour chaque byte. Le SDK ESP8266 est livré avec un exemple dont voici une version simplifiée.

#include <EEPROM.h>  

void setup() {
  EEPROM.begin(512);
  // write a 0 to all 512 bytes of the EEPROM
  for (int i = 0; i < 512; i++) {
    EEPROM.write(i, 0);
  }
  EEPROM.end();
}

void loop() {
}

Peut-on stocker des caractères spéciaux dans l’EEPROM ?

Oui, à priori la majorité des caractères spéciaux peuvent être enregistrés.

J’ai testé avec succès les caractères spéciaux et accentués suivants (sans oublier l’espace)

& é ' ( § è ! ç à ) - @ # ^ ¨ % , ? ; . : / = + ! | _ -

Mises à jour

14/08/2020 Première publication de l’article

Avez-vous aimé cet article ?
[Total: 1 Moyenne: 4]
Exit mobile version