/** * Exemple d'utilisation de structure avec EEPROM.put(). * Variante avec versionnage et détection de première utilisation. * Utilise une somme de contrôle 16 bits pour détecter les erreurs de lecture. */ #include /** Le nombre magique et le numéro de version actuelle */ static const unsigned long STRUCT_MAGIC = 123456789; static const byte STRUCT_VERSION = 2; /** La structure qui contient les données */ struct MaStructure { unsigned long magic; byte struct_version; uint16_t checksum; int valeur_1; // Depuis la struct_version = 0 float valeur_2; // Depuis la struct_version = 1 char valeur_3[16]; // Depuis la struct_version = 2 }; /** L'instance de la structure, globale car utilisé dans plusieurs endroits du programme */ MaStructure ms; void setup() { Serial.begin(9600); // Charge le contenu de la mémoire chargeEEPROM(); // Affiche les données dans la structure Serial.print("Valeur 1 = "); Serial.println(ms.valeur_1); Serial.print("Valeur 2 = "); Serial.println(ms.valeur_2); Serial.print("Valeur 3 = "); Serial.println(ms.valeur_3); } void loop() { } /** Sauvegarde en mémoire EEPROM le contenu actuel de la structure */ void sauvegardeEEPROM() { // Met à jour le nombre magic, le numéro de version et la checksum avant l'écriture ms.magic = STRUCT_MAGIC; ms.struct_version = STRUCT_VERSION; ms.checksum = 0; // Calcul la checksum sans prendre en compte la valeur actuelle ms.checksum = crc16_ccitt((byte*) &ms, sizeof(ms)); EEPROM.put(0, ms); } /** Charge le contenu de la mémoire EEPROM dans la structure */ void chargeEEPROM() { // Lit la mémoire EEPROM EEPROM.get(0, ms); // Calcul de la checksum uint16_t current_checksum = ms.checksum; ms.checksum = 0; // Calcul la checksum sans prendre en compte la valeur actuelle uint16_t real_checksum = crc16_ccitt((byte*) &ms, sizeof(ms)); // Détection d'une mémoire non initialisée ou corrompue byte erreur = ms.magic != STRUCT_MAGIC || current_checksum != real_checksum; // Valeurs par défaut struct_version == 0 if (erreur) { // Valeurs par défaut pour les variables de la version 0 ms.valeur_1 = 42; } // Valeurs par défaut struct_version == 1 if (ms.struct_version < 1 || erreur) { // Valeurs par défaut pour les variables de la version 1 ms.valeur_2 = 13.37; } // Valeurs par défaut pour struct_version == 2 if (ms.struct_version < 2 || erreur) { // Valeurs par défaut pour les variables de la version 2 strcpy(ms.valeur_3, "Hello World!"); } // Sauvegarde les nouvelles données sauvegardeEEPROM(); } /** Fonction de calcul d'une somme de contrôle CRC-16 CCITT 0xFFFF */ uint16_t crc16_ccitt(unsigned char* data, unsigned int data_len) { uint16_t crc = 0xFFFF; if (data_len == 0) return 0; for (unsigned int i = 0; i < data_len; ++i) { uint16_t dbyte = data[i]; crc ^= dbyte << 8; for (unsigned char j = 0; j < 8; ++j) { uint16_t mix = crc & 0x8000; crc = (crc << 1); if (mix) crc = crc ^ 0x1021;