Pages: [1]   Go Down
Author Topic: I2C EEPROM Class on playground  (Read 4328 times)
0 Members and 1 Guest are viewing this topic.
Global Moderator
Netherlands
Offline Offline
Shannon Member
*****
Karma: 168
Posts: 12430
In theory there is no difference between theory and practice, however in practice there are many...
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset


While experimenting with an I2C EEPROM I encountered the problem that the Wire library only wrote in (relative) small chunks to EEPROM so I wrote a simple library to write and read objects of "any" size to an I2C EEPROM. The EEPROM used was a 24LC256 but it should work with other too (not confirmed).

The library and a small example can be found on - http://arduino.cc/playground/Main/LibraryForI2CEEPROM - and as allways remarks, comments and improvements are welcome.

Rob
Logged

Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

Global Moderator
Offline Offline
Brattain Member
*****
Karma: 452
Posts: 18694
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I just want to draw to your attention that the 24LC256 "wraps around" its internal addressing on 64-bytes boundaries. So for example, if you write 4 bytes to address 62, it actually ends up writing to 62, 63, 0 and 1.

So any code that attempts to write "large buffers" needs to address this, otherwise you need to add a warning that not only can it simply not write more than 64 bytes at a time, it has to not cross a 64-byte boundary. So in my example, even writing 3 bytes to address 62 would not work as expected.

I should also point out that your test program writes 102 bytes to the chip, and then reads it back into a 100-byte array - so that is going to overwrite memory somewhere.

In principle the library is a great idea, you just need to handle the wrapping issue.
Logged

Global Moderator
Netherlands
Offline Offline
Shannon Member
*****
Karma: 168
Posts: 12430
In theory there is no difference between theory and practice, however in practice there are many...
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi Nick,

thanks for this insight, I will dive into it and come asap with an updated version. I understand that in my sample code I started at address 0 with chuncks of 16 which is a divider of 64 so it worked by accident.

Do you know if other EEPROMS have similar issues?

wrt the test program, it only reads 40 bytes from memory into the 100 byte buffer, but its a risk youre right.
« Last Edit: February 11, 2011, 03:28:46 am by robtillaart » Logged

Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

Global Moderator
Netherlands
Offline Offline
Shannon Member
*****
Karma: 168
Posts: 12430
In theory there is no difference between theory and practice, however in practice there are many...
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Updated the code to be 1.0 compatible (Thanks Craig)

See - http://playground.arduino.cc//Main/LibraryForI2CEEPROM - for the latest version,

As always comments and improvements are welcome,
Logged

Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

Global Moderator
Netherlands
Offline Offline
Shannon Member
*****
Karma: 168
Posts: 12430
In theory there is no difference between theory and practice, however in practice there are many...
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Today I updated the I2CEEPROM class to version 1.0.04    See - http://playground.arduino.cc//Main/LibraryForI2CEEPROM - ,
or - https://github.com/RobTillaart/Arduino/tree/master/libraries/I2C_EEPROM -

I fixed some bugs and refactored the code. Most important the 1.0.04 version is on average substantial faster than the 1.0.00 version. This is done by optimizing internal buffer sizes to maximize the use of the TWI buffer, and by replacing the hardcoded 5 millisecs write latency after every write by a polling mechanism before a read or a write. The advantage is that the code will only wait for as long as needed and that will be less than 5 millis() quite often. This part can be simplified even further to get a smaller footprint, and to get the readByte() performance to previous level again but that is under test right now.

The performance numbers: (from the test sketch, UNO, IDE 1.5.4) - just as indication

400 KHZ I2C
reference 1.0.00
------------------
TEST: timing writeByte()     5164
TEST: timing writeBlock(50)  22120
TEST: timing readByte()      212
TEST: timing readBlock(50)   2476
total: 29972

1.0.04
------------------------------
TEST: timing writeByte()      220 
TEST: timing writeBlock(50)   8600 
TEST: timing readByte()      3768   // due to previous write!!
TEST: timing readBlock(50)   2252 
total: 14460

