ESP32 Preserving EEPROM for as long as possible

KeithWalker

Joined Jul 10, 2017
3,063
You are always writing the same number of bytes on every reset. On restart, read the eprom, 12 bytes at a time. When you find no more data, save a pointer in ram to that position. The last data before that is valid. On reset, save the 12 bytes, starting at the pointer.
When the pointer indicates that the eprom is almost full, erase all the data and start again.
 

ericgibbs

Joined Jan 29, 2010
18,766
hi z,
You could implement the option I suggested in post #5, by using the double Reset method described in post #35.

ie: when the reset counter is full, just move the counters address.
To initialise the start at say address 00, use the double reset
E
 

Thread Starter

zazas321

Joined Nov 29, 2015
936
You are always writing the same number of bytes on every reset. On restart, read the eprom, 12 bytes at a time. When you find no more data, save a pointer in ram to that position. The last data before that is valid. On reset, save the 12 bytes, starting at the pointer.
When the pointer indicates that the eprom is almost full, erase all the data and start again.
After a reset, how will I know what address is the starting address ? Since I saved it in RAM, and after reset I lost that information. So lets say I write 12 bytes before reset. After the reset, I should start from Address 13 since 12 bytes were already occupied from the previous write. I still cannot understand how do I keep track on the last written address. I cannot save it in RAM because that information will be lost upon the reset. How can my program know whether I should start from address 13, 26, 39 or etc.. I must keep track of write cycles I have done. And the only way I see doing that is to save write cycles counter to reserved place in EEPROM but I dont want to do that since its going to wear down that part of EEPROM much faster.
 
Last edited:

Thread Starter

zazas321

Joined Nov 29, 2015
936
hi z,
You could implement the option I suggested in post #5, by using the double Reset method described in post #35.

ie: when the reset counter is full, just move the counters address.
To initialise the start at say address 00, use the double reset
E
I have checked that video. He always write to EEPROM address 0 so surely he is going to wear that part of EEPROM much faster that any other address.
 

djsfantasi

Joined Apr 11, 2010
9,156
After a reset, how will I know what address is the starting address ? Since I saved it in RAM, and after reset I lost that information. So lets say I write 12 bytes before reset. After the reset, I should start from Address 13 since 12 bytes were already occupied from the previous write. I still cannot understand how do I keep track on the last written address. I cannot save it in RAM because that information will be lost upon the reset. How can my program know whether I should start from address 13, 26, 39 or etc.. I must keep track of write cycles I have done. And the only way I see doing that is to save write cycles counter to reserved place in EEPROM but I dont want to do that since its going to wear down that part of EEPROM much faster.

You are always writing the same number of bytes on every reset. On restart, read the eprom, 12 bytes at a time. When you find no more data, save a pointer in ram to that position. The last data before that is valid. On reset, save the 12 bytes, starting at the pointer.
When the pointer indicates that the eprom is almost full, erase all the data and start again.
As Keith said, you find the last address written to by reading the EEPROM to find the next unused locations and backing up a few positions. Think of your original question: how do I save a value that survives a restart? By writing it to EEPROM. Then ask, how do I save the number of write cycles that survives a restart?
 

KeithWalker

Joined Jul 10, 2017
3,063
As Keith said, you find the last address written to by reading the EEPROM to find the next unused locations and backing up a few positions. Think of your original question: how do I save a value that survives a restart? By writing it to EEPROM. Then ask, how do I save the number of write cycles that survives a restart?
That is correct. I believe in the "KISS" principal. I answered the original question with the simplest solution that I could think of.
I am not a software guru. I just solve problems.
Regards,
Keith
 

MrSalts

