Je cherche à sauvegarder en EEPROM le nom d'un moteur en texte.
Je voudrais aussi pouvoir le modifier grace à une console série.
J'ai donc créé une structure dans laquelle j'ai quelques variables y compris celle pour le nom de mon moteur.
Mais lorsque je le liste après la sauvegarde (commande SW), ça me retourne n'importe quoi.
Par contre, le changement du nom (commande E TOTO) semble fonctionner.
Postez votre code ici entre balises de code on ne peut pas simplement lire le code sinon depuis un smartphone . (Je n’ai donc pas pu voir votre code).
Pour sauver du texte en eeprom faites une structure avec ce que vous voulez sauvegarder dedans et n’utilisez pas la classe String mais une cString de taille fixe (un tableau de char). Vous pourrez alors utiliser put et get sur la structure.
il y a quelques autres warning à corriger - voici un code qui doit être plus fonctionnel
#include <EEPROM.h>
#include "SerialCommand.h" //https://github.com/kroimon/Arduino-SerialCommand/tree/master
SerialCommand sCmd;
const byte tailleMax = 10 + 1; // 10 caractères max
struct MaStructure {
uint8_t ENGINE_CH;
uint8_t ENGINE_MODE;
char ENGINE_SOUND[tailleMax];
bool SMOKE_ONOFF;
uint8_t SMOKETIMEOFF;
};
MaStructure ms;
#define PRINT_BUF_SIZE 100
static char PrintBuf[PRINT_BUF_SIZE + 1];
#define PRINTF(fmt, ...) do{if(Serial){snprintf_P(PrintBuf, PRINT_BUF_SIZE, PSTR(fmt) ,##__VA_ARGS__);Serial.print(PrintBuf);}}while(0)
void setup()
{
Serial.begin(115200);
sCmd.addCommand("SW", writeSettings);
sCmd.addCommand("S?", readAllEEprom);
sCmd.addCommand("E", writeEngineName);
sCmd.addCommand("R", resetEEPROM);
sCmd.setDefaultHandler(unrecognized);
EEPROM.get(0, ms);
Serial.println("Ready");
}
void loop()
{
sCmd.readSerial(); // We don't do much, just process serial commands
}
void writeEngineName()
{
char *arg;
arg = sCmd.next(); // Get the next argument from the SerialCommand object buffer
strncpy(ms.ENGINE_SOUND, arg, tailleMax);
Serial.print("Engine = "); Serial.println(ms.ENGINE_SOUND);
EEPROM.put(0, ms);
}
void readAllEEprom()
{
EEPROM.get(0, ms); // Read all EEPROM settings in one time
Serial.print("Engine Name: "); Serial.print((char *)ms.ENGINE_SOUND);
Serial.println(ms.ENGINE_MODE == 1 ? " (Ship)" : " (Plane)");
PRINTF("EngineCh: %d\r\n", ms.ENGINE_CH);
Serial.print(ms.SMOKE_ONOFF ? "Engine Smoke:On" : "Engine Smoke:Off");
PRINTF(" (Stop after: %ds)\r\n", ms.SMOKETIMEOFF);
}
void writeSettings()
{
SettingsWriteDefault();
}
void SettingsWriteDefault()
{
ms.ENGINE_CH = 2;
ms.ENGINE_MODE = 0;
ms.SMOKE_ONOFF = false;
ms.SMOKETIMEOFF = 3;
strncpy(ms.ENGINE_SOUND, "VAPEUR", tailleMax);
EEPROM.put(0, ms);
Serial.println("Saved !");
}
void resetEEPROM()
{
for (size_t i = 0 ; i < EEPROM.length() ; i++)
{
EEPROM.write(i, 0);
}
Serial.println("EEprom clear !");
}
// This gets set as the default handler, and gets called when no other command matches.
void unrecognized(const char *command) {
Serial.print("Unreconnized command: ");
Serial.println(command);
}
Je n'ai pas modifié mais notez qu'à la fin de votre setup vous faites
Généralement on insère aussi en EEPROM un mot magique qui dit si la mémoire a déjà été initialisée. Si c'est le cas on fait le get, sinon on charge les valeurs par défaut dans la structure et on fait un write puis on écrit le mot magique afin que les données soit initialisées correctement la première fois. ça évite de lire n'importe quoi depuis l'EEPROM. par exemple il se pourrait que vous chargiez dans votre chaîne ENGINE_SOUND des données sans le caractère nul de fin et ensuite quand vous essayez de l'imprimer ça fera n'importe quoi et ira lire d'autres données en mémoire.
sinon si vous utilisez le mot magique, au lieu de mettre 0 pour l'adresse mémoire EEPROM, créez des constante par exemple
(ou une autre façon est de mettre le mot magique dans la structure comme premier élément. Si quand vous lisez la structure vous ne trouvez pas le mot magique, ça veut dire que les autres éléments ne sont pas corrects)
Merci pour votre aide
En recopiant mon code, j'avais omit la variable du mot magique car la sauvegarde ne se faisant pas (oubli du EEPROM.put(0,ms) , du coup, je l'avais viré.
Et oui, je test cette variable dans le setup.
Vous prenez l’adresse du début de sauvegarde et ajoutez sizeof(la structure) et vous avez l’adresse du premier octet libre après la structure (donc enlever 1 pour avoir l’adresse du dernier octet)
l’opérateur sizeof donne le nombre d’octets utilisé par une variables ou un type