Storing const char* array into eeprom and reading it back

Hi there

I've already read many posts about how to save ints or bytes or strings on arduino EEPROM but my problem still remains

i have a const char* array and i want to save it in eeprom so whenever i make a change to this array i call my function to save it on eeprom again and in case of a powerout none of my numbers get lost but no luck so far
my code is for a sim reader with special id codes and i want to keep a list of authorized phones for my code execution:

#include <SoftwareSerial.h>
#include <EEPROM.h>

char buffer[256];
const char* savednumbers[10] = {"+1289203104190", "+1281483104190", "+1281489122810", "@1281489131041"};
//it says 10 numbers and its for the case that i want to add another number to the list (numbers are just for example)

i would appreciate any help regarding to how can i store my array in eeprom and read it back on start up exactly as a const char* array

Thank you in advance

you can't, const is a precompiler statment to put the data in flash, rather than RAM.

A const array wouldn't ever need to be stored in EEPROM, you can't modify it and it's stored in flash.
Arrrr you beat me to it!

I don't think const is a precompiler function though... I think it's part of the actual compiler.

That means that the following data can't also be stored in EEPROM by
executing EEPROM.write(0, x)?

const byte x = 0x75;

Yes, a copy of a const can be stored into EEPROM, but you still have the original const byte x stored in flash. One thing you won't be able to do is write over it with x = EEPROM.read(0)

Not necessarily, in many Arduino boards const data is stored in ram, unless you specify PROGMEM.

What I understand about the role of const keyword is this:

A variable qualified by const keyword can't be reassigned a new value after the first intialization. The user has the liberty to store it freely either in RAM or flash. For example:

const byte x = 0x75;
x = 0x85;  //is not allowed by the compiler

Now a const char* array can be altered, the array itself is not const, the pointers point to a const.

What's it all about, projectsalehx ?

Ah, true, but the compiler won't allow you to write it even though it is.

I think the question is (x)Y ?

If you have the numbers hard coded in the code I can't modify them, and if you will change the numbers somewhere in the code, I guess it should not be constant...

But for what you want, I would try something like this:

#include <EEPROM.h>

char* savednumbers[10] = {};

template <typename T> 
unsigned int writeAnythingToEEPROM(const T& value)
{
    const byte * p = (const byte*) &value;
    unsigned int i;
    for (i = 0; i < sizeof value; i++) 
    {
        EEPROM.update(i, *p++);
    }
    return i;
}

template <typename T> 
unsigned int readAnythingFromEEPROM(T& value)
{
    byte * p = (byte*) &value;
    unsigned int i;
    for (i = 0; i < sizeof value; i++)
    {
        *p++ = EEPROM.read(i);
    }
    return i;
}

Then, you can use those functions to read and save the numbers in EEPROM like:

readAnythingFromEEPROM(savednumbers);

and

writeAnythingToEEPROM(savednumbers);

How are those better than https://www.arduino.cc/en/Reference/EEPROMPut and https://www.arduino.cc/en/Reference/EEPROMGet ?

about saving a const char array inside eeprom
and people right i forgot that constant variables are fixed
i made it this way to avoid change of data by my program a while back

ye i forgot about const chars

so basicly we convert chars array into bytes like a normal string
ill try it as soon as i can but is asking for a char array puts all of the variables in a line so they can all be read and written with a single line?! or we have to specify the location in eeprom for each entry and use codes like this:

readAnythingFromEEPROM(savednumbers[k]);
writeAnythingToEEPROM(savednumbers[k]);

kinda got confused :confused:

actually, this two functions, readAnythingFromEEPROM and writeAnythingToEEPROM I saw in an another post some time ago, and use it a lot when need to store things in EEPROM.

From what I understand they take a parameter of any kind, and stores to EEPROM/reads from it. It always put the data on the beginning of the EEPROM, and uses as much space is needed.

If you run writeAnythingToEEPROM(something); and "something" is an string, the function will split the string in bytes and save in the EEPROM, but the "something" can be anything, can be for example an array of int, or even an structure

In your case you can, in just one line, save the whole array of char * with the command writeAnythingToEEPROM(savednumbers);

If you want to make the function start writing/reading not in the beginning of the EEPROM, but in another address I think something like that will work:

template <typename T> 
unsigned int writeAnythingToEEPROM(const T& value, unsigned int addressToStart)
{
    const byte * p = (const byte*) &value;
    unsigned int i;
    for (i = addressToStart; i < (sizeof value) + addressToStart; i++) 
    {
        EEPROM.update(i, *p++);
    }
    return i;
}

template <typename T> 
unsigned int readAnythingFromEEPROM(T& value, unsigned int addressToStart)
{
    byte * p = (byte*) &value;
    unsigned int i;
    for (i = addressToStart; i < (sizeof value) + addressToStart; i++)
    {
        *p++ = EEPROM.read(i);
    }
    return i;
}

Notice that the change is in the for loop

But I never had to use this functions like that because when I need to save more than one variable, I make it as an structure and save the whole structure in the EEPROM, so I don't have to thing about the beginning and ending address of each variable in the EEPROM

I think thats it, if you didn't understand something, tell and I can explain better

Edit: you can use the functions
EEPROM.put(0, savednumbers); and EEPROM.get(0, savednumbers);
instead of
writeAnythingFromEEPROM(savednumbers); and readAnythingFromEEPROM(savednumbers);
They make exactly the same thing, but are built in the EEPROM library

actually I don't know hahaha. I can't tell that I never herd of this function, but I don't know why I didn't use it before, it seems that this function does exact the same thing as "mine" does. (obs: it's not my function)

@projectsalehx
Because, the sub-arrays/sub-strings are of equal size, your "array of arrays" can be easily expressed by the following 2-dimensional array. For unequal sizes of the sub-arrays, the jagged array (as you have declared) is the option.

//const char *savednumbers[10] = {"+1289203104190", "+1281483104190", "+1281489122810", "@1281489131041"};
const char savednumbers[4][15] =
{
  {"+1289203104190"},
  {"+1281483104190"},
  {"+1281489122810"},
  {"@1281489131041"}
};

Sketch to perform read/operation with EEPROM:

#include<EEPROM.h>
//const char *savednumbers[10] = {"+1289203104190", "+1281483104190", "+1281489122810", "@1281489131041"};
const char savednumbers[4][15] =
{
  {"+1289203104190"},
  {"+1281483104190"},
  {"+1281489122810"},
  {"@1281489131041"}
};

char readArray[4][15];

void setup()
{
  Serial.begin(9600);
  int addr = 0x0100;
  EEPROM.put(addr, savednumbers);
  
  EEPROM.get(addr, readArray);
  for (int i = 0; i < 4; i++)
  {
    Serial.println(readArray[i]);
  }
}

void loop() 
{

}

Read after Write:

+1289203104190
+1281483104190
+1281489122810
@1281489131041