(delay(5) added between tests to simulate other code)
TEST: timing writeByte()      212
TEST: timing writeBlock(50)   5996
TEST: timing readByte()      264
TEST: timing readBlock(50)   2248
total: 8720


100 KHZ I2C
reference 1.0.00
-----------------
TEST: timing writeByte()     5452
TEST: timing writeBlock(50)  26348
TEST: timing readByte()      572
TEST: timing readBlock(50)   7020
total: 39402

optimized delay = 1.0.04
------------------------------
TEST: timing writeByte()   576
TEST: timing writeBlock(50)   12948
TEST: timing readByte()      4148
TEST: timing readBlock(50)   6360
total: 24032

(delay 5 added inbetween tests)
TEST: timing writeByte()   588
TEST: timing writeBlock(50)   10016
TEST: timing readByte()      712
TEST: timing readBlock(50)   6340
total: 17656


As always comments and remarks are welcome,
Logged

Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

Global Moderator
Netherlands
Offline Offline
Shannon Member
*****
Karma: 168
Posts: 12430
In theory there is no difference between theory and practice, however in practice there are many...
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Today I updated the I2CEEPROM class to version 1.0.05 on GITHUB
- https://github.com/RobTillaart/Arduino/tree/master/libraries/I2C_EEPROM -

+ 1.0.05
+ improved waitEEReady() -> on average far lower write latency than 1.0.00 reference.
+ added determineSize -> behind #ifdef to keep base lib small
+ improved comments
+ corrected return type readBlock()
+ updated test sketch

The determineSize() worked well for a 24LC256 (32KB) and a 24LC512 (64KB).
It is a non destructive test, that copies a number of memories and writes patterns to these locations to see address folding.

performance figures - note readByte() is on par with 1.0.00 version again.
Code: (400KHz)
reference 1.0.00
------------------
TEST: timing writeByte()     5164
TEST: timing writeBlock(50)  22120
TEST: timing readByte()      212
TEST: timing readBlock(50)   2476
total: 29972

 - 1.0.05
--------------------------------------
TEST: timing writeByte() 164
TEST: timing writeBlock(50) 8480
TEST: timing readByte() 3788  // delayed due to the previous write
TEST: timing readBlock(50) 2208
total: 14640 = 49%

(delay(5) between calls)
TEST: timing writeByte() 168
TEST: timing writeBlock(50) 5960
TEST: timing readByte() 216  // on par again
TEST: timing readBlock(50) 2140
total: 8484 = 28%

Code: (100KHz)
reference 1.0.00
-----------------
TEST: timing writeByte()     5452
TEST: timing writeBlock(50)  26348
TEST: timing readByte()      572
TEST: timing readBlock(50)   7020
total: 39402

- 1.0.05
--------------------------------------
TEST: timing writeByte() 444
TEST: timing writeBlock(50) 12832
TEST: timing readByte() 4160   // delayed due to the previous write
TEST: timing readBlock(50) 6096
total: 23530 = 60%

TEST: timing writeByte() 452
TEST: timing writeBlock(50) 9888
TEST: timing readByte() 576
TEST: timing readBlock(50) 6084
total: 17000 = 43%

[did not upgrade the playground yet]
« Last Edit: November 16, 2013, 12:24:06 pm by robtillaart » Logged

Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

Global Moderator
Netherlands
Offline Offline
Shannon Member
*****
Karma: 168
Posts: 12430
In theory there is no difference between theory and practice, however in practice there are many...
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

updated the playground to 1.0.05 - http://playground.arduino.cc//Main/LibraryForI2CEEPROM -
Logged

Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

Global Moderator
Netherlands
Offline Offline
Shannon Member
*****
Karma: 168
Posts: 12430
In theory there is no difference between theory and practice, however in practice there are many...
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

updated the playground to 1.1.00 on github
- https://github.com/RobTillaart/Arduino/tree/master/libraries/I2C_EEPROM -

Note: the playground is not updated yet (still 1.0.05)  - http://playground.arduino.cc//Main/LibraryForI2CEEPROM -
Logged

Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

Pages: [1]   Go Up
Jump to: