Write & read a struct to an i2c eeprom

Suriken:
I am using this library: GitHub - jlesech/Eeprom24C01_02: Arduino library for 24C01/02 serial EEPROM
It allows the user to write & read a single byte or an array.

In my project I need to use a struct to store all my data and searching on the forum I found a topic in which a user points here: http://www.arduino.cc/playground/Code/EEPROMWriteAnything

So I created an example code in which I try to use this 2 functions with the previous library but I did something wrong or I need to change something else because it is failing. Values I read from eeprom are not the ones I wrote before.

You might be running into a problem with your Device's WritePage size.

Depending on exactly which EEPROM you are using(brand and Model), For instance a MicroChip 24LC01B 128byte EEPROM. Which has a 8byte WritePage.

Any Single Write must fit within one of the 8 byte write pages:

Address: 0x00..0x07
Address: 0x08..0x0F
Address: 0x10..0x17
Address: 0x18..0x1F
Address: 0x20..0x27
Address: 0x28..0x2F
Address: 0x30..0x37
Address: 0x38..0x3F
Address: 0x40..0x47
Address: 0x48..0x4F
Address: 0x50..0x57
Address: 0x58..0x5F
Address: 0x60..0x67
Address: 0x68..0x6F
Address: 0x70..0x77
Address: 0x78..0x7F

If your structure is 10 bytes long and you use the WriteAnything() Template to save it at address 0x14.

char buffer[10] = "ABCDEFGHI"; // with appended null

What you expect the EEPROM to store:

EEPROM memory Map( as HexiDecimal Characters):

0x10: xx xx xx xx 41 42 43 44
0x18: 45 45 45 48 49 00 xx xx

What is actually Stored:

0x10: 45 46 47 48 49 00 43 44

The way an EEPROM works, is that it has to erase the memory cells before it can change them.

When you issue a Write command, you do send the address followed by the data.

Wire.beginTransaction(I2CChipAddress);
Wire.write((byte)address); // starting point were to store data
Wire.Write((byte)firstDataByte);
Wire.Write((byte)secondDataByte);
Wire.Write((byte)thirdDataByte);
//...
Wire.Write((byte)lastDataByte); // all of these Wire.write() commands actually just buffer the data
Wire.endTransaction(); // this command actually does all of the transmitting to the EEPROM.

The EEPROM takes the first byte of the write sequence, stores it as the 'address pointer',
Calculates which WritePage is going to be changed: Page=addressPoint / WritePageSize;
then copies this page from the EEPROM array into the WritePageBuffer.

then calculates the offset into the WritePageBuffer: offset= addressPointer | WritePageSize;

then it starts overwriting it's WritePageBuffer one byte at a time with the data it is receiving. If the offset pointer is incremented past the end of the WritePageBuffer, it restarts at the beginning of the buffer: offset=0;

After the last byte is received the Chip then Erases the Complete Page in the EEPROM array, then it writes the 'new' values from the WritePageBuffer.

So, to store data into an EEPROM you must break your data into pieces that fit on it's pages.

For my example:
Ten bytes of data, stored in addresses 0x14 through 0x1D. Two Write operations are required. because this address range occupies two of the 8byte Write pages.

char buffer[10] ="ABCDEFGHI"; // remember the terminating Null!

// now we must wait for the EEPROM chip to actually to complete any prior Write cycle

bool ready=false;
while(!ready){
  Wire.beginTransmission(I2CEEPROMAddress);
  ready = Wire.endTransmission()==0; // Chip answered!, prior Write Cycle has completed!
  }

Wire.beginTransmission(I2CEPPROMAddress);

Wire.write((byte)0x14); // starting address in EEPROM
for(byte i = 0; i<4; i++){
  Wire.write((byte)buffer[i]);
  }
Wire.endTransmission(); // send the first partial page of data

// now we must wait for the EEPROM chip to actually complete the Write cycle

bool ready=false;
while(!ready){
  Wire.beginTransmission(I2CEEPROMAddress);
  ready = Wire.endTransmission()==0; // Chip answered!, prior Write Cycle has completed!
  }

Wire.beginTransmission(I2CEPPROMAddress);

Wire.write((byte)0x18); // starting address of next page EEPROM
for(byte i = 4; i<10; i++){
  Wire.write((byte)buffer[i]);
  }
Wire.endTransmission(); // send the first partial page of data

As a note, Reading from the Chip is not limited to WritePageSize chunks, once you specify the starting address, the chip directly accesses the EEPROM array.

Chuck.