Go Down

Topic: EEPROM_writeAnything - slightly improved (Read 1 time) previous topic - next topic

mooney

Hi,

just like to share a slightly improvement to EEPROM_writeAnything. Lets assume you're using a struct to store your data to the EEPROM, for instance:

Code: [Select]

struct config_t
{
  unsigned int param1;
  unsigned int param2;
  unsigned int param3;
  int sockets[63];
} cfg;


The obvious drawback of the original EEPROM_writeAnything lies in always writing out the whole data to the EEPROM, regardless of the actual changed data. So here's my simple (but effective) solution:

Code: [Select]

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

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


The function reads and compares each byte, writing only different data to the EEPROM. This will drasticially improve write performance with bigger data structures, and increases the overall lifetime of the EEPROM. ;-)

Cheers,
-- Bastian

RuggedCircuits

That is a nice idea, though have you noticed any increase in size of code or RAM usage because of the template usage? Would it not be simpler (trying to avoid templates here) to just pass a "const void *" to EEPROM_writeAnything?

--
The Ruggeduino: compatible with Arduino UNO, 24V operation, all I/O's fused and protected

mooney

#2
May 29, 2011, 07:16 pm Last Edit: May 29, 2011, 09:02 pm by mooney Reason: 1
Interesting point, I'll check that. Just copied the code from the playground: http://www.arduino.cc/playground/Code/EEPROMWriteAnything. Using templates seems a bit overkill to me as well.

mooney

Made a quick test, first using templates:

Code: [Select]

template <class T> int EEPROM_writeAnything(int ee, const T& value)
{
    (...)
}

Binary sketch size: 15528 bytes
Available RAM: 438 bytes

...next without:

Code: [Select]

int EEPROM_writeAnything(int ee, const config_t& value)
{
    (...)
}

Binary sketch size: 15682 bytes
Available RAM: 438 bytes

Surprisingly, using templates saves me 154 bytes, the RAM doesn't seem to be affected at all...

RuggedCircuits

Cool! Yay for GCC.

Personally I would still prefer a "const void *" version ensuring that only 1 instance of the code is ever instantiated. I'd be worried with the template version that if you try to use the functions with more than one type it will insert the code twice.

--
The Flexible MIDI Shield: MIDI IN/OUT, stacking headers, your choice of I/O pins

Go Up