Writing values to EEPROM - The Basics

Hi, after reading the library examples i have to admit I’m a little confused about how to go about writing to EEPROM and then reading back the data correctly.

This is my requirement
I need to save three strings to EEPROM so they can be used later, following a power fail or reboot.

The 3 strings are
0x28, 0xAA, 0x6F, 0x3F, 0x48, 0x14, 0x01, 0xBC
0x28, 0xFF, 0xC1, 0x54, 0x90, 0x16, 0x05, 0x20
0x28, 0xFF, 0xD7, 0x29, 0xA4, 0x15, 0x03, 0x3D

which later get used as the HEX address for DS18B20 temperature sensors.
uint8_t sensor1adr[8] = { 0x28, 0xAA, 0x6F, 0x3F, 0x48, 0x14, 0x01, 0xBC }
uint8_t sensor2adr[8] = { 0x28, 0xFF, 0xC1, 0x54, 0x90, 0x16, 0x05, 0x20 }
uint8_t sensor3adr[8] = { 0x28, 0xFF, 0xD7, 0x29, 0xA4, 0x15, 0x03, 0x3D }

I can see the write would use EEPROM.update()
and the read EEPROM.read()
but the addressing and length parameters are not making sense.

  1. How do I write these three strings to EEPROM
  2. How to I then at program start up read the EEPROM so i can use them?

Your help is much appreciated.

here is an example that could come handy (just adapted a piece of code I had for your parameters)

#include <EEPROM.h>

struct __attribute__ ((packed)) _paramS {
  uint8_t sensor1addr[8];
  uint8_t sensor2addr[8];
  uint8_t sensor3addr[8];
} myParamters;

const uint8_t defaultSensor1addr[8] = { 0x28, 0xAA, 0x6F, 0x3F, 0x48, 0x14, 0x01, 0xBC };
const uint8_t defaultSensor2addr[8] = { 0x28, 0xFF, 0xC1, 0x54, 0x90, 0x16, 0x05, 0x20 };
const uint8_t defaultSensor3addr[8] = { 0x28, 0xFF, 0xD7, 0x29, 0xA4, 0x15, 0x03, 0x3D };

const uint32_t keyword = 0xDEADBEEF;
const uint16_t keywordAddress = 0x00;
const uint16_t paramAddress = keywordAddress + sizeof(keyword);

void printSensorAddress(const uint8_t* addr)
{
  for (byte i = 0; i < 8; i++) {
    Serial.print(F("0x"));
    if (addr[i] < 0x10) Serial.write('0');
    Serial.print(addr[i], HEX);
    Serial.write(' ');
  }
  Serial.println();
}

void printParam()
{
  Serial.println(F("\n************* PARAMS *************"));
  Serial.print(F("sensor1addr = ")); printSensorAddress(myParamters.sensor1addr);
  Serial.print(F("sensor2addr = ")); printSensorAddress(myParamters.sensor2addr);
  Serial.print(F("sensor3addr = ")); printSensorAddress(myParamters.sensor3addr);
}

void saveParam()
{
  EEPROM.put(keywordAddress, keyword);
  EEPROM.put(paramAddress, myParamters);
}

void getParam()
{
  uint32_t tmpKey;

  EEPROM.get(keywordAddress, tmpKey);
  if (tmpKey == keyword) {
    EEPROM.get(paramAddress, myParamters);    // EEPROM was already initialized OK to read
  } else {
    // First run on this arduino, memory was never initialized. so establish default values
    memcpy(myParamters.sensor1addr, defaultSensor1addr, 8);
    memcpy(myParamters.sensor2addr, defaultSensor2addr, 8);
    memcpy(myParamters.sensor3addr, defaultSensor3addr, 8);
    saveParam();
  }
}


void setup() {
  Serial.begin(115200);
  randomSeed(analogRead(A0));

  // load our params from EEPROM or assign defaults if EEPROM was never used
  getParam();
  printParam();
  
  // modify address1 first byte
  myParamters.sensor1addr[0] = random(0, 256);
  saveParam();
  
  // now check them out
  printParam();
}

void loop() {}

compile and launch with the Serial monitor opened at 115200 bauds

  • the first run should establish the default parameters, then the code modifies randomly the first byte of the first address and saves it again.

  • reboot the arduino, you should now no longer see the default parameters for the first address but see that the modified byte #1 as been kept. It’s then modified again

  • at each reboot you’ll get a new value for that 1st byte

the keyword is used to detect if the EEPROM of this arduino has already been initialized for your code. Use something specific. the first time you run the code, chances are that you won’t find those 4 bytes in EEPROM and so you know it’s the first use and you can establish the defaults. the following run you’ll find the keyword, so whatever is in EEPROM will get used

J-M-L, wow so much so fast, cheers
now so i understand the steps…(sorry so many questions)

Could you explain further the “keyword” and you say use something specific; do you mean i should change it from the example 0xDEADBEEF.

I see you have used EEPROM.put, why “put” and not “update”?

and have i got this right.
The first string in written to EEPROM address
0x00 + size of keyword;
what is the address of the second string?

What is the use of tmpKey?

the purpose of the keyword is to know if what is in EEPROM can be somewhat trusted to be your sensor addresses. it’s just bytes at the end of the day… So the code first checks if there is a known value in a known location of the EEPROM → I use tmpKey to extract whatever is at the location of the keyword and use it to compare its value with 0xDEADBEEF. If it finds this value, it assumes that the sensor addresses are correct. if it does not find the keyword, then the code initializes the sensor addresses with the default ones and write them in EEPROM for the next time.

you can keep 0xDEADBEEF if you want, but if you use the same technics on the same Arduino later for something else, then the code will believe the memory has already been initialized. So make up one code for each sketch.

the EEPROM.put() method writes data on EEPROM using the EEPROM.update()method. so it only writes the bytes that have changed but it’s smarter as it adapts to the type of the data you pass (here a structure, so I don’t have to deal with the individual bytes)

PS: on second thoughts it’s probably better to write

void saveParam()
{
  EEPROM.put(paramAddress, myParamters);
  EEPROM.put(keywordAddress, keyword);
}

so that the keyword is only written once the parameters have actually been written (in case of power failure right at that time)

ideally you would want to erase the keyword before an update — just in case the updates fails in the middle — and write it back again at the end… or use a smarter approach with 2 areas to update the parameters…

but as a start that’s good enough :slight_smile:

1 Like

Brilliant, Thank you.
I will give it a go and come back if i run into problems

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.