Having a hard time saving struct[] to EEPROM

Hi all, I am having a hard time saving a struct array into the EEPROM.

my code looks like this:

//EEPROM address
int addr = 0;

struct values{
  int side;
  int pitch;
  int roll;
} storedValues[6];

//populates data in structs. actual code takes data from events from a particle function.
for(int i = 0; i < 6; i++){
  storedValues[i].side = i;
  storedValues[i].pitch = i*2;
  storedValues[i].roll = i*3;
}

//saves to EEPROM 
EEPROM.put(addr, storedValues);

//grabs values from the EEPROM and prints them out. 
for(int i = 0; i < 6; i++){
  int _side = EEPROM.get(addr, storedValues[i].side);
  int _pitch = EEPROM.get(addr, storedValues[i].pitch);
  int _roll = EEPROM.get(addr, storedValues[i].roll);
  Serial.print(_side);
  Serial.print(", ");
  Serial.print(_pitch);
  Serial.print(", ");
  Serial.println(_roll);
}

The actual array of structs seems to be set up correctly, however when I try to read the values from the EEPROM, I get identical pairs values that dont seem to correspond with anything. Ive tried to set up an anonymous union, but that yields the same result.
Any ideas?

Welcome to the Particle Community.

What you have posted would not compile since there is no setup() nor loop().

When you define the struct as an array of 6 struct objects you are reserving that space in RAM. It is only when you call EEPROM.put(addr, storedValues); that you write the 6 struct objects to EEPROM starting at address 0.

When you read or get from the EEPROM with EEPORM.get() you want to get the whole array of 6 struct objects into RAM and then read from there.

Another approach would be to use Retained RAM in which case you could just define your struct object array as Retained values storedValues[6]; So long as VBat pin is powered with 3.3V then the RAM will be retained even if Vin is 0V.

3 Likes

You can do that like so

  EEPROM.get(addr, storedValues);
  for (int i=0; i < 6; i++) 
    Serial.printlnf("%d: %d, %d, %d", i, storedValues[i].side, storedValues[i].pitch, storedValues[i].roll);

when only looking for a particular set in the array, you'd do it like this

  values valueSet;
  EEPROM.get(addr + i*sizeof(values), valueSet);
  Serial.printlnf("%d: %d, %d, %d", i, valueSet.side, valueSet.pitch, valueSet.roll);

and if you really only want a particular field you could do it like this

  int _pitch;
  EEPROM.get(addr + i*sizeof(values) + offsetof(values, pitch), _pitch);
  Serial.printlnf("pitch (%d): %d, i, _pitch);
4 Likes

@armor yeah I didn’t paste the setup or loop in this thread as the whole app itself is more complicated, just added the code which is conceptually at question.
But wow, this makes a lot more sense now. I’ve never worked with addresses and this totally clarifies it. Thanks so much @armor and @ScruffR !

1 Like