Saving values in the firmware

I have an application that uses values entered through the console. How can I save the user entered values in the spark core such that they stay in the core even after it is turned off.

take a look at: http://docs.particle.io/core/firmware/#other-functions-eeprom

Thank you, very helpful

But it looks like it only takes byte values, how does one convert the value to a byte?

If you are using an uint8_t, you can save it directly as a byte, otherwise, you will need to split them up into bytes and save them accordingly.

Will write up an example when i have time :wink:

1 Like

Hi @thespark

What kind of values do you have? Float? Double? int? Let us know and we can show you how to convert.

2 Likes

So, you could take your value and bust it up into bytes with a bit-shifting method like this:

int myInt = -147789;
int eepromLocation = 22;


void setup() 
{
  Serial.begin(115200);
  //store int to EEPROM
  boolean didSave = saveIntToEEPROM(myInt, eepromLocation)
  if(didSave)
  {
    Serial.println("Success");
  }
  else
  {
    Serial.println("Failed");
  }
  //retrieve int from EEPROM
  int retrievedValue = retrieveFromEEPROM(eepromLocation);
  Serial.print("Retrieved from EEPROM an integer value of:")
  Serial.println(retreivedValue);
}

void loop() 
{
  
}

byte saveIntToEEPROM(int value, int location);
{
  if (location > 24)
  {
    Serial.println("failed to store EEPROM value");
    return 0;
  }
  else
  {
    char* successBuffer[60];
    sprintf(successBuffer, "Saving %d to EEPROM location %d", value, location);
    Serial.println(successBuffer);
    for (int i = 0; i < 4; i++)
    {
      EEPROM.write((4 * location + i, byte(value >> (8 * i)));// store four byte int in 4 locations of EEPROM starting in location*4   
   }
    return 1;
  }
  
}

int retrieveFromEEPROM(int location)
{
  int storedInteger = 0;
  for (int i = 0; i < 4; i++)
  {
    storedInteger |= (EEPROM.read((4*location + (3-i));
    if (i != 3) 
    {
      storedInteger = storedInteger << 8;
    }
  }
  char* messageBuffer[60];
  sprintf(messageBuffer, "retrieved:%d from EEPROM location:%d", storedInteger, location);
  Serial.println(messageBuffer);
  return storedInteger;
}

Since on a core there is 100 byte-sized loctions, I am using the limit of 25 locations, starting at zero and ending at 24 for the four byte int on a core. (not tested)

EDIT added retrieve from EEPROM function

@bko, I’m looking to store a few ints
@BulldogLowell, is there a reason why you are multiplying the memory location by 4, and what is the function of the successBuffer?

Hi @thespark

The reason for the times four is that an int is 4-bytes or 32-bits long on the Core (and Photon). The EEPROM storage is setup for 8-bit bytes and what @BulldogLowell code does is take the 4-byte integer and extract the bytes one at a time by shifting so the can be stored individually.

Let’s say the number you wanted to store was the integer 287454020 which has the convenient hex representation of 0x11223344 and using the code above, do you

saveIntToEEPROM(287454020, 10);

What happens is that location 10 in the call gets converted from an address for a 32-bit integer into a byte address by multiplying it by four so the first EEPROM location written will be byte location 40, then 41, etc. In the end the EEPROM looks like this:

Location  Value
   ...
40        0x44
41        0x33
42        0x22
43        0x11
  ...

When you read out the data the reverse happens.

2 Likes

we are just building a message to be 'printed' to your serial monitor so you can witness the event happening.

Thanks @bko! :ok_hand:

1 Like

Thanks guys, worked like a charm.

3 Likes

Hello,
The AVR library has recently evolved if I am not mistaken. The eeprom.h library now provides get() and put() functions that accept data types other than bytes (int, float and even struct).
Any chance to get an equivalent change on the Spark (Arduino compatible core library if I understood well)?
Thanks
Emmanuel

2 Likes

Yes, definitely!