big int to/from EEPROM

EEPROM.read/write is reading/writing only 1 byte.
Is there any easy way to read/write more then 1 byte?
What I'm looking for: to store array into EEPROM like this:
int MyArray[3][5]=
{
{1111,1112,1113,1114}
,{2111,2112,2113,2114}
,{31,32,33,34}
}

You could cast the name "MyArray" to a "char*" and write "sizeof (MyArray)" bytes.
Or you could use "EEPROMWriteAnything"

how to convert the value 2114 to char and back?

Or one of the functions below, see the avr-libc user manual at AVR Libc Home Page

• uint8_t eeprom_read_byte (const uint8_t __p) __ATTR_PURE__
• uint16_t eeprom_read_word (const uint16_t __p) __ATTR_PURE__
• uint32_t eeprom_read_dword (const uint32_t __p) __ATTR_PURE__
• float eeprom_read_float (const float __p) __ATTR_PURE__
• 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)

how to convert the value 2114 to char and back?

You should never need to.

"MyArray" is an "int" pointer.
By casting it to an "char" pointer, you're telling the compiler that you know what you're doing when you read and write "sizeof (MyArray)" bytes from and to EEPROM.
Just make sure that the actual array "MyArray" is in scope when you use "sizeof".

kapelan:
how to convert the value 2114 to char and back?

you can't. You can convert it to 2 chars though. After all, that's what an int is - 2 chars.

Once you realise that an int is 16 bits, and a char is 8 bits, and that you can slice those bits up it becomes obvious.

Using "and" (&) you can "mask" sections of the bits. Using shift left/right (<< / >>) you can slide the bits around.

So, your value of 2114 is represented in binary as:

0000100001000010

If you mask just the lower 8 bits using "& 0xFF" you get:

0000100001000010 & 0000000011111111 = 0000000001000010

Which is 0x42 (66 in decimal).

Using right shift 8 times on your value you get:

0000100001000010 >> 8 = 0000000000001000

Which is 0x08 (8 in decimal).

It simply shifts the bits 8 places to the right losing the ones that drop off the end.

To test that this is right we can take the two values and recombine them. Mathematically it is:

256 * 8 + 66 = 2114.

  • is a heavy operation, but we can do the opposite operations as before, which is much more microcontroller friendly. OR (|) is the opposite of AND, and << is the opposite of >>

So, the 8 we << by 8, and we then OR in the 66:

8 << 8 | 66 = 2114

So, to sum up:

unsigned char b1, b2;
int value = 2114;

b1 = value & 0xFF;
b2 = value >> 8;

...

value = (b2 << 8) | b1;

There is no reason why you can't write a series of bytes to EEPROM and then put them in an array when you read them back.
Wrap the writing and reading in functions and call them when you need to and it's just like having a native function to do the same thing.

wow, that is not an easy way :wink:

this code splits the value 2114 to to bytes, right?:

unsigned char b1, b2;
int value = 2114;

b1 = value & 0xFF;
b2 = value >> 8;

Then these 2 bytes can be stored to EEPROM?:

EEPROM.write(1,b1);
EEPROM.write(2,b2);

Reading from EEPROM?:

b1= EEPROM.read(1);
b2= EEPROM.read(2);

// and result:

value = (b2 << 8) | b1;

is that right?

that seems equivalent:
http://www.nongnu.org/avr-libc/user-manual/group__avr__eeprom.html#gabeef2e14398b47268f88462b3d7738dc

uint16_t eeprom_read_word ( const uint16_t * __p )
Read one 16-bit word (little endian) from EEPROM address __p.

eeprom_read_word always read 2 bytes, is it correct?

kapelan:
that seems equivalent:
avr-libc: <avr/eeprom.h>: EEPROM handling

uint16_t eeprom_read_word ( const uint16_t * __p )
Read one 16-bit word (little endian) from EEPROM address __p.

eeprom_read_word always read 2 bytes, is it correct?

Correct.

23.14.3.5 uint16_t eeprom_read_word ( const uint16_t  p )
Read one 16-bit word (little endian) from EEPROM address __p.

UKHeliBob:
There is no reason why you can't write a series of bytes to EEPROM and then put them in an array when you read them back.
Wrap the writing and reading in functions and call them when you need to and it's just like having a native function to do the same thing.

I do not know the size if it is 1 byte value or 2 bytes.
So to do this from the code: always 2 bytes have to be stored into EEPROM for each element of array.
It looks like this function is doing it: uint16_t eeprom_read_word
So, no reason to create a custom function if it exists from a standard library
Will need this function and a custom function to populate this array from EEPROM.

Big thanks to everybody

For the 8-bit AVRs, an int is the same as a word, two bytes. Also uint16_t and int16_t are different names for unsigned int and int.