basic EEPROM questions.

From what I understand:

  • the stock EEPROM value for each byte is 255
  • the stock “arduino uno” fuse settings for ATMega328P do not enable EESAVE (which, when enabled should save the EEPROM values, even during new programming)
  • programming through the arduino IDE does not revert fuse-settings back to stock. (regardless of the EESAVE fuse setting)… as explained in this post.
  • Arduino’s EEPROMClear example changes each byte of eeprom to “0”.

My questions:

1. Why would the stock EEPROM values be 255 instead of 0?
2. Why does arduino’s EEPROMClear example set values to be 0, when it is known that stock values are 255?
3. Why did Arduino (the company) choose to save EEPROM values upon programming in their IDE, rather than just set the 328P EESAVE fuse to begin with?
4. What is best-practice when wanting to do the following:

  • you have a bunch of user-adjustable variables in your code.
  • you want to save any changes that a user makes to said variables.
  • you want to load-in any saved variables upon re-start of arduino.

Here’s how I have been doing it:

#include <EEPROM.h> // so we can save settings

// variables (shown with default values):

byte var0 = 1;
// if modified, saved as byte #0 in EEPROM

byte var1 = 2;
// if modified, saved as byte #1 in EEPROM

byte var2 = 0;
// if modified, saved as byte #2 in EEPROM


void setup() {
  // put your setup code here, to run once:

  // load-in any saved variables if we have any:
  if(EEPROM.read(0) != 255) // 255 = nope, anything else = yep
  {
    // load that saved option:
    var0 = EEPROM.read(0);
  }
  if(EEPROM.read(1) != 255)
  {
    // load that saved option:
    var1 = EEPROM.read(1);
  }
  if(EEPROM.read(2) != 255)
  {
    // load that saved option:
    var2 = EEPROM.read(2);
  }

}

void loop() {
  // put your main code here, to run repeatedly:

}

this approach would work great if:

  • The uno was bone-stock, and nothing had been written to eeprom
  • The uno’s eeprom would be re-set after each programming

but this approach falls on its face if:

  • The uno has previously been programmed and has had an eeprom value written to it.

Thoughts?

Best practice would be to assume nothing about the EEPROM contents, prior to the first run of the program. After that, it's application dependent, and the programmers responsibility to manage it correctly.

aarg: Best practice would be to assume nothing about the EEPROM contents, prior to the first run of the program. After that, it's application dependent, and the programmers responsibility to manage it correctly.

good advise. but is there any way I can get the functionality I describe w/o assuming any EEPROM values?

Obviously, I can't simply write all 0's or all 255's to EEPROM in setup, because that would clear out any saved data each and every time the arduino is reset.

One thing I've thought of doing is a "one-time wipe" of EEPROM. I could do this by checking a "save byte" in EEPROM, and if that byte isn't X, then I could wipe all EEPROM values and set the save byte to X.

suedo code:

if save byte in EEPROM isn't X: - set all EEPROM values to 255 - set save byte in EEPROM to X

but even that assumes the save-byte in EEPROM is not X immediately after flashing code. (granted, there are 254:1 odds that my assumption is correct)

Thoughts?

As I understand your question, it becomes a matter of probability. Because there is no pattern that could not be put there by accident or intention. If you marked it with a pattern, like "0xDEADBEEF" to prove that you have already written it, you are essentially gambling that nobody else (or nothing else) would do that. The longer the pattern, the more unlikely. But you can never be 100% sure.

Or am I misunderstanding the question?

I don't know about fuse settings, haven't had to deal with that. But:

  1. Why would the stock EEPROM values be 255 instead of 0?

Because that's how the AVR processor works. All the bits are set.

  1. Why does arduino's EEPROMClear example set values to be 0, when it is known that stock values are 255?

So that you can see that it has changed. That's it.

aarg:
As I understand your question, it becomes a matter of probability. Because there is no pattern that could not be put there by accident or intention. If you marked it with a pattern, like “0xDEADBEEF” to prove that you have already written it, you are essentially gambling that nobody else (or nothing else) would do that. The longer the pattern, the more unlikely. But you can never be 100% sure.

awesome.
Thanks for the tip.

EEPROMs get erased by charging up all the cells (of a page/a chip) to HIGH, writing to the single cells can only change HIGH bits to LOW bits.

This creates the 0xFF in empty (erased, unwritten, ...) cells.

(as far as I remember...)

And for the variables in the EEPROM?

Use some identification so you can see if you already initialized the EEPROM (2+ run of the sketch) and then initialize it, or use the content.

Values (longer than one byte) are often written followed by a bitinverted copy, to detect value corruption.

Whandall: Use some identification so you can see if you already initialized the EEPROM (2+ run of the sketch) and then initialize it, or use the content.

Note an important requirement of the OP. That it not be misled in the case that:

  • The uno has previously been programmed and has had an eeprom value written to it.

That means that the identification has to be extremely unlikely to have been written previously (not by the OP's program). Obviously, the longer and more "diverse", the more unlikely it is to happen.

For example, suppose you signal "written" by putting a zero in the first byte. Not very good. There are many programs that might put that there. Now try 0xAA. Your chances improved 256 times, but it is still possible. Make it longer... more bytes... 0xAA55. Now it is even more unlikely. But it is still possible. ... and so on and so on up the Yangtse.