Go Down

Topic: Extending EEPROM life (Read 648 times) previous topic - next topic

CyberOddity

I'm working on some software using an UNO (atmega328p). I have a stage byte that can be 1 of 5 values (0-4) in my code and it will increase by 1 every 2.5 hours. If I lose power I need to ensure that on wake up the stage is the same as it was at the time of power loss, so each time the stage is updated I save it to EEPROM.

To ensure the EEPROM lasts as long as possible I want to write some code that uses more than a single byte which I continually erase and write to. I was wondering if there is any library to do this or if my idea below would work?

I currently don't need to use the EEPROM for anything else so to extend the EEPROM life I was going to section of 1 quarter of it (0-255 bytes) for saving this value. Each time I change the stage I will write 3 bytes to EEPROM which will be,

 - An index byte (used to shift addresses I write to)
 - A stage byte (the stage I need to store)
 - A count byte (the amount of times I have wrote the stage at the current index)

To begin with the index will be written to byte 0 in the EEPROM, the stage to byte 1 and the count to byte 2. 

My plan is to allow the stage to be written to byte 1 250 times, then clear the count and shift the index to 3. This will in turn move the bytes that the stage and count are being written to to 4 and 5. I will do this until the index reaches the end of the 255 bytes and then return the index to 0. So in total I should be able to shift 85 times.

Each byte has 100,000 erase/write cycles so this means I can pass through bytes 0-255 400 times, writing the stage 250 times each pass. So instead of having 100K writes I would have about 8.5 million writes.   
 
This is my first Idea and I realize there is also some waste in the way I do it. I haven't worked with EEPROM much and I was just hoping for some advice as I'm sure I could be going at this completely wrong.   


DrAzzy

So you're writing it once every 2.5 hours?

If you used a single byte, and rewrote it every time, that would mean 250,000 hours.

At approx 25 hrs per day, that's 10,000 days, or 30 years. So I feel like you may be solving a problem that doesn't exist.
ATtiny core for 841+1634+828 and x313/x4/x5/x61/x7/x8 series Board Manager:
http://drazzy.com/package_drazzy.com_index.json
ATtiny breakouts (some assembled), mosfets and awesome prototyping board in my store http://tindie.com/stores/DrAzzy

septillion

#2
Jan 17, 2018, 04:49 pm Last Edit: Jan 17, 2018, 04:49 pm by septillion
Why not increase the bytes one by one and check which address you needed to update?

For example, you have 5 EEPROM bytes:
20  20  19  19 19
Next to increase is the third (address 2) so you know the setting now. Next update you make it
20  20  20  19  19
to index to 4 etc.

This way you only change 1 byte at a time. Aka you have 100k5 = 10 yotta cycles = 2,85 zetta years :D

But indeed, with a single byte you already have 30 year.
Use fricking code tags!!!!
I want x => I would like x, I need help => I would like help, Need fast => Go and pay someone to do the job...

NEW Library to make fading leds a piece of cake
https://github.com/septillion-git/FadeLed

pert

Also posted at:
https://arduino.stackexchange.com/q/48872
If you're going to do that then please be considerate enough to add links to the other places you cross posted. This will let us avoid wasting time due to duplicate effort and also help others who have the same questions and find your post to discover all the relevant information. When you post links please always use the chain links icon on the toolbar to make them clickable.

lastchancename

#4
Jan 17, 2018, 11:04 pm Last Edit: Jan 17, 2018, 11:04 pm by lastchancename
If you can afford an analog input pin, check the supply voltage before the regulator, and save the eeprom when you see it going down (or any other time you want).

This way, if you only save the eeprom when power is crashing or other time for 'maintenance' or critical event... the eeprom will live longer than your children,
When posting - use the toolbar and read the stickies if you're not sure!  </code> tags are our friend!
You can lead a plug to an outlet, but you can't make them turn it on.

ard_newbie

