Reading and Writing Data Structures to EEPROM
In the Arduino library versions through 0013, the only way to read and write the built-in EEPROM memory was through functions that only support one byte of data at a time. When saving a number from 0-255, this is sufficient. When saving a larger number, you have to call the EEPROM routines more than once, to save a "high byte" and a "low byte" for 16-bit numbers, or even more often for bigger numbers or other data types that cannot fit in one byte.

With the following code, you can write any data structure or variable, using any number of bytes of EEPROM to do it (of course, only as many bytes as your chip holds), all in a single call.

A common use of this would be to have a group of related "persistent" variables that you want to save for future sessions. This could be a high-score list in a game, or a set of configuration choices in a device like an alarm clock.

Note: as of version 22, templates must be in a separate header file.


put this in a file named "EEPROMAnything.h":

#include <EEPROM.h>
#include <Arduino.h>  // for type definitions

template <class T> int EEPROM_writeAnything(int ee, const T& value)
{
    const byte* p = (const byte*)(const void*)&value;
    unsigned int i;
    for (i = 0; i < sizeof(value); i++)
          EEPROM.write(ee++, *p++);
    return i;
}

template <class T> int EEPROM_readAnything(int ee, T& value)
{
    byte* p = (byte*)(void*)&value;
    unsigned int i;
    for (i = 0; i < sizeof(value); i++)
          *p++ = EEPROM.read(ee++);
    return i;
}


Once your sketch has these two functions defined, you can now save and load whole arrays or structures of variables in a single call. You provide the first EEPROM address to be written, and the functions return how many bytes were transferred.


#include <EEPROM.h>
#include "EEPROMAnything.h"

struct config_t
{
    long alarm;
    int mode;
} configuration;

void setup()
{
    EEPROM_readAnything(0, configuration);
    // ...
}
void loop()
{
    // let the user adjust their alarm settings
    // let the user adjust their mode settings
    // ...

    // if they push the "Save" button, save their configuration
    if (digitalRead(13) == HIGH)
        EEPROM_writeAnything(0, configuration);
}


This facility is being offered on the Playground for versions up to 0013 of the Arduino IDE. It will be proposed for built-in support in a future release like 0014. (this apparently did not happen)


If you don't want to bother with a separate header file, you can use the avr eeprom library instead:


#include <avr/eeprom.h>

struct settings_t
{
  long alarm;
  int mode;
} settings;

void setup()
{
  eeprom_read_block((void*)&settings, (void*)0, sizeof(settings));
    // ...
}
void loop()
{
    // let the user adjust their alarm settings
    // let the user adjust their mode settings
    // ...

    // if they push the "Save" button, save their configuration
    if (digitalRead(13) == HIGH)
      eeprom_write_block((const void*)&settings, (void*)0, sizeof(settings));
}

Share