Bonjour,
Je recherche à intégrer une variable String dans une structure ainsi:
struct MaStructure {
byte ID;
String HWPRIORITY;
};
MaStructure ms;
Lui donner une valeur, par exemple:
HWPRIORITY = "PNPNPN";
Puis sauvegarder en EEPROM ma structure:
EEPROM.put(0, ms);
Enfin lire ma structure dans le setup et visualiser la variable HWPRIORITY:
EEPROM.get(0,ms);
Serial.print("Var=");Serial.println(ms.HWPRIORITY);
Jusque là, ça fonctionne.
Mais si je veux modifier ma variable et la sauvegarder à l'aide de la console série, ma variable est mal sauvegardée.
J'ai donc une solution qui fonctionne parfaitement mais avec une variable String définie en dehors de ma structure.
Voici mon code actuel qui fonctionne parfaitement:
#include <EEPROM.h>
#define CARRIAGE_RETURN 0x0D /* '\r' = 0x0D (code ASCII) */
#define RUB_OUT 0x08
#define CFG_MSG_MAX_LENGTH 10//22 /* Longest Rx or Tx Message (Message le plus long est S=I 12) donc 8 devrait suffir*/
static char CfgMessage[CFG_MSG_MAX_LENGTH + 1];/* + 1 pour fin de chaine */
struct MaStructure {
byte ID;
};
uint8_t Inputs_Alarms[]={18,19,20,21,15,14};
bool SoundPriorities[]={0,0,0,0,0,0};
String HWPRIORITY;
MaStructure ms;
void setup() {
Serial.begin(115200);
EEPROM.get(0,ms);
for (uint8_t i = 0; i<6; i++)
{
pinMode(Inputs_Alarms[i], INPUT_PULLUP); // 6 Inputs pullup setup
}
/* Priority management of sounds */
// declaring character array (+1 for null terminator)
char* char_array = new char[HWPRIORITY.length() + 1];
// copying the contents of the
// string to char array
strcpy(char_array, HWPRIORITY.c_str());
//Serial.print("Sounds Priorities:");
for (uint8_t x = 0; x < HWPRIORITY.length() ;x++)
{
if (char_array[x] == 'P')
SoundPriorities[x] = true;
// Serial.print(SoundPriorities[x]);//Inputs_Alarms[i]
// if (x < HWPRIORITY.length()) Serial.print(" ");
}
Serial.println();
/* Priority management of sounds */
}
void loop() {
if(CfgMessageAvailable() >= 0)
{
InterpreteCfgAndExecute();
}
/* Read 6 alarms inputs */
for (uint8_t i = 0; i<6; i++)
{
if ((digitalRead(Inputs_Alarms[i]) == LOW) && (SoundPriorities[i] == true))
{
Serial.print("Alarm: ");Serial.print(i+1);Serial.println(" Started !");
}
}
/* Read 6 alarms inputs */
}
void writeStringToEEPROM(int addrOffset, const String &strToWrite)
{
byte len = strToWrite.length();
EEPROM.write(addrOffset, len);
for (int i = 0; i < len; i++)
{
EEPROM.write(addrOffset + 1 + i, strToWrite[i]);
}
}
String readStringFromEEPROM(int addrOffset)
{
int newStrLen = EEPROM.read(addrOffset);
char data[newStrLen + 1];
for (int i = 0; i < newStrLen; i++)
{
data[i] = EEPROM.read(addrOffset + 1 + i);
}
data[newStrLen] = '\0';
return String(data);
}
void readAllEEprom()
{
EEPROM.get(0,ms);// Read all EEPROM settings in one time
if ( ms.ID != 0x99)
{
SettingsWriteDefault();
delay(500);
readAllEEprom();
}
else
{
//EEPROM Ok!
HWPRIORITY = readStringFromEEPROM(100);
Serial.print("Prior: ");Serial.println(HWPRIORITY);
Serial.println();
}
}
void SettingsWriteDefault()
{
ms.ID = 0x99;//write the ID to indicate valid data
HWPRIORITY = "NNNNNN";
writeStringToEEPROM(100,HWPRIORITY);
Serial.println("Defaults Value Saved\r\n");
EEPROM.put(0, ms);
}
static char CfgMessageAvailable(void)
{
char Ret = -1;
char RxChar;
static uint8_t Idx = 0;
if(Serial.available() > 0)
{
RxChar = Serial.read();
switch(RxChar)
{
case CARRIAGE_RETURN: /* Si retour chariot: fin de message */
CfgMessage[Idx] = 0;/* Remplace CR character par fin de chaine */
Ret = Idx;
Idx = 0; /* Re-positionne index pour prochain message */
break;
case RUB_OUT:
if(Idx) Idx--;
break;
default:
if(Idx < CFG_MSG_MAX_LENGTH)
{
CfgMessage[Idx] = RxChar;
Idx++;
}
else Idx = 0; /* Re-positionne index pour prochain message */
break;
}
}
return(Ret);
}
#define COMMAND ( CfgMessage[0] )
#define ACTION ( CfgMessage[1] )
#define ARG ( CfgMessage[2] )
#define REQUEST '?'
#define ORDER '='
#define EMPTY_CMD 0
#define HELP_CMD 'H'
#define MS_SETTINGS 'S'// Read settings from EEPROM
#define MS_PRIORITIES 'I'// Define priorities
enum {ACTION_ANSWER_WITH_REPONSE = 0, ACTION_ANSWER_ERROR};
static void InterpreteCfgAndExecute(void)
{
uint8_t Val8;
uint8_t Action = ACTION_ANSWER_ERROR;
char *CharPtr;
switch(COMMAND)
{
case EMPTY_CMD: /* No break: Normal */
case HELP_CMD:
DisplayHelp();
CfgMessage[1] = 0; /* Echo */
Action = ACTION_ANSWER_WITH_REPONSE;
break;
case MS_SETTINGS://S
if(ACTION == ORDER)
{
Val8 = (uint8_t)atoi(&ARG);
if(ARG == 'W')//S=W Writedefault config
{
SettingsWriteDefault();
}
EEPROM.put(0,ms);
CfgMessage[1] = 0;
Action = ACTION_ANSWER_WITH_REPONSE;
}
else if(ACTION == REQUEST)//S?
{
readAllEEprom();
CfgMessage[1] = 0;
Action = ACTION_ANSWER_WITH_REPONSE;
}
break;
case MS_PRIORITIES://I
if(ACTION == ORDER)
{
if ((ARG == 'P') || (ARG == 'N'))
{
/* Priority management of sounds */
String n = &ARG;
if (n.length()!=6) {
Serial.println("Use 6 N or P !");
CfgMessage[1] = 0;
Action = ACTION_ANSWER_WITH_REPONSE;
break;
}
HWPRIORITY = n;
writeStringToEEPROM(100,HWPRIORITY);
Serial.print("Prior:");Serial.println(HWPRIORITY);
/* Priority management of sounds */
CfgMessage[1] = 0;
Action = ACTION_ANSWER_WITH_REPONSE;
}
else
{
Serial.println("only 6 N or P !");
CfgMessage[1] = 0;
Action = ACTION_ANSWER_WITH_REPONSE;
}
}
else if(ACTION == REQUEST)
{
Serial.println(HWPRIORITY);
CfgMessage[1] = 0;
Action = ACTION_ANSWER_WITH_REPONSE;
}
break;
}
if(Action != ACTION_ANSWER_WITH_REPONSE)
{
strcpy_P(CfgMessage, PSTR("ERR"));
}
Serial.println(CfgMessage);
}
void DisplayHelp(void)
{
Serial.print("\r\nH Help\r\n");
Serial.print("W Board Connections\r\n");
Serial.print("S=W Write Default Settings\r\n");
Serial.print("S? Read Settings\r\n");
Serial.print("I=XXXXXX X=N or P (Priorities)\r\n");
Serial.print("\r\n");
}
J'ai cru comprendre qu'il vaudrait mieux utiliser le type char * dans la structure.
Auriez vous une solution pour simplifier mon code ?
Merci par avance,
Pierre