RobTillaart / I2C_EEPROM

Library for I2C EEPROM - 24LC512, 24LC256, 24LC64/32/16/08/04/02/01.
MIT License
91 stars 20 forks source link

Add autodetection of size and i2c address #3

Closed aeakin1 closed 4 years ago

aeakin1 commented 4 years ago

First off, thank you for the library.

What I am trying to do is abstract the EEPROM size and i2c address from the end user by scanning the i2c bus and reading the EEPROM size in code prior to calling the library since both of those values are required to instantiate an object.

More Detail: There are 4 AT24cXX Chips on the market. Two of them are common:

They use different page sizes

These modules can be located on 1 of 8 addresses -

In code I can scan for the i2c address but I need the I2c address and Memory size to instantiate your library.

you currently have a getsize() function, but that seems redundant if we need to define or assume size ahead of time (chicken/egg problem).

Is there a way we can "automagically" detect size and location within your library and return those values?

Thanks!

RobTillaart commented 4 years ago

Yes, this is one of the more difficult things (did not spend time on it recently)

Which platform are you working with?

Did not analyze it but some quick ideas / thoughts

  1. extract the function int I2C_eeprom::determineSize() from the library (and all it needs) and make a standalone function of it. I think I can squeeze out some more performance

  2. you could assume always PAGE_SIZE of 32 as that will work on 64 byte pages too - although less efficient. Note that on an UNO the I2C buffer size is 30 so that is limiting paging anyway

  3. rewrite the library to do it for you. A determinePageSIze() function could be developed. DPS() would call deterineSize() and adjust the value set by the constructor or os. [never tried]

  4. If you need max performance you could consider using FRAM iso EEPROM. I have a lib for that too.

  5. Create a temporary object and call determineSize() and use that information to set the final object.

If performance allows I would start definitely with option 2 as that would be pretty easy and straightforward.

aeakin1 commented 4 years ago

Thanks!

The Platform is ESP32 and the use case is storing persistent counters, so not really a performance requirement as they are only updated every 30 seconds (in a round robin fashion so as not to wear out the EEPROM).

I will look into option 2 for now as I really only need to work with a single page at a time and there is no penalty to my implementation in doing this.

RobTillaart commented 4 years ago

Once every 30 seconds = ~3000x per day (assuming 24/7) EEPROM has about a million write cycles so yes same spot would give you 300 days

You could at least check if the counter has changed, before writing, as that would save you a write. If that occurs often the lifetime of the EEPROM is extended quite a bit.

In terms of write cycles, FRAM might be an easier choice as the datasheet states it has 10^10 RW cycles, that is a factor 10.000 more than EEPROM. Would allow you to write every second and still be able to write for 300 years...

aeakin1 commented 4 years ago

In order to avoid burning out the eeprom, I use a round robin algorithm to spread writes across the chip.

See here for a description of how I handle it. https://github.com/Photonsters/ESParaSite/wiki/ESParaSite--EEPROM-Format

Thanks for your help!

RobTillaart commented 4 years ago

you're welcome

Read it twice and looks like a good strategy.

some ideas