Joined Apr 2, 2020
2,767
Because whole pages are written at a time by default, In a given page of memory, you can organize it to write the first two bytes as a write counter (0-65000). Then write your interesting few dozen bytes on the rest of the page. When your write counting bytes exceed your safe number of bytes, you can move onto the next page. You can find which page is the correct page on restart, read pages lowest to highest until you find one with less than your maximum safe number of writes snd write to that one (or read from that one.

Once you start writing in a page, there is no reason to write to different registers in the page since all registers get written to the same number of times during a page write operation.

For an added security/self check, you can write twice on the same page if you have very few bytes to save. Then make sure they match so you can identify errors. Or do it three times and make sure at least two match when you need to read them and move on to the next page if you are getting errors. You'll have to write the page count to multiple locations on a page to make sure you don't run into problems with the counter register.

You could even reserve page 0 to maintain an index of which page is your active page. You'll only need to write to that page when you change your active page.

Memory lasts a lot longer than you'd think if you use proper error checking and load leveling.
 

Thread Starter

zazas321

Joined Nov 29, 2015
936
That is correct. I believe in the "KISS" principal. I answered the original question with the simplest solution that I could think of.
I am not a software guru. I just solve problems.
Regards,
Keith
Ok I think I can now understand what you mean. By default, if cleared, all flash memory should read 0xff if empty. so I would just read the EEPROM in 12 byte chunks untill I find next 12 bytes that are 0XFF. If I find next 12 bytes to be 0xFF, I would return 12bytes back and should be able to read back the previously written information. Is my understanding correct?
 

KeithWalker

Joined Jul 10, 2017
3,063
Ok I think I can now understand what you mean. By default, if cleared, all flash memory should read 0xff if empty. so I would just read the EEPROM in 12 byte chunks untill I find next 12 bytes that are 0XFF. If I find next 12 bytes to be 0xFF, I would return 12bytes back and should be able to read back the previously written information. Is my understanding correct?
That's correct. Set a RAM pointer to the position where you find the null data because that is where you will save the new data on shut-down.
 

Thread Starter

zazas321

Joined Nov 29, 2015
936
I have implemented some simple test program as KeithWalker suggested. For those who are interested:

Code:
/*
   EEPROM Write

   Stores random values into the EEPROM.
   These values will stay in the EEPROM when the board is
   turned off and may be retrieved later by another sketch.
*/

#include "EEPROM.h"

// the current address in the EEPROM (i.e. which byte
// we're going to write to next)



#define EEPROM_SIZE 4080
char serial[10];
int eeprom_pointer=0;



void setup()
{
  Serial.begin(115200);
  Serial.println("start...");
  if (!EEPROM.begin(EEPROM_SIZE))
  {
    Serial.println("failed to initialise EEPROM"); delay(1000000);
  }

strcpy(serial,"12345678");

//clear_all_eeprom();
//read_12_byte_chunks();
//write_12_byte_chunks();

eeprom_pointer = read_12_byte_chunks();
write_12_byte_chunks(eeprom_pointer);
}

void loop()
{
  // need to divide by 4 because analog inputs range from

}



void write_12_byte_chunks(int eeprom_pointer){
  int new_eeprom_pointer = (eeprom_pointer*12) ;
  EEPROM.writeUShort(new_eeprom_pointer, 15); //This will wryte 2 byte number
  new_eeprom_pointer += sizeof(unsigned short);// increment addr by 2
  Serial.print("Quantity written=");
  Serial.println(15);
    
  EEPROM.writeString(new_eeprom_pointer, serial);// this will write 10 byte string
  new_eeprom_pointer += 10;
  Serial.print("Serial written=");
  Serial.println(serial);
  Serial.print("Last address=");
  Serial.println(new_eeprom_pointer);
  EEPROM.commit();

}


void clear_all_eeprom(){
  for(int i=0; i<EEPROM_SIZE;i++){
    EEPROM.write(i,0xFF);// writing 0xFF to all eeprom positions

  }
  EEPROM.commit();

}


int read_12_byte_chunks(){

  for(int j=0 ; j<=340 ; j++){
    Serial.print("NEXT CHUNK = ");
    Serial.println(j);
    int counter = 0;
    for(int i=0 ; i<12 ; i++){
      Serial.print("Value inside EEPROM ");
      Serial.print((j*12)+i);
      Serial.print(" = ");
      Serial.println(EEPROM.read((j*12)+i));
      if(EEPROM.read((j*12)+i) == 0xFF){
        Serial.println("0xFF Detected");
        counter++;
      }
    }
    if(counter >=12){ //The EEPROM chunk is empty
      Serial.print("Found an empty chunk of EEPROM=");
      Serial.println(j);
      return j;
    }

  }

}
The following code does not require any additional libraries so everyone with ESP32 device should be able to compile and run. I am simply reading EEPROM 12 byte chunks and looking for 0xFF match for all 12 bytes. If I find the match, I know which part of EEPROM is emtpy and can write to it.

I have declared EEPROM size as 4080. If I use 12 bytes, that would give me 340 chunks of 12 byte. If I am not mistaken, that would extend my EEPROM lifetime by 170times!
 
Last edited:

KeithWalker

Joined Jul 10, 2017
3,063
I have implemented some simple test program as KeithWalker suggested. For those who are interested:
Do you need to write 0xff to all locations after clearing the E=prom? Can you not use the error caused by reading a blank location to determine the position of the pointers? That would double life of the E-prom.
 

Thread Starter

zazas321

Joined Nov 29, 2015
936
Do you need to write 0xff to all locations after clearing the E=prom? Can you not use the error caused by reading a blank location to determine the position of the pointers? That would double life of the E-prom.
Can you clarify to me what you mean "after clearing the EEPROM" ? The EEPROM built in library does not have a function to clear EEPROM. I have to manually clear it by writing FF to all addresses.

I just cleared it once, and then I should never clear it unless it has reached the maximum address (4080).
 

KeithWalker

Joined Jul 10, 2017
3,063
Can you clarify to me what you mean "after clearing the EEPROM" ? The EEPROM built in library does not have a function to clear EEPROM. I have to manually clear it by writing FF to all addresses.

I just cleared it once, and then I should never clear it unless it has reached the maximum address (4080).
OK, I misunderstood . Yes, you have the life extended to the.maximum. I have not used E-proms for many years, and then, I was using 4 bit assembly language and clearing them with a UV lamp..
 
Last edited:

ericgibbs

Joined Jan 29, 2010
18,766
hi zazas,
Thanks for the code in post #51, problem is the version of ESP32 I have just started using is the WROOM 32D, it only has a few Bytes of EEPROM in the RTC.
I am currently developing a WiFi & Internet control projects.
Will order a couple of ESP32's, which version of the ESP32 dev board are you using.?
E
 

Thread Starter

zazas321

Joined Nov 29, 2015
936
hi zazas,
Thanks for the code in post #51, problem is the version of ESP32 I have just started using is the WROOM 32D, it only has a few Bytes of EEPROM in the RTC.
I am currently developing a WiFi & Internet control projects.
Will order a couple of ESP32's, which version of the ESP32 dev board are you using.?
E

I am using the ESP32 dev board that I have purchased from the digikey:
https://www.digikey.lt/product-detail/en/espressif-systems/ESP32-DEVKITC-32D/1965-1000-ND/9356990

Mine has 4MB of flash memory
 

ericgibbs

Joined Jan 29, 2010
18,766
hi zazas,
Did a little more checking and I have found that the ESP32 WROOM WD MPU modules I have are coded on the underside of the PCB as ESP32_Devkitc_V4.
Ran your test program OK and found that the module has 4095 EEPROM.

E
I think you will find this video of interest, I intend trying some of the described features.
 

Thread Starter

zazas321

Joined Nov 29, 2015
936
That is quite interesting what you can achieve by using 2 cores independantly. However , I believe it becomes very tricky when using ESP32 with wifi. I think one of the ESP32 cores are dedicated for the WIFI and handling everything while the other core is running user program.
 
Top