EEPROM Data don't persist when new schema flashed on MEGA 2560

hello,

I would like to store some product data in the EEPROM, so this can survive over restart and reset as well as firmware upgrade.

I have a schema that stores the data in EEPROM, then dumps the EEPROM content on the Serial line. The dump looks OK. So I believe that the EEPROM.write is working as it should.

Then I load another schema that reads the content and this is all zeroed. Like if I was using RAM :confused:

Reference Arduino MEGA2560
Arduino IDE 1.6.7 on Windows 10.

Any idea where to look at ?

Hello,

This me again. As the error looks really strange I made the same sketch running on a Uno and this is working as expected => perfectly. So, this not my code, but rather something wrong either in the HW (but I don't have another Mega for the test) or in the base libraries.

Any chance that you try to save Strings (capital S) in eeprom?

Hello,

No I just store char[] or bytes.

Here is the code for your review. The exact same code on Uno works perfectly. There are additional traces as I had some doubt about everything.

char* partnumber="AQS-G6P4W3-V12";
char* serialnumber="XZ182400001";
byte mac[] = {
  0xCA, 0xEE, 0xBB, 0xC0, 0x00, 0x01
};

void write_part() {
  unsigned int i;
  Serial.print("Part number:");
  Serial.println(partnumber);
  for(i=0;i<strlen(partnumber);i++){
    int v = partnumber[i];
    Serial.print(i);
    Serial.print(" V=");
    Serial.println(v);
    EEPROM.write(i,v);
  }
}

void write_serial(){
  unsigned int i;
  unsigned int base=16;
  Serial.print("Serial number:");
  Serial.println(serialnumber);
  for (i=0;i<strlen(serialnumber);i++)
    EEPROM.write(base+i,serialnumber[i]);
}

void write_mac() {
  unsigned int i;
  unsigned int base=32;
  Serial.println("Mac address:");
  for(i=0;i<6;i++){
    EEPROM.write(base+i,mac[i]);
  }
}

EEPROM.write writes bytes, not integers.

Use EEPROM.put and EEPROM.get instead. Check the syntax in the reference, get does not return the character.

Or change v to char or byte.

No idea why it might work on the uno.

Hello,

The first version was using bytes and not int. Look at the 2 other routines they are using char/byte and do not work better.

I have tried to use int after carefull reading of the Arduino documentation and in the example EEPROM.write(), an int variable is used.

Look at the page: EEPROM write

I am really stuck.

after carefull reading of the Arduino documentation

Is there something about this you don't understand?

write()
Description

Write a byte to the EEPROM.

My emphasis.

It doesn't matter whether you use an integer variable, the EEPROM.write still only writes the low order byte.

You've only posted the code which writes to the EEPROM. Post the code which reads those values back and show us what you get.

Pete

Ok, I will post more code, but this code is working fine until I put the same code in another sketch.

Note, that the same code is running on Uno without problem.

void e2reader(int dump_size){
  char buffer[16];
  char valuePrint[4];
  byte value;
  unsigned int address;
  uint8_t trailingSpace = 2;
 
  Serial.print("Dumping "); Serial.print(dump_size + 1);
  Serial.println(" bytes from EEPROM.");
  Serial.print("baseAddr ");
  for(int x = 0; x < 2; x++){
    Serial.print(" ");
    for(int y = 0; y < 25; y++)
      Serial.print("=");
  }
 
  // E2END is a macro defined as the last EEPROM address
  // (1023 for ATMEGA328P)
  for(address = 0; address <= dump_size; address++){
    // read a byte from the current address of the EEPROM
    value = EEPROM.read(address);
 
    // add space between two sets of 8 bytes
    if(address % 8 == 0)
      Serial.print("  ");
 
    // newline and address for every 16 bytes
    if(address % 16 == 0){
      //print the buffer
      if(address > 0 && address % 16 == 0)
        printASCII(buffer);
 
      sprintf(buffer, "\n 0x%05X: ", address);
      Serial.print(buffer);
 
      //clear the buffer for the next data block
      memset (buffer, 32, 16);
    }
 
    // save the value in temporary storage
    buffer[address%16] = value;
 
    // print the formatted value
    sprintf(valuePrint, " %02X", value);
    Serial.print(valuePrint);
  }
 
  if(address % 16 > 0){
    if(address % 16 < 9)
      trailingSpace += 2;
 
    trailingSpace += (16 - address % 16) * 3;
  }
 
  for(int i = trailingSpace; i > 0; i--)
    Serial.print(" ");
 
  //last line of data and a new line
  printASCII(buffer);
  Serial.println();
}

Here is the result I have just after the write. I can power off the card and reset, this is still the same results

Dumping 128 bytes from EEPROM.
baseAddr ========================= =========================
0x00000: 41 51 53 2D 47 36 50 34 57 33 2D 56 31 32 00 00 AQS-G6P4 W3-V12..
0x00010: 58 5A 31 38 32 34 30 30 30 30 31 00 00 00 00 00 XZ182400 001.....
0x00020: CA EE BB C0 00 01 00 00 00 00 00 00 00 00 00 00 ........ ........
0x00030: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ........ ........
0x00040: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ........ ........
0x00050: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ........ ........
0x00060: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ........ ........
0x00070: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ........ ........

If I load another sketch that is doing only the reading, then this is all zero.

If I load another sketch that is doing only the reading, then this is all zero.

How are you loading the new sketch?

Are you loading the new sketch through the normal usb/serial interface with a bootloader on the processor, or are you loading using icsp.

There are fuse settings controlling eeprom behavior when using icsp, but the fuse settings don't effect the eeprom behavior when a sketch loaded "normally" through usb with the bootloader.

Ok, found a workaround. I have decoupled erasing and writing and now it works.

FYI I am using the USB standard bootloader.

Let's close here.