Re-Upload Causes EEPROM Value to Increase?

Hey guys,

I'm literal loosing my mind over this, so I would very much like some help, understanding what is happening.

To start out I am making an accelerometer that I can have in my backpack while I'm skiing, biking, etc... I am taking the data the accelerometer gives and storing it to a txt file on a micro SD card. The accelerometer module is using I2C protocol using the SDA and SCL pins, and the SD module is using pins 10-13.

I am using an Elegoo Arduino Uno R3, GY-521 accelerometer, and some generic SD module (I can't find any labels (maybe HW-125))

I want to have a naming scheme for these txt files that changes based on the previous entries/ txt files that I have created. I am planning on including a button or switch that that tells the Arduino to create an new txt file and write to it and then when the button is pressed again to stop writing and close the file. Basically I was thinking:
"Accel01",
"Accel02",
"Accel03", etc...

However, because I would have this in my backpack I obviously have to use batteries to power the Arduino, and I do not want to power this all of the time because it would use up so many batteries. So my solution to this was to have different (but similar) naming scheme based on the file names on the SD card. Something like:
"01Accel01",
"01Accel02",
"01Accel03",
"02Accel01",
"02Accel02",
"03Accel01",
"03Accel02",
"03Accel03",
"03Accel04", etc...

I was planning on reading the file names from the SD cards but I am not sure how to cycle through each of the files because I am new to reading and writing data to other file locations. I've got experience with MATLAB using arrays, matrices, for loops, if loops, etc... I'm just not sure how to cycle through them.

Anyways I ran across EEPROM while trying to figure out the above issue and that was perfect for what I needed. I could just say:

int val = EEPROM.read(addr);
String tempfilename = String(val)+"Accel"+String(count);

And get the file name I want.

However my issue arises when I re-upload the code to my Arduino (to simulate being turned off and back on), the value that I read from the EEPROM changes between uploads even though it should be resistant to change.

When I use this exact code:

#include <EEPROM.h>

int addr = 13;
int val = EEPROM.read(addr);

void setup(){
    Serial.begin(9600);
    
    Serial.println();
    Serial.print(" ");
    Serial.print(EEPROM.read(addr));
    Serial.print(" ");
    Serial.print(val);
    Serial.print(" ");
    val = val + 1;
    Serial.print(val);
    Serial.print(" ");
    EEPROM.update(addr,val);
    Serial.print(val);
    Serial.print(" ");
    Serial.print(EEPROM.read(addr));
    Serial.print(" ");
    Serial.println(val);
}

void loop() {

}

With each new line being a re-upload. My Results looks like this:

 24 24 25 25 25 25

 26 26 27 27 27 27

 28 28 29 29 29 29

 30 30 31 31 31 31 

It ends up incrementing by an additional 1 in between the last print of the original upload and the first print of the re-upload.

When they should look like this:

 24 24 25 25 25 25

 25 25 26 26 26 26 

 26 26 27 27 27 27
 
 27 27 28 28 28 28 

 28 28 29 29 29 29

I don't know why and I need help.

I was thinking it might be something in the library but after looking through it I'm not so sure.

I'm just using the one that comes standard with the arduino installation. So maybe it's outdated? My file location is this: C:\Program Files (x86)\Arduino\hardware\arduino\avr\libraries\EEPROM

It might also just be a bad board (I hope not)

Any help would be GREATLY appreciated.


FYI:

I could use val++ but val = val + 1 gives me more room to debug cause I can change the interval by which it increments.

Having val = val + 2 does make the re-upload increment by 2 instead of by 1, in addition if I have val = val the re-upload does not increment at all (which makes sense because I am technically not changing anything)

EEPROM.update(addr, val++) does not work. It has to be val++ ; EEPROM.update(addr,val)

I have not noticed a difference in using .update() compared to .write()

The short hand val = EEPROM[addr] and EEPROM[addr] = val acts in the same manner which is to be expected.

For those curious, I am pretty sure (not 100%), that addr is the address EEPROM uses to read and write data to, like the index in an array.

int val = EEPROM.read(addr);  //read the value of val from the EEPROM

val = val + 1;  //add 1 to the value of val
 
EEPROM.update(addr, val); //save the updated value of val if it has changed, which it has

Every time you power up or reset the board you add one to the value saved in the EEPROM so is it any wonder that

That is because update() only writes to EEPROM if the value has changed, but val++ changes the value after the update() function is executed

I am trying to increment it by 1, however it somehow ends up incrementing it again, somewhere between the last print of the original up load and the first print of the re-upload. So it ends up incrementing it twice.

Yeah, I figured that out after messing with it for a few hours. haha

I have tried your code on a Nano with the following results

 0 0 1 1 1 1

 1 1 2 2 2 2

 2 2 3 3 3 3

 3 3 4 4 4 4

 4 4 5 5 5 5

 5 5 6 6 6 6

 6 6 7 7 7 7

 7 7 8 8 8 8

 8 8 9 9 9 9

 9 9 10 10 10 10

so cannot reproduce your problem. Does it happen consistently ?

It does happen consistently. Also it doesn't matter which addr I am using, I tried it with 1, 7, and 12. 13 just happened to be the latest.

If it's not a basic code issue than could it be a library issue? Or a board issue? I don't have another board for me to test it on.

Oh! Almost forgot.

If I have this in Loop():

    char letter = Serial.read();
    if (letter != -1){
        if (letter == 'R' || letter == 'r'){
            int val = EEPROM.read(addr);
            Serial.println();
            Serial.print(" ");
            Serial.print(EEPROM.read(addr));
            Serial.print(" ");
            Serial.print(val);
            Serial.print(" ");
            val = val + 1;
            Serial.print(val);
            Serial.print(" ");
            EEPROM.update(addr,val);
            Serial.print(val);
            Serial.print(" ");
            Serial.print(EEPROM.read(addr));
            Serial.print(" ");
            Serial.println(val);
        }
    }

The results update fine (and are what I expect them to be) whenever I enter R, but it still gives me an issue when I re-upload.

I believe that you are seeing a double reset. Once when you apply upload code or reapply power, and once again when you open the Serial monitor.

It's really not clear what you are tying to do, and how best to work around the reset which occurs with the Serial monitor.

If you are just removing and reapplying power and not uploading new code, then you can do something like this to run setup code after the monitor is opened.

void setup() {
  Serial.begin(9600);
  Serial.println("Type any character to start");
  while (Serial.read() <= 0) {}
//continue with setup code

I am trying to use the EEPROM as a counter that counts every time the Arduino gets turned off or the code gets reuploaded.

I'm assuming they (reuploading code and disconnecting power) act the same way, please correct me if I'm wrong.

Weird. I'll look into that

Unfortunately, I'll eventually be away from a computer so typing in a character to continue the code would only work in the meantime.

Someone else had the same problem a few months ago. I found that by adding "delay(200);" after the "Serial.begin();" I could avoid modifying the EEPROM after the upload and before the reset caused by the Serial Monitor connecting.

1 Like

Thank you so much. This issue has been driving me crazy for a couple days now and this seems to have solved it. Do you happen to know why using delay make this go away? Now I guess I'll be bothered by that question, haha.

I know that @cattledog said that this could be a double reset but wasn't sure how to fix it so I tried changing the baud when I pressed a button but that didn't fix it, not sure if that's because you can't change the baud in the middle of a code or if it's because changing it does nothing.

Anyways thanks again @johnwasser for helping me with this.

Didn't I explain it adequately?

If you have the Serial Monitor process open, there are two processes on the PC that want to use the one serial port of the Arduino: the uploader and Serial Monitor. When you do an upload, the Serial Monitor has to disconnect from your Arduino and re-connect when the upload is complete. Every time a process on the PC connects to the Arduino serial port, the Arduino is forced to reset.

When the uploader is done uploading, your sketch starts running and the uploader disconnects from the Arduino serial port. There is a wait of about 150 to 180 milliseconds between the time your sketch starts and the Serial Monitor is able to establish a new connection and reset your Arduino.

Your sketch was modifying EEPROM in the first 150 milliseconds and again after Serial Monitor caused a reset. By putting a 200-millisecond delay early in setup(), the Arduino doesn't make any changes to EEPROM before the reset.

Initially? No. I am quite new to programming Arduinos so I am trying to learn as much as I can about them, but your next explanation about the serial port was very informative. Thank you.