ESP32 EEprom.h ou preferences.h

Bonjour,

J'ai plusieurs "sons de cloches" à propos de sauvegarde en mémoire. Il y a la librairie eeprom.h mais il m'est dit qu'il ne faut pas utiliser celle-ci avec ESP32, mais plutôt preferences.h
Bien j'ai donc commencé avec preferences mais j'estime que c'est, pour moi, une usine à gaz, et je préfèrerais, de loin utiliser EEprom que je trouve juste efficace et simple (adresse->octet = parfait)
Confirmez vous de ne pas utiliser, sur l'ESP32, cette dernière ? Merci
Hervé

Salut.
Tout dépend des informations que l'on veut stocker.
Si ce sont des bytes ou des entiers, autant utiliser EEPROM, et dans ce cas, il est encore plus judicieux de regrouper ces informations dans une structure, afin de ne pas avoir à gérer l'offset.
Si ce sont des chaînes de caractères de longueur variable, je pense que préférences est le meilleur choix.

EDIT : lorsque l'on utiliser EEPROM il est pratiquement obligatoire d'ajouter un nombre magique à la structure, car en cas de modification de celle-ci, le logiciel peut lire le nombre magique, le reconnaître ou non, et agir en conséquence.
préférences n'a pas cet inconvénient.

Hello hbachetti,
Donc tu me confirmes qu'il n'y a pas de raisons de ne pas l'utiliser. Merci
Bah je vais avoir une trentaine d'octets... (IP-gateway-mask et quelques bricoles)
Mais tu m'interpelles avec le "nombre magique" Keskecé ?
Serait-ce un checksum ou quelque chose du genre ?
Enfin pour ma trentaine de bytes, je vais peut-être pas faire de structure.... J'essaye de faire le plus simple possible.
Amicalement
Hervé

Cherche nombre magique dans cet article :
https://riton-duino.blogspot.com/2019/03/arduino-sauvegarde-de-donnees-en-eeprom.html

Aussi : paragraphe 7. Améliorons avec un CRC

Au contraire, avec une structure ce sera plus simple.

#define EEPROM_ADDR 0    // une seule adresse à gérer
struct __attribute__ ((packed)) eeprom_data
{
  int a;
  int b;
  int c;
};
  struct eeprom_data data;  // structure de données
  // ...
  EEPROM.get(EEPROM_ADDR, data);  // lecture des données
  EEPROM.put(EEPROM_ADDR, data); // écriture

j'ai déplacé ce post en dehors de la partie Tuto ➜ remis dans la section générale francophone

Oui, c'est très intéressant !
Je devrais me faire une banque de liens avec tout ce genre de tutos bien expliqués.
D'accord pour la structure.
Je ne vais toutefois pas mettre de sécurité sur le risque de corruption des datas en mémoire.
Ce sont, dans mon projet, des datas qui ne bougent quasi jamais... Une fois à l'installation et peut-être si on installe ailleurs....
De toutes mes mises en EEprom sur PIC j'ai jamais rien perdu. Je pense pas que l'ESP32 est plus capricieux ?
Ah... Tant que j'y suis, sur mes pics je faisais:
MOT var word
MOT.0 était de fait le byte0 de mon "MOT"
et MOT.1 ....
Tant à la lecture qu'à l'écriture en EEprom, ou série par exemple
Il existe un équivalent aussi simple pour arduino ?
J'ai trouvé ça:

byte low =  intVar & 0xFF;  // Take just the lowest 8 bits.
byte high = intVar >> 8;  // Shift the integer right 8 bits.

Mais même si je pige le truc, c'est pas aussi simple.
Merci bien

Merci, et Bonjour.
Je ferais attention à l'endroit ou je dois poster dans l'avenir. (je savais pas trop...)
Amicalement

Bonjour @F1SLU

De toutes mes mises en EEprom sur PIC j'ai jamais rien perdu. Je pense pas que l'ESP32 est plus capricieux ?

Contrairement aux PIC , AVR ...... les ESP32 et autres microcontrolleurs 32 bits ne contiennent pas d'EEPROM !!
La bibliothèque EEPROM se chargeant d'émuler une EEPROM dans un coin de la mémoire FLASH , avec comme conséquence un nombre de cycles effacement/écriture plus faible que celui des EEPROM

Perso je préfère à 'Eeprom' l'organisation proposée par la bibliothèque 'Préferences '

Je prend également en compte le choix d'Espressif d'en faire bibliothèque désormais recommandée sous ARDuino (bibliothèque NVS sous IDF) pour le stockage de petites données de manière non volatile, et de maintenir celle-ci et la faire à l'avenir évoluer pour permettre le stockage dans d'autres mémoires externes que la mémoire Flash (FRAM entre autres)

C'est autre chose que de dire 'il ne faut pas utilser EEPROM' .....

sur ESP32 il vaut mieux effectivement passer par la bibliothèque preferences et une structure (avec putBytes, getBytes)

le mot magique n'est pas forcément nécessaire puisque la bibliothèque offre un service de plus haut niveau

voici un exemple avec une structure dans laquelle vous mettez tout ce que vous voulez sauvegarder.

#include <Preferences.h>
Preferences preferences;

struct Params {
  uint32_t compteur;
  char message[10];
} donnees;

bool ecrire(Params & p) {
  preferences.begin("monEspace");
  size_t n = preferences.putBytes("medDonnees", &p, sizeof p);
  preferences.end();
  return n == sizeof p;
}

bool lire(Params & p) {
  preferences.begin("monEspace");
  size_t n = preferences.getBytes("medDonnees", &p, sizeof p);
  preferences.end();
  return n != 0;
}


void setup() {
  Serial.begin(115200);
}

void loop() {
  Serial.println("--------------------");

  if (lire(donnees)) {
    Serial.println("Données:");
    Serial.print("Compteur = "); Serial.println(donnees.compteur);
    Serial.print("message = "); Serial.println(donnees.message);

    // on incrémente pour le prochain tour après le reboot
    donnees.compteur++;
    // on change le message suivant la parité du compteur
    if (donnees.compteur % 2) {
      strlcpy(donnees.message, "IMPAIR", sizeof donnees.message);
    } else {
      strlcpy(donnees.message, "PAIR", sizeof donnees.message);
    }
    
    if (ecrire(donnees)) {
      Serial.println("OK - mise à jour");
    } else {
      Serial.println("Erreur - mise à jour");
    }
  } else {
    Serial.println("Je n'ai pas trouv les données. Tentative écriture");
    // la mémoire n'existe pas, on la crée
    donnees.compteur = 1;
    strlcpy(donnees.message, "Coucou", sizeof donnees.message);
    if (ecrire(donnees)) {
      Serial.println("OK - Première écriture");
    } else {
      Serial.println("Erreur - Première écriture");
    }
  }

  Serial.println("on recommence dans 3 secondes...");
  delay(3000);
}

Non, il existe un équivalent en C (Arduino, c'est du pur C / C++) : les champs de bits
Cela va plus loin que découper un word en deux bytes. On peut donner la taille que l'on veut à chaque membre :

struct my_struct
{
   int member1 : 8;
   unsigned int member2 : 4;
   unsigned int member3 : 4;
};

Ce qui fait 16 au total.

mais vaut mieux écrire

struct __attribute__((packed)) my_struct
{
   int member1 : 8;
   unsigned int member2 : 4;
   unsigned int member3 : 4;
};

pour dire au compilateur qu'on veut vraiment que ça ressemble à cela si on veut à tout prix qu'il n'y ait que 2 octets sinon il peut prendre des libertés

Oui, bien entendu.

Bien.... Merci les gars. :+1:
Je vais prendre un peu sur mon week end pour avaler ça.
C'est beaucoup de boulot, je pensais m'en sortir plus facilement / vite. Je me rends compte que j'ai bien plus à apprendre que prévu.
Je repasserais sur ce sujet si je rame... :wink:
PS: Pas vraiment de news de mon "prof" de superprofs... Je me demande si je me suis pas fait arnaqué, je patiente un peu....

Bonjour je suis de retour :wink:
Bien je suis parti pour utiliser preferences.h et j'ai ceci dans mon setup:

  preferences.begin("my-ip", true); // initialize the preferences library with preference space allocation 4096 octets
  // Lire l'adresse IP stockée à l'adresse "my-ip" dans la flash
  uint8_t readIpAddress[4];
  preferences.getBytes("my-ip", readIpAddress, 4);
  if (readIpAddress[0] != 0){                 // pas d'IP dans la flash, on affiche pas
    Serial.print("Adresse IP lue : ");
    Serial.print(readIpAddress[0]);
    Serial.print(".");
etc...

et j'obtiens:
[ 4016][E][Preferences.cpp:50] begin(): nvs_open failed: NOT_FOUND
Un peu d'aide SVP ?
Merci

Bonjour @F1SLU

1.As tu testé les deux exemples fournis dans l'IDE pour la bibliothèque 'Préférences' ?

2.Quelle carte as-tu sélectionné dans l'IDE ?

Bonjour al1fch,
Je viens de tester avec le code plus haut de

J-M-LJackson et ça marche.....
Bien je vais regarder de plus près les différences entre son code d'initialisation et le mien.

Pour finir, comme je voyais rien, j'ai tout effacé et tout réécrit, et ca colle.... Merci quand même.

Bravo

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.