This might help you, however (as stated in reply #1) IMO I don't see the interest:

http://www.digikey.kr/en/pdf/a/atmel/avr101-high-endurance-eeprom-storage

krupski

To ensure the EEPROM lasts as long as possible.......
As DrAzzy said, the eeprom will last a lot longer than you could ever need.

BUT, if you insist, then how about this idea?

First, initialize all of eeprom to 0xFF (i.e. all erased). Then, have your code (when running properly and saving restart points) do this (pseudo code):

S = eeprom_size (2048, 4096, whatever your board has)
for (x = 0; x < S; x++) {
   if eeprom_read == 0xFF {
       break;
   }
}
now, X has the address of the first unused location
eeprom_write (X, your_data);

To recover from a crash, do the same thing (find the first unused eeprom location) then back up one and grab that data (which is the last valid one you saved).

Hope this helps.

Gentlemen may prefer Blondes, but Real Men prefer Redheads!

PaulS

So you're writing it once every 2.5 hours?

If you used a single byte, and rewrote it every time, that would mean 250,000 hours.

At approx 25 hrs per day, that's 10,000 days, or 30 years. So I feel like you may be solving a problem that doesn't exist.
This makes an assumption that may not be true. The 100,000 write cycles is the manufactures guarantee regarding how many times you can write. Now, if I was making EEPROM chips, or anything else, and was going to guarantee that it would last for 100,000 cycles, I would make damned sure that it would last at least twice, and more likely 10 times that long before I guaranteed any number.

The EEPROM isn't really likely to up and die at 100,001 writes.

It is likely that your device will last 60 to 600 years, writing once every 2 and a half hours.
The art of getting good answers lies in asking good questions.

septillion

The AVR will not die when you power it with 5,6V (or 6,1V even) but for a good and stable design you're not going to take that bed. Same for write cycles, it will probably last at least 10 times as long but a good design doesn't take that risk and solves it.
Use fricking code tags!!!!
I want x => I would like x, I need help => I would like help, Need fast => Go and pay someone to do the job...

NEW Library to make fading leds a piece of cake
https://github.com/septillion-git/FadeLed

PaulS

Quote
but a good design doesn't take that risk and solves it.
No. A good design evaluates the risk, and decides whether there is a need to address a problem, or not. If the risk is that there is a one in a million chance that 1000 people will die, then the risk needs to be addressed. If the risk is that there is a one in a million chance that a flea will die, then the flea might have an opinion about whether or not you should mitigate that risk, but I don't expect you to.
The art of getting good answers lies in asking good questions.

septillion

True, but if he decides it should last the 30 year it's a must. And based on the assumptions he made in the first post I think that's the case.  But that is something completely different then you said in reply #7. That's just extending the spec to, yeahh, after 100k cycles the change is still small so you could say it's not "one in a million chance that 1000 people will die" but it's probably "one in ten million chance that 1000 people will die" and that might be fine.
Use fricking code tags!!!!
I want x => I would like x, I need help => I would like help, Need fast => Go and pay someone to do the job...

NEW Library to make fading leds a piece of cake
https://github.com/septillion-git/FadeLed

PaulS

True, but if he decides it should last the 30 year it's a must. And based on the assumptions he made in the first post I think that's the case.  But that is something completely different then you said in reply #7. That's just extending the spec to, yeahh, after 100k cycles the change is still small so you could say it's not "one in a million chance that 1000 people will die" but it's probably "one in ten million chance that 1000 people will die" and that might be fine.
If the Arduino is being used in a project where people might die, then it is the wrong hardware for the project, whether the chance is 1 in million or 1 in 10 million.

But, I understand your point. As you say, it's all about managing risk. My impression is that the risk of wearing out one cell in EEPROM, at the rate that OP is writing to it, in the amount of time that the project is likely to be used, is extremely small. Not very many projects running today are running the same way they were 30 years ago. Those that are are usually because it isn't worth the trouble to upgrade the process, because it isn't that important.
The art of getting good answers lies in asking good questions.

krupski

The AVR will not die when you power it with 5,6V (or 6,1V even) but for a good and stable design you're not going to take that bed. Same for write cycles, it will probably last at least 10 times as long but a good design doesn't take that risk and solves it.
A thing that I do..... whenever I write eeprom, I first get the value of OSCCAL, then set the register to zero, then write eeprom, then reset OSCCAL back to what it should be.

Since eeprom and flash writes are timed with the internal r/c oscillator, setting OSCCAL to zero "cooks" the memory a bit longer.

Don't know if this shortens the life of the cells, but I had good luck "overcooking" eeprom cells in Motorola 68HC11 parts...

Gentlemen may prefer Blondes, but Real Men prefer Redheads!

septillion

May I ask what the benefit of cooking the cells longer is? Is it like sous-vide? :D
Use fricking code tags!!!!
I want x => I would like x, I need help => I would like help, Need fast => Go and pay someone to do the job...

NEW Library to make fading leds a piece of cake
https://github.com/septillion-git/FadeLed

Coding Badly

To ensure the EEPROM lasts as long as possible I want to write some code...
Or, you could spend $6 then spend the time you save doing things that are much more interesting...

https://www.adafruit.com/product/1897

To ensure you know what you are up against: Reliably extended the life of non-volatile storage using wear leveling requires a two-phase commit (with a carefully crafted write order), two extra bytes for flags per record, two (or more) extra bytes for error detection per record, splitting erase from write, error detection (CRC), and N * (sizeof(record)+4) bytes of storage where N >= 3.  Anything less will have a hole that prevents either failure recovery, failure detection, or both.


Go Up