0

I am making a project, in which I need to store the WiFi credentials to the EEPROM. For now, I am able to store a bool array in the EEPROM, but I am not able to store the char variables as the ESP32 crashes. I can't share the complete code since it is REALLY long, but here are the problematic functions:

To save to the EEPROM:

//////////////////////////////////WORKING////////////////////////////////
void saveToEEPROM() {
  // Save the contents of the array in EEPROM memory
  for (int i = 0; i < NUM_PARAM_ITEMS; i++) {
    EEPROM.write(i, menu_items_param_bool[i]);
  }
//////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////NOT WORKING////////////////////////////////
  // Save WiFi credentials in EEPROM if not empty
  int offset = NUM_PARAM_ITEMS;

  if (strlen(ssid1) > 0) {
    for (int i = 0; i < strlen(ssid1); i++) {
      EEPROM.write(offset + i, ssid1[i]);
    }
    offset += strlen(ssid1);
    EEPROM.write(offset, '\0'); // Null-terminate the SSID1 string
  }
  offset++;
  if (strlen(password1) > 0) {
    for (int i = 0; i < strlen(password1); i++) {
      EEPROM.write(offset + i, password1[i]);
    }
    offset += strlen(password1);
    EEPROM.write(offset, '\0'); // Null-terminate the Password1 string
  }
  offset++;
  if (strlen(ssid2) > 0) {
    for (int i = 0; i < strlen(ssid2); i++) {
      EEPROM.write(offset + i, ssid2[i]);
    }
    offset += strlen(ssid2);
    EEPROM.write(offset, '\0');  // Null-terminate the SSID2 string
  }
  offset++;
  if (strlen(password2) > 0) {
    for (int i = 0; i < strlen(password2); i++) {
      EEPROM.write(offset + i, password2[i]);
    }
    offset += strlen(password2);
    EEPROM.write(offset, '\0'); // Null-terminate the Password2 string
  }

  EEPROM.commit(); // Don't forget to call the commit() function to save the data to EEPROM
}

To read from the EEPROM:

void readFromEEPROM() {
//////////////////////////////////WORKING////////////////////////////////
  // Read the contents of the EEPROM memory and restore it to the array
  for (int i = 0; i < NUM_PARAM_ITEMS; i++) {
    menu_items_param_bool[i] = EEPROM.read(i);
  }
//////////////////////////////////NOT WORKING//////////////////////////////////
  // Read WiFi credentials from EEPROM if not empty
  int offset = NUM_PARAM_ITEMS;

  // Read SSID1
  int ssid1Length = EEPROM.read(offset);
  if (ssid1Length > 0) {
    for (int i = 0; i < ssid1Length; i++) {
      ssid1[i] = (char)EEPROM.read(offset + i + 1);
    }
    ssid1[ssid1Length] = '\0'; // Null-terminate the SSID1 string
    Serial.print("SSID1: ");
    Serial.println(ssid1);
  }
  offset += ssid1Length + 1;

  // Read Password1
  int password1Length = EEPROM.read(offset);
  if (password1Length > 0) {
    for (int i = 0; i < password1Length; i++) {
      password1[i] = (char)EEPROM.read(offset + i + 1);
    }
    password1[password1Length] = '\0';  // Null-terminate the Password1 string
    Serial.print("PASSWORD1: ");
    Serial.println(password1);
  }

  offset += password1Length + 1;

  // Read SSID2
  int ssid2Length = EEPROM.read(offset);
  if (ssid2Length > 0) {
    for (int i = 0; i < ssid2Length; i++) {
      ssid2[i] = (char)EEPROM.read(offset + i + 1);
    }
    ssid2[ssid2Length] = '\0'; // Null-terminate the SSID2 string
    Serial.print("SSID2: ");
    Serial.println(ssid2);
  }

  offset += ssid2Length + 1;

  // Read Password2
  int password2Length = EEPROM.read(offset);
  if (password2Length > 0) {
    for (int i = 0; i < password2Length; i++) {
      password2[i] = (char)EEPROM.read(offset + i + 1);
    }
    password2[password2Length] = '\0'; // Null-terminate the Password2 string
    Serial.print("PASSWORD2: ");
    Serial.println(password2);
  }
}

And the variables to save and read are:

char ssid1[32] = "ssid1"; // SSID of the first WiFi network
char password1[64] = "password1"; // Password of the first WiFi network
char ssid2[32] = "ssid2"; // SSID of the second WiFi network
char password2[64] = "password2"; // Password of the second WiFi network

Can anybody help me?

2
  • 1
    what is the specific problem? ... but not the Char variables does not desctibe what actually happens ... please update your question above ... do not add a comment below
    – jsotola
    Commented Jan 27 at 20:18
  • 2
    In your read routine you are trying to read the length of the string from EEPROM, but you never saved the length there, just the null terminated strings themselves. For that to work you would need to write strlen() to EEPROM directly before the string
    – chrisl
    Commented Jan 27 at 20:27

1 Answer 1

1

There are multiple issues with your code.

  1. If strlen(anystring) is zero, you write nothing, but increment offset.
  2. You try to read the lengths of the strings from EEPROM, but you never write them there.

Some things are complicated and can be simplified.

  1. You don't need to explicitly write '\0' (end-of-string marker), since each of your strings already includes it.
  2. Increment offset directly in the course.

This is a possible corrected solution. It uses the length and the end-of-string marker for each stored string.

  // Write anystring
  int anystringLength = strlen(anystring);
  EEPROM.write(offset, anystringLength);
  offset++;
  for (int i = 0; i <= anystringLength; i++) {
    EEPROM.write(offset, anystring[i]);
    offset++;
  }
  // Read anystring
  int anystringLength = EEPROM.read(offset);
  offset++;
  for (int i = 0; i <= anystringLength; i++) {
    anystring[i] = (char)EEPROM.read(offset);
    offset++;
  }
  // start of debug output
  Serial.print("any String: ");
  Serial.println(anystring);
  // end of debug output

Note: To make things explicit, using the offset and incrementing it are separated. You can combine them, though. But terse code tend to be misinterpreted.

This is another possible solution. Instead of expecting the length written before a string, read it until you find the end-of-string marker.

The writing loop writes all characters including the final end-of-string marker. This works for empty strings, too.

  int i;
  // Write anystring
  i = 0;
  do {
    char c = anystring[i];
    EEPROM.write(offset, c);
    offset++;
    i++;
  } while (c != '\0');

The reading loop does the same in the opposite direction. Using the do-while loop ensures that the end-of-string marker is read in any case.

  int i;
  // Read anystring
  i = 0;
  do {
    char c = EEPROM.read(offset);
    anystring[i] = c;
    offset++;
    i++;
  } while (c != '\0');
  // start of debug output
  Serial.print("any String: ");
  Serial.println(anystring);
  // end of debug output

Like the original the solutions lack error checks, for example of too long strings, which are left as an exercise to the reader.

Another bonus point will be received, if you extract these loops into functions. It simplifies the code and removes duplicates. [Edit] I found that the EEPROM class already provides writeString() and readString(). You should read its documentation and consider the usage.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.