Can not change EEPROM values

I am using the following code to test writing and reading EEPROM. (Also tried all kinds of other simpler things …)

No matter what I write into eeprom, I always get the previously existing numbers back(=what ever was in there before)

What am I doing wrong?

thx
KW

String Version ="Version = 1";
#include "lib1.h"

void setup(){
        Serial.begin(9600);
        delay(2000);
        Serial.println(Version);
 }

void loop(){
    for(int i=0;i<5;i++){ 
        EEPROM.write(i,0);
        Serial.print("memory# ");
        Serial.print(i);
        delay(1001);
        Serial.print(" reading V=0 results in:");Serial.print(EEPROM.read(i));

        EEPROM.write(i,5);
        delay(1001);
        Serial.print(" reading V=5 results in:");Serial.print(EEPROM.read(i));

        delay(1001);
        Serial.println(" ");

    }    
}

results in

Version = 1
memory# 0 reading V=0 results in:1 reading V=5 results in:1 
memory# 1 reading V=0 results in:0 reading V=5 results in:0 
memory# 2 reading V=0 results in:1 reading V=5 results in:1 
memory# 3 reading V=0 results in:0 reading V=5 results in:0 
memory# 4 reading V=0 results in:0 reading V=5 results in:0 
memory# 0 reading V=0 results in:1 reading V=5 results in:1 
memory# 1 reading V=0 results in:0 reading V=5 results in:0 
memory# 2 reading V=0 results in:1 reading V=5 results in:1 
memory# 3 reading V=0 results in:0 reading V=5 results in:0

or even simpler:

#include "lib1.h"

String Version ="Version = 2";
void setup(){
        Serial.begin(9600);
        delay(2000);
        Serial.println(Version);
 }

void loop(){
        int addr = 55;
        uint8_t value ;
        uint8_t val = 0x45;
        EEPROM.write(addr, val);        
        delay(1001);
        value = EEPROM.read(addr);
        Serial.print("memory# "); Serial.print(addr);Serial.print(" reading V=");Serial.print(val);Serial.print(" results in:");Serial.println(value);
}

results in
memory# 55 reading V=69 results in:255
memory# 55 reading V=69 results in:255
memory# 55 reading V=69 results in:255

I made this library which seems to work for me although I cant see whats wrong with what you are doing.

https://github.com/Rockvole/indoor-air-quality-dashboard/tree/master/firmware/SimpleEeprom

even simpler:
``#include "lib1.h"
void setup(){ Serial.begin(9600); }

void loop(){
EEPROM.write(44, 5);
delay(1000);
Serial.print(" result of EEPROM.read:");Serial.println(EEPROM.read(44));
}
’’'
results in:
result of EEPROM.read:255
result of EEPROM.read:255
result of EEPROM.read:255
result of EEPROM.read:255

should show a 5,

tried values = 0 3 4; different addresses …
it worked once then I noticed that the values did not change anymore after I wrote.

have done a factory reset … don’t know what to do next
KW

I too have no idea why this does not work - it seems that it should.

So maybe give this a try on your Core, if this does not work, your Core’s might have a problem.

int i = 0;

void setup() {
    pinMode(D7, OUTPUT);
    digitalWrite(D7, HIGH);

    Serial.begin(115200);
    while (!Serial.available())
        Spark.process();
        
    digitalWrite(D7, LOW);
    
    i = EEPROM.read(0);
}

void loop() {
    EEPROM.write(0, i++);
    delay(1000);
    Serial.println(EEPROM.read(0));
}

This should count up and up and up, and on reset it should carry on from where it was before the reset.

output to serial is “1” no change…

I guess my core is broken…

@satishgn,

Any ideas on this? :smiley:

@ScruffR, @kennethlimcp, it seems that even though “i” is initialized to zero, it actually gets set by the EEPROM.read(0) in setup(). Since i is an integer, it could any value up to 255 from the read byte. Then, in loop(), EEPROM.write(0,i++) is writing an integer which could be greater than 255 converted to a byte for the write. I think it gets messy.

To be sure, I would declare i as a uint8_t, then initialize it to zero in setup(). That way you start with i=0 in loop(). There is also no range check in loop() to reset i when it exceeds its maximum value. An important thing to note is that on the Core, EEPROM is emulated using flash memory and there is a limited number of write cycles you can apply (10,000 I think). I you will be changing values often, you may consider @mdma’s Flashee-eeprom library. :smile:

1 Like

@peekay123, while it's true that i might exceed 255 after long running (200+ seconds), the low byte of this will still change with each iteration of loop and only the low byte will be written into EEPROM.
And with each reset i gets reset to some value that fits into one byte (the high bytes of iare initialized by int i = 0; anyway ;-))

To intialize with the EEPROM.read() value is intentional to show that the last value written and Serial.printed before the reset should be the first one to be printed on next start, ensuring that it actually goes in and comes from permanent mem.

Even an overflow won't hurt, i will just wrap round (2,147.483,647 -> -2,147.483,648 -> -1 -> 0 -> 1 -> ...).

But anyway it's probably best to change it into uint8_t, just to be on the safe side.

On the other hand, as I understand the docs, standard EEPROM implementation actually works against the STMs flash which should have 1.000,000+ (as I recall the STM datasheet) endurance compared to aprox. 10,000 on real EEPROM.

Edit: I recalled wrong :blush: the STM datasheet does actually state a min. number of possible write cycles 10K. Some sources even suggest, that EEPROM may have better endurance. But then the docs quote from above is somehow misleading and should be changed.

But as for @kw123 's problem, since this code does work on my Cores but does not seem to work on his - even after factory resets as I understand - I'd suspect some hardware issue.
But maybe try a couple more factory resets and then flash above code again.

If you read the first entries I tried to set many different cells to 0/1/2/3/4/5/6/7/8/9/10 , no change of the preexisting values.

it work initially and stopped working 3-4 days ago.

I was using it to save the modes of the pins and output values to set them after a reboot. All that worked fine and stopped working. Initially thought I did something wrong in the code and stripped it down to bare bones.

thanks

KW

I have read this, but since I don't think you may have exceeded the 1M+ write cycles in merely 4 days, and your code should work, there must be some other explanation
(or how frequently have you actually been writing to EEPROM?)

Maybe that allocation got somehow muddled up, which may well be a reason to call on @satishgn as @kennethlimcp suggested earlier.

Or there is some HW issue, after all.

I was reading in setup and writing if something had changed ~ may be 1000 times a day or so and ONLY 36 cells (1-7,10-17,20-27,30-37) I get the same result for all cells (tried # 60, 50,70…)

so what is the next step… throw it away and buy a new one?

thx

KW

No way, don’t throw it away - there might be some solutions popping up once the pros chime in :wink:

@kw123,
It could be either you have exceeded the maximum permitted write cycles by way of continuously executing EEPROM.write() in a loop in which case using EEPROM functions would be of no use for the core under test.
OR
you have accidentally write protected the concerned flash areas which is used by EEPROM functions. If this is the case, the following call in setup() will clear the write protection bits of pages 16 to 19 and restart the system to apply the same.

FLASH_WriteProtection_Disable(FLASH_WRProt_Pages16to19);

Please let me know if this solves your EEPROM issue.

Thanks!
Satish

2 Likes

Just for information:
I never touched cells#s 60++ and they show the same behavior. Does the max write apply to all cells if one goes bad?
thx
KW

FLASH_WriteProtection_Disable(FLASH_WRProt_Pages16to19);

void setup(){ Serial.begin(9600); 
delay(3000);
Serial.print(" starting v1");
 
 }
void loop(){
EEPROM.write(44, 5); 
delay(5000);
Serial.print(" result of EEPROM.read:");
Serial.println(EEPROM.read(44));
}

gives the following error in line 1:

from ../inc/application.h:29,
from tcpserver.cpp:2:
../../core-common-lib/SPARK_Firmware_Driver/inc/config.h:12:2: warning: #warning "Defaulting to Release Build" [-Wcpp]
#warning "Defaulting to Release Build"
^
tcpserver.cpp:1:30: error: expected constructor, destructor, or type conversion before '(' token

^
make: *** [tcpserver.o] Error 1

Satish probably meant to put the call inside (!) the setup() { // put it here }.

And there will be no point to the code inside loop(), since after FLASH_WriteProtection_Disable(FLASH_WRProt_Pages16to19); the Core will reboot, and if you let it run back into setup() it will keep on doing this till you reflash a sketch that does not call it.

I’d do this

setup() {
  Serial.begin(115200);

  while (!Serial.available())
    Spark.process();

  if (Serial.read() == 'D')  // only if you press 'D' the flash protect will be disabled 
    FLASH_WriteProtection_Disable(FLASH_WRProt_Pages16to19);

  // we should not end up here, but if we do
  while (true)  // wait forever for a new firmware
    Spark.process(); 
}
1 Like

yes ok... did it ... no change..

I guess its dead, time for a new one…

@kw123, it’s important to get a “lessons learned” from this. How many times do you figure your app did EEPROM writes - 4 days @ 1000/day? Could your code have written more than that (eg. unexpected loop)?

The STM32F103 specs indicate a minimum write lifecycle of 10,000 so it is odd that the flash would fail unless your code did more writes than expected.