EEPROM write cycles?
I have a quick question. The write cycles specified for Arduino's EEPROM is 100.000. Does Industruino has a higher or lower spec? Also is there alternative way to store settings?
Thank you for the suggestion. Will definitely try it. I really love industruino. The only complain I have is lack of I/O. I recently purchased one Controllino Mega and one M-Duino with 58 I/Os for larger project. When will you release product with more I/O? I will definitely buy at least one. Also, it would be great if you integrate the FRAM on main unit instead of placing it on the expansion module. If you do so, I will buy at least two =P. Anyway, great product! I sincerely hope you release more product with more I/O in the future.
Hello, EEPROM lifetime is more or less the same for all types of chips I guess.
The main thing with EEPROM is to avoid writing when it's not needed, ie. when the data written in EEPROM is equal to the data your are writing. Usually in a set of data 90% of them is exactly the same.
That's why a function named update() is usually present in EEPROM libraries.
There's no limit in EEPROM reads, only in writes!
As I remember, this is not so in Arduino library, so I had to implement it in my software using an if() statement:
if( data2write != EEPROM.read() ) EEPROM.write(data2write);
This will make your EEPROM life longer.
Anyhow, if you really are planning massive datalogging of very different data, the solution is to mount the Ethernet add-on and use the SD card slot instead.
By the way, I have a standard method to write variables to EEPROM which is the same across all my projects and very efficient:
- first I prepare a struct where I write all my parameters
- then I make a union btw the struct and a byte array using sizeof(struct);
- then I just dump the byte array with a for() loop.
Beware only of this: you cannot init variables in the struct declaration.
I usually have a setDefault() routine with a list of my variables and their values.
Now for a bit of quick code:
struct par
{
//General
unsigned int checkSum; // rolling sum
char mType[8]; // machine type
char mSer[8]; //machine serial #//hardware
//Schedule
byte schedule1[168]; //Pump1 schedule
byte schedule2[168]; //Pump2 schedule//Network
char ip[20];
char ssid[20];
char pass[20];
};
//total ???union
{
par eP;
byte bP[sizeof(eP)];
} sP;
Then the only issue is to get the right variable name, ie. sP.eP.schedule1[x] or sP.bP[y].
Routines at this point are very easy to implement:
unsigned int sumCheck()
{
unsigned int sum=0;
for(int cS=2;cS<sizeof(sP.eP);cS++) sum+=sP.bP[cS];
Serial.print("Checksum ");
Serial.println(sum);
return sum;
}void saveEeprom()
{
Serial.println("Save Eeprom");
sP.eP.checkSum = sumCheck();
Serial.printf("Checksum = %u\n", sP.eP.checkSum);for(int cS=0;cS<sizeof(sP.eP);cS++)
{
if (sP.bP[cS] != EEPROM.read(cS)) EEPROM.write(cS, sP.bP[cS]);
}
EEPROM.commit();
Serial.println("EEPROM write OK");
}void defPar()
{
Serial.println("Default parameters");
Serial.printf("Checksum = %u\n", sP.eP.checkSum);String buf = hwType;
buf.toCharArray(sP.eP.mType,8); //machine type
buf = hwId;
buf.toCharArray(sP.eP.mSer,8); //machine serial #//default schedule = 30 seconds at midnight every day
for(int nS=0;nS<168;nS++)
{
if((nS % 24) == 0) sP.eP.schedule1[nS]=30;
else sP.eP.schedule1[nS]=0;
sP.eP.schedule2[nS] = sP.eP.schedule1[nS];
}sP.eP.ip[0] = '\0';
sP.eP.ssid[0] = '\0';
sP.eP.pass[0] = '\0';
saveEeprom();
Serial.println("Default loaded");
Serial.printf("Checksum = %u\n", sP.eP.checkSum);
}void loadEeprom()
{
Serial.println("Load Eeprom");
for(int cS=0;cS<sizeof(sP.eP);cS++) sP.bP[cS] = EEPROM.read(cS);
Serial.println();
Serial.printf("Checksum = %u\n", sP.eP.checkSum);
Serial.printf("sumCheck = %u\n", sumCheck());
if( ( sP.eP.checkSum == 0 ) || ( sP.eP.checkSum != sumCheck() ) ) defPar(); //on wrong checksum load default
Serial.println("EEPROM read OK");
Serial.printf("Checksum = %u\n\n", sP.eP.checkSum);
}
Very simple and always the same for any type of variables or project, you only need to avoid going over the EEPROM size.
I actually have a EEPROM.ino file which I copy directly into the project folder and adds all functions to my project.
The next step would be to build a library, but as soon as I solved my issue I have to move forward, so I never did. Maybe someone can take care of that and share the results!
You can also have more than one variable struct and write each variable at the end of the previous one as in:
for(cS=0;cS<sizeof(yourvar); cS++) EEPROM.write(sizeof(sP.eP)+cS, yourvar.bP[cS] );
The nice part is, when you change the structure of any var during development, checkSum won't match and the new structure will be automatically written in EEPROM, alas with default values.
Bravo as usual, Mr. Stefano. Thanks a lot for the information. This surely expand my knowledge on programming industruino.
Your answer
Please try to give a substantial answer. If you wanted to comment on the question or answer, just use the commenting tool. Please remember that you can always revise your answers - no need to answer the same question twice. Also, please don't forget to vote - it really helps to select the best questions and answers!
Keep Informed
About This Forum
This community is for professionals and enthusiasts of our products and services.
Read GuidelinesQuestion tools
Stats
Asked: 2/26/17, 1:41 AM |
Seen: 6307 times |
Last updated: 2/27/17, 7:01 AM |
Hi, As an alternative, if you have an application that requires very frequent storage of small values then you can use the FRAM memory (Ferroelectric RAM memory) found onboard the Ethernet expansion module. This memory has almost unlimitted write cycles and keeps its memory content during power-off (non-vollatile memory). It basically combines the advantages of RAM and EEPROM. Cheers, Loic