Write String to permanent flash memory of Arduino ESP32
Asked Answered
G

2

5

I want to write some text into the flash memory of an Arduino ESP32. It works kinda but not as I want it to.

void writeString(const char* toStore, int startAddr) {
  int i = 0;
  for (; i < LENGTH(toStore); i++) {
    EEPROM.write(startAddr + i, toStore[i]);
  }
  EEPROM.write(startAddr + i, '\0');
  EEPROM.commit();
}

My call

writeString("TEST_STRING_TO_WRITE", 0);

only writes TEST into the memory. I do not understand why. Is that because of the _? Or am I missing something different?

Here is the used LENGTH macro

#define LENGTH(x) (sizeof(x)/sizeof(x[0]))

and the method I use to read the string from the memory again (which seems to work correctly):

String readStringFromFlash(int startAddr) {
  char in[128];
  char curIn;
  int i = 0;
  curIn = EEPROM.read(startAddr);
  for (; i < 128; i++) {
    curIn = EEPROM.read(startAddr + i);
    in[i] = curIn;
  }
  return String(in);
}
Geminian answered 14/5, 2019 at 22:54 Comment(0)
N
3

Where on earth did you get that LENGTH macro from? It’s surreal.

sizeof will not do what you want here. It’s a compile-time function that computes the storage requirements of its argument. In this case it should return the length in bytes of a character pointer, not the string it points to.

You want to use strlen(), assuming your char* is a properly terminated C string. Add one to make sure the ‘\0’ at the end gets stored, too.

#define LENGTH(x) (strlen(x) + 1)
Needlecraft answered 15/5, 2019 at 0:44 Comment(3)
it's from visual studio. thanks a lot, its working now. But I thought sizeof(x) gives the size of the array in bytes. And that has to be devided by the size of the datatype in the array to get the number of elementsGeminian
If you had char string[23]; then sizeof(string); would return 23, even if you only stored a 5 character string in the character array. If you then passed string as an argument to a function and used sizeof inside the function, you'd (most likely, it would depend on the CPU) get 4 because the function would only know about a char *. sizeof returns the number of bytes needed to store whatever its argument is.Needlecraft
This gets really bad with String - if you did sizeof(String("verylongstring")), you'll get the number of bytes needed to store a String object, not the number of bytes it allocated to store its data. This bites people all the time.Needlecraft
W
3

Below is the code to demonstrate the storing as well as retrieving of the string ssid in the EEPROM (permanent storage).

#include "EEPROM.h"

int addr = 0;
#define EEPROM_SIZE 64

// the sample text which we are storing in EEPROM
char ssid[64] = "CARNIVAL OF RUST";

void setup() {
    Serial.begin(115200);
    Serial.println("starting now...");

    if (!EEPROM.begin(EEPROM_SIZE)) {
        Serial.println("failed to init EEPROM");
        while(1);
    }

    // writing byte-by-byte to EEPROM
    for (int i = 0; i < EEPROM_SIZE; i++) {
        EEPROM.write(addr, ssid[i]);
        addr += 1;
    }
    EEPROM.commit();

    // reading byte-by-byte from EEPROM
    for (int i = 0; i < EEPROM_SIZE; i++) {
        byte readValue = EEPROM.read(i);

        if (readValue == 0) {
            break;
        }

        char readValueChar = char(readValue);
        Serial.print(readValueChar);
    }
}

void loop() {

}
Winstead answered 19/11, 2019 at 14:56 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.