Write to EEPROM automatically add value ?

Hi Guys,
I just new to Arduino Uno R3 and Arduino IDE 2.3.4. I want to write in EEPROM the number of times, the program is called. So I put a code like this

#include <EEPROM.h>

void setup() {
  Serial.begin(9600);

  Serial.print("EEPROM length = ");
  Serial.println(EEPROM.length());

  uint8_t value;
  value = EEPROM.read(10);
  Serial.println(value);
  value++;
  Serial.print("The number of call  =  ");
  Serial.println(value);
  EEPROM.write(10, value);
}

void loop() {
// do nothing 
}

and the results come such as I increment the value twice ..

EEPROM length = 1024
12
The number of call = 13
EEPROM length = 1024
14
The number of call = 15

But, if I remove the increment code (value++), then the value will still the same all the time as expected.

14
The number of call = 15
EEPROM length = 1024
15
The number of call = 15
EEPROM length = 1024
15
The number of call = 15

Anybody can explain what happen in the program ?

Regards,
Michael

Welcome to the forum

The EEPROM library needs a short period of time to initialise itself. Add a delay() of 1 second at the start of setup()

I've never seen that (there is not even a begin() function on AVR). It's always ready the nanosecond the code hits the setup() function.

The EEPROM library uses the AVR lib for read and write, calling
eeprom_read_byte() and eeprom_write_byte()

if you look at their documentation they explain that their API is polling and

  • All of the read/write functions first make sure the EEPROM is ready to be accessed. Since this may cause long delays if a write operation is still pending, time-critical applications should first poll the EEPROM e. g. using eeprom_is_ready() before attempting any actual I/O. But this functions are not wait until SELFPRGEN in SPMCSR becomes zero. Do this manually, if your softwate contains the Flash burning.

@mich001

I ran your code on my UNO R3 and pressed the reset button once the text was shown. It works as expected;

EEPROM length = 1024
1
The number of call  =  2
EEPROM length = 1024
2
The number of call  =  3
EEPROM length = 1024
3
The number of call  =  4
EEPROM length = 1024
4
The number of call  =  5
EEPROM length = 1024
5
The number of call  =  6
EEPROM length = 1024
6
The number of call  =  7

➜ how did you reboot the Arduino to see the +2 increment? Did you re-upload the code?

There have been previous reports of it here

If you remove the power from the Arduino, then the count will increment when the power is re-applied.
However you won't see that being reported as the Serial Monitor is no longer connected.
When you re-start the Serial Monitor, the Arduino gets reset and the count incremented a second time.

Is this what you have been seeing?

I've seen the discussion but there were no documentation nor proof it's the case.
I'd love to see an example where it does not work.

Indeed, that's why I asked about the reboot method. pressing the reset button on the board will not create the disconnection from the Serial monitor and so the count is fine.

It seems that the problem is not that the EEPROM library needs time to initialise

Take a look at this topic EEPROM for initiation program - #6 by johnwasser

Having worked with EEPROM extensively on R3:

The EEPROM does not need time to initialize. It is immediately ready.

And I confirm the earlier answer, that activating the serial monitor may boot your device an extra time, resulting in an extra run of setup() and, in turn, an extra count beyond the one resulting from powerup.

Thank you J-M-L. What I did, was that I compiled and downloaded the program from Arduino IDE every time, I wanted to run the program. It seems that the program download from Arduino IDE, in fact, run the setup once. Otherwise, if I do like what you did, I have the same result as yours. Reswobslc below also states the same thing.

Yes, when you push the code in the arduino, it reboots and thus the increment takes place but the Serial monitor takes a bit of time before connecting back and opening the Serial connection reboots the arduino too ➜ you end up with two cycles.

This is also why I think some people got confused into thinking the EEPROM needed some time to get ready. Adding a delay(1000); did not prevent the double boot but was actually waiting long enough for the Serial monitor to reconnect before messing with the EEPROM and thus you would only have one increment. Then people thought it was the cure and the internet does what it does worst - propagate the false information and new users taking this for a fact, adding weight to the belief (and at some point tricking AI into believing this too)... ➜ Let's debunk this myth !

Of course second guessing how long the Serial connection will take is error prone and not the solution.

However, it is also noted in "A guide to EEPROM" (https://docs.arduino.cc/learn/programming/eeprom-guide/), that
" An EEPROM write takes 3.3 ms to complete. " So, I guess in the function EEPROM.write() and EEPROM.read(), there is some kind of "waiting" or interrupt mechanism. Anybody knows what is the address of EEPROM space when I use EEARL-EEARH registers ? It is 0x0 - 0x3FF, or is there any offset ? Regards

yes, as per my previous comment

➜ they are actively waiting until the previous operation is completed before doing the read or write. So if you develop an app and want to optimise the time it takes to write, you would only call read/write when eeprom_is_ready() returns true otherwise you would attend other tasks

from top of my head, the ATmega328P has 1024 bytes of EEPROM, and since EEAR is a 10-bit register (EEARH[1:0] + EEARL[7:0]), it can directly address memory locations from 0x000 to 0x3FF without any offset or remapping ➜ I don't think there are any offset.