EEPROM signifie « memoire non-volatile et programmable électriquement ». Les Arduino à base de microcontrôleur AVR (8, 168, 328, 1280, 2560) en comportent une intégrée qui permet de conserver des données lorsque la tension d’alimentation disparaît.
Le cas de l’Arduino Due qui n’en contient pas et nécessite donc une EEPROM externe, sera présenté dans un autre article.
Explications
Bibliothèque officielle faisant partie du référentiel Arduino sur le site éponyme arduino.cc, elle facilite l’écriture du code pour lire et écrire sur la mémoire EEPROM.
Un petit rappel avant de continuer : Sur une carte Arduino, il existe 3 types de mémoire :
- la mémoire flash qui stocke le programme,
- la mémoire SRAM qui stocke les valeurs des variables, toutefois c’est une mémoire volatile. Les valeurs disparaissent à l’extinction de la carte,
- la mémoire EEPROM, semblable à la précédente à la différence que cette mémoire n’est pas volatile à l’extinction de la carte.
Six fonctions sont comprises maintenant dans cette bibliothèque.
Installation
Cette bibliothèque fait partie intégrante d’Arduino, elle est donc installée de base. Il suffit juste de l’importer dans le programme que l’on écrit.
Avertissement
La mémoire EEPROM est semblable à la mémoire flash d’une carte SD, c’est-à-dire que le nombre de réécritures est limité. La mémoire EEPROM a une limite de 100000 réécritures/écrasements, après la mémoire est inutilisable.
Il s’agit donc d’employer ce type de code avec parcimonie. Si il est exécuté à chaque loop, la mémoire va être très vite hors service... Il s’agit donc de l’employer avec conditions, par exemple if, ou simplement juste avant extinction de l’Arduino.
Nous pouvons donc stocker la valeur d’une configuration et ne réécrire cette valeur que lorsque la configuration change. Prenons un exemple concret dans notre domaine, la position d’une aiguille, nous ne réécrirons la valeur de l’aiguille que lorsque la position de l’aiguille aura changé. Cela permettra donc de garder la position des aiguilles à l’extinction et de charger à la réinitialisation la position de toutes les aiguilles en lisant la mémoire EEPROM.
Importer la bibliothèque
#include <EEPROM.h>
Cela se fait en début de programme.
Paramètres des six fonctions
Définissons d’abord le type de cette mémoire. L’EEPROM stocke les valeurs de variables de type byte dans des cases dont le nombre dépend du type de micro contrôleur que possède la carte Arduino. Dans le cadre d’un Arduino Uno, la taille est de 1ko et nous aurons le droit de stocker 1024 valeurs de variables de type byte (0 à 255).
Si nous voulons imager, la mémoire EEPROM est un tableau à 1024 cases dont chaque case a une valeur de type BYTE.
Donc il existe deux paramètres :
- l’adresse de la case : de 0 à 1023
- la valeur de la case qui sera de 0 à 255
Ceci est vrai pour les trois premières fonctions. On verra que cela devient plus sophistiqué pour les trois dernières.
EEPROM.read()
Cette fonction permet de lire la mémoire EEPROM.
Elle a comme paramètre unique l’adresse de la case et renverra la valeur contenue dans la case.
int a = 0;//adresse de la case
byte value;
value = EEPROM.read(a);
Nous sélectionnons la case 0 de la mémoire et stockons la valeur de cette case dans la variable value.
EEPROM.write()
Cette fonction permet d’écrire dans la mémoire EEPROM. Elle doit donc avoir 2 paramètres :
- l’adresse EEPROM
- la valeur que l’on veut stocker, on met le nom d’une variable de type Byte.
int a = 0;//adresse de la case
byte value;
EEPROM.write(a, value);
Ce code va stocker la valeur contenue dans la variable value dans l’EEPROM à l’adresse 0.
EEPROM.update()
Cette fonction permet d’écrire dans la mémoire EEPROM seulement si la valeur à écrire est différente de la valeur déjà présente à cette adresse. Cette fonction permet d’augmenter la durée de vie de la mémoire.
Comme EEPROM.write(), elle doit donc avoir 2 paramètres :
- l’adresse EEPROM
- la valeur que l’on veut stocker, on met le nom d’une variable de type Byte.
for (int i = 0; i < 255; i++) {
// résultat identique à EEPROM.write(i, i)
EEPROM.update(i, i);
}
for (int i = 0; i < 255; i++) {
// écrit "12" à l’adresse 3 seulement la 1ère fois
// mais ne modifie plus cette adresse les 254 autres tours de la boucle for
EEPROM.update(3, 12);
}
Ce code devrait remplacer avantageusement :EEPROM.write().
EEPROM.get()
Cette fonction permet de lire une structure de donnée complexes en une seule instruction (plutôt qu’un seul octet à la fois).
Elle doit donc avoir 2 paramètres :
- l’adresse EEPROM de départ,
- la variable que l’on veut lire, de n’importe quel type y compris une structure.
struct MyObject{
float field1;
byte field2;
char name[10];
};
int eeAddress = 0; // adresse de départ dans l’EEPROM
MyObject customVar;
//Variable à initialiser à partir de l’EEPROM.
EEPROM.get( eeAddress, customVar );
La variable customVar contient maintenant le contenu lu dans l’EEPROM.
EEPROM.put()
Cette fonction permet d’écrire une structure de donnée complexe en une seule instruction (plutôt qu’un seul octet à la fois).
Elle doit donc avoir 2 paramètres :
- l’adresse EEPROM de départ,
- la variable que l’on veut écrire, de n’importe quel type y compris une structure.
struct MyObject{
float field1;
byte field2;
char name[10];
};
int eeAddress = 0; // adresse de départ dans l’EEPROM
MyObject customVar = {
3.14f,
65,
"Working!"
};
//Variable à initialiser à partir de l’EEPROM.
EEPROM.put( eeAddress, customVar );
La variable customVar est maintenant enregistrée dans l’EEPROM.
Cette fonction utilise la fonction EEPROM.update() pour optimiser la durée de vie de l’EEPROM.
EEPROM[]
Il s’agit en fait d’un opérateur qui permet d’utiliser la mémoire EEPROM comme un tableau. On peut lire et écrire directement par cette méthode.
Le seul paramètre est l’adresse dans le tableau.
unsigned char val;
//Lecture de la 1ère cellule.
val = EEPROM[ 0 ];
//Ecriture de la 1ère cellule.
EEPROM[ 0 ] = val;
//Comparaison de contenu
if( val == EEPROM[ 0 ] ){
//...
}
Mais attention de ne pas oublier qu’il s’agit d’une EEPROM !!!