Josh_Blackburn:
Correct, I don't really understand the code I'm using, I just know it works. I did not write the code myself.
I'm not sure what that line is doing, I'll try to remove it and see what happens.
I think I understand what youre saying. So I would add the other byes like this?
Wire.write(byte1)
Wire.write(byte2)
...
Wire.write(byte64)
Wire.end transmission
I'll try that and see what happens.
Thanks for the tip.
You need to understand what an EEPROM Write Page is, and the Arduino Wire.h library limitations.
An EEPROM can be though of as an array of memory cells in a X * Y array where the Write page is the width of the 'X' dimension. The chip contains a Write buffer that is the same size the Write Page.
The hardware in the chip always writes ONE complete page at a time. When you write a byte to the EEPROM three sequences happen:
- First, you tell the EEPROM where the write starts (the 16bit address).
This causes the EEPROM to decode your address into two parts, first the Page address, second the offset within that page where your changes start.
Then it copies the current content of that decoded page from it's EEPROM array into the Write buffer.
- Second, you send the individual bytes, which the chip then overwrites into the Page buffer. After each byte is stored in the buffer the chip's internal buffer offset counter is incremented. If this counter exceeds the maximum offset value (Write page Size), the offset is counter is set to zero (0). The next byte you send then overwrite the 0'th byte of the page. (It does NOT increment to the next higher address, on the NEXT page.)
- When you issue the Wire.endTransmission(); call the chip then copies the current content of the Write buffer into the EEPROM array.
So, the maximum number of bytes that can be stored in a single I2C transaction is equivalent to the lessor of two limits, first, the Write page size, or the Maximum Arduino Wire transaction size (32bytes, Except the two address byte count against the Arduino limit). A standard Wire.h write transaction is limited to 30 data bytes.
If your I2C chip has a 64byte Write page this means that if you try to write 10 bytes of data starting at address 60, you will actually change bytes, 60..63, 0..5.
If you try the same write sequence at address 120, you will actually change 120..127, 64..67.
This is my code for isolating the Write page issues from raw block writes.
bool writeI2CBin(const uint8_t id,uint16_t adr, char data[],const uint16_t len,const uint8_t pageSize){
// Have to handle write page wrapping,
// 24lc512 has 128 byte
// 24lc64 has 32 byte
/*
Serial.print("writeBin(0x");
Serial.print(id,HEX);
Serial.print(",0x");
Serial.print(adr,HEX);
Serial.print(",len=");
Serial.println(len,DEC);
*/
uint16_t bk = len;
bool abort=false;
uint8_t i;
uint16_t j=0;
uint32_t timeout;
uint16_t mask = pageSize-1;
while((bk>0)&&!abort){
i =30; // maximum data bytes that Wire.h can send in one transaction
if(i>bk) i=bk; // data block is bigger than Wire.h can handle in one transaction
if(((adr)&~mask)!=((((adr)+i)-1)&~mask)){ // over page! block would wrap around page
i = (((adr)|mask)-(adr))+1; // shrink the block until it stops at the end of the current page
// Serial.print("adjust i =");
// Serial.println(i,DEC);
}
//wait for the EEPROM device to complete a prior write, or 10ms
timeout = millis();
bool ready=false;
while(!ready&&(millis()-timeout<10)){
Wire.beginTransmission((uint8_t)id);
ready=(Wire.endTransmission(true)==0); // wait for device to become ready!
}
if(!ready){ // chip either does not exist, is hung, or died
abort=true;
Serial.print(id,HEX);
Serial.println(F(" chip timeout"));
break;
}
// Serial.print("adr=");Serial.print(*adr,HEX);
// Serial.print(":");
// start sending this current block
Wire.beginTransmission((uint8_t)id);
Wire.write((uint8_t)highByte(adr));
Wire.write((uint8_t)lowByte(adr));
bk = bk -i;
adr = (adr) + i;
while(i>0){
// Serial.print(" ");
// Serial.print((uint8_t)data[j],HEX);
Wire.write((uint8_t)data[j++]);
i--;
}
uint8_t err=Wire.endTransmission();
if(err!=0){
Serial.print(F("write Failure="));
Serial.println(err,DEC);
abort = true;
break;
}
// else Serial.println();
}
return !abort;
}
Chuck.