# Best way to store large data in eeprom

• Hi,
In my node (ATMega328p) I want to store a duration in seconde in Eeprom....
This duration can range from 0 to 86400 (1day :))
I think use the method :
void saveState(uint8_t pos, uint8_t value);
but uint8_t can only store value range from 0 to 255

So, I found 2 solutions :

• Cut the duration in 2 variables : 1 for minutes, 1 for seconds, and store them at 2 differents positions.
• Store in a uint32_t type and not use saveState method but use mySensor internal method : hwWriteConfigBlock(__buf, __pos, __length) with the correct param.

In your opinion, what is the best choice ? or perhaps an other solution ?

• Third option:

``````int duration = 4000;

saveState(0, (duration >> 8) & 0xff);
saveState(1, duration & 0xff);

``````

• @Tetnobic the first solution won't work. There are 1440 minutes in a day

I use the method suggested by hek when storing the highscore for my MySesnors-powered Tetris game (soon to be published), except that I use an unsigned int.

Using highByte(), lowByte() and word() might be more readable than the bit shifting though. Like this:

``````unsigned int duration = 4000;

saveState(0, highByte(duration));
saveState(1, lowByte(duration));

``````

• @hek thanks for your Nice 3d solution,
I do not usually use the bit shifting technique, I guess the max value is 8 * 2 bits : 65 535 ?

@mfalkvidd right 1440 minutes in a day... I am a goat... Thanks for the methods, I think I will use this...

• @Tetnobic correct, the max value for a 16-bit unsigned integer is 2^16-1 which is 65535. See https://www.arduino.cc/en/Reference/UnsignedInt for details.

• @mfalkvidd so not enough to store 1 day (86400s) , can I do same things with int32 ?

• @Tetnobic true, nice catch

32 bits (unsigned long) would work. You'd have to use bit shift though, I don't think there are equivalents for high/lowByte and word.

``````unsigned long duration = 4000;

saveState(0, (duration >> 24) & 0xff);
saveState(1, (duration >> 16) & 0xff);
saveState(2, (duration >> 8) & 0xff);
saveState(3, duration & 0xff);

``````

But your original idea with hwWriteConfigBlock would be easier to read I think.

• @mfalkvidd yes for this solution, I guess that hwWriteConfigBlock method access to the eeprom in one time, contrary to bit shifting technique that need 4 saveState so 4 access to the eeprom ?

• I try this :

``````#define EEPROM_SLEEP_DURATION_ADDRESS 0

uint32_t sleepDurationInS = 86399;

``````

but seems no work my node freeze at this method

• @Tetnobic that looks correct to me, but I am no c/c++ expert so pointers and casting is scary for me Hopefully someone with better skills can give some clarity.

The code in the security personalizer seems to use the same syntax.

• Length should be 4 not 32.

• @hek right sizeof uint32_t : 4

it works with :

``````#define EEPROM_SLEEP_DURATION_ADDRESS 0

uint32_t sleepDurationInS = 86399;

``````

• Just for info, I found others methods to save data in eeprom :
in <avr/eeprom.h> there is :

``````uint8_t 	eeprom_read_byte (const uint8_t *__p)
void 	eeprom_read_block (void *__dst, const void *__src, size_t __n)
void 	eeprom_write_byte (uint8_t *__p, uint8_t __value)
void 	eeprom_write_word (uint16_t *__p, uint16_t __value)
void 	eeprom_write_dword (uint32_t *__p, uint32_t __value)
void 	eeprom_write_float (float *__p, float __value)
void 	eeprom_write_block (const void *__src, void *__dst, size_t __n)
void 	eeprom_update_byte (uint8_t *__p, uint8_t __value)
void 	eeprom_update_word (uint16_t *__p, uint16_t __value)
void 	eeprom_update_dword (uint32_t *__p, uint32_t __value)
void 	eeprom_update_float (float *__p, float __value)
void 	eeprom_update_block (const void *__src, void *__dst, size_t __n)
``````

It is to these methods that the aliases are made in the file MyHwATMega328.h

``````#define hwReadConfig(__pos) eeprom_read_byte((uint8_t*)(__pos))
#define hwWriteConfig(__pos, __val) eeprom_update_byte((uint8_t*)(__pos), (__val))
#define hwWriteConfigBlock(__buf, __pos, __length) eeprom_update_block((void*)(__buf), (void*)(__pos), (__length))
``````

• @Tetnobic the hw* functions is a way to abstract the underlying hardware. Many MySensors fans use non-avr hardware, for example ESP8266.

You can of course choose to optimize for a single platform in your own sketches, but we strive to make the MySensors example sketches available for as many platforms as possible.

9

6

10

1

1

3