Use EEPROM simply

Hello together,

after I haven't found a simple wrapper class for the EEROM anywhere, I created a small class and want to share it. I intentionally didn't override the operators to keep the class as simple as possible and that you are aware EVERY time you assign a new value to the variable, because the EEPROM has a limited lifetime.

Settings.h:

#pragma once
#include <avr/eeprom.h>

template <typename T>
class Settings
{
private:
  const size_t _mem_addr;
  T _data;

public:
  Settings(size_t &mem_addr) : _mem_addr(mem_addr) { mem_addr += sizeof(T); }

  Settings(const size_t mem_addr) : _mem_addr(mem_addr) {}

  void restore() { eeprom_read_block((void *)reinterpret_cast<uint8_t *>(&_data), (const void *)_mem_addr, sizeof(T)); }

  void setValue(const T &value)
  {
    _data = value;
    eeprom_update_block((const void *)reinterpret_cast<const uint8_t *>(&value), (void *)_mem_addr, sizeof(T));
  };

  T getValue() const { return _data; };
};

example.cpp:

#include "Settings.h"
// #define USE_DEFAULT_VALUES

Settings<int> setting(0);

void setup()
{
  Serial.begin(9600);
#ifdef USE_DEFAULT_VALUES
  setting.setValue(5);
#else
  setting.restore();
#endif
}

void loop()
{
  Serial.print("Configvalue for Sensor: ");
  Serial.println(setting.getValue());
  delay(1000);
}

I would be happy about constructive criticism (please forgive me the define in the example :slight_smile: ).

int x = setting.getValue();

How is that easier than using EEPROM.get() ?

The point is that EEPROM.get() reads each time from the EEPROM and settings.getValue() returns only a variable. Furthermore, EEPROM.get() uses a for loop internally. This leads me to the conclusion that eeprom_read_block() is performing better.

Can you please post an example showing its use in a complete sketch that can be compiled and run ?

Sure, I've slightly revised my first post so that this one acts as an example (untested).

Is the sketch intended to print -1 once the Serial.begin() has been added, or should it be saving something to the EEPROM and loading it back ?

No, you can uncomment the line #define USE_DEFAULT_VALUES, upload the program, comment the line again and upload the program a second time. You should then see a 5.
(Sorry for forgetting Serial.begin(), as I said: untested)

Sorry to be picky, but I assume that #if USE_DEFAULT_VALUES should actually be #ifdef USE_DEFAULT_VALUES

So, how would this class be used to save and load an array of ints, for example

An array is basically only a pointer with a size. Therefore this is not possible. Maybe I can have a look later if there is something I can do. I have edited the code above. Thanks for the hint. As I said: untested.

Sorry to say, but code in tutorials should be tested before being published. Beginners should be able to run an example without unpleasant surprises.

1 Like