5

I'm using EEPROM to store project settings non-volatile. After reuploading the sketch to my board (over SPI via ArduinoISP), the EEPROM is reset to full 0xFFs and I have to manually do a "software reset" with a second switch, which initializes the EEPROM with its default values.

Is it possible to run a segment of code once, and only once, after booting up the first time after being programmed?

I'm working around it by checking whether a piece of EEPROM is 1 at startup when it would always be 0 after the initialization and during usage, but surely there's a cleaner alternative than checking for an EEPROM bit each time.

  • 3
    Personally I think your way is very clean, program an EEPROM bit, set it, and change it after doing a one time initialization. It's also very flexible, in case you want to do it multiple times (just use a counter in EEPROM for example). Or in case the initialization is not done correctly, you can omit resetting the bit. – Michel Keijzers Feb 12 at 9:23
  • 2
    change the high fuse setting in boards.txt to preserve the EEPROM content at ISP – Juraj Feb 12 at 9:49
  • @Juraj The solution with the fuse has worked, although I had to flash it manually through avrdude (D6 instead of DE). Is it normal that changing it in the boards.txt would not update it when flashing (/ flashing using ArduinoISP)? – towe Feb 12 at 10:16
  • The fuses are only written when you select the "burn bootloader" option in the Arduino IDE. PS You can also use AVRdude to write to the EEPROM directly. – Gerben Feb 12 at 11:10
  • see the EEPROM library's eeprom_crc example – Juraj Mar 20 at 10:10
8

This is a X->Y problem. Here is a solution for X:

Bit 3 of high fuse of the ATmega328p controls if EEPROM memory is preserved through the chip erase. You can change the high fuse setting in boards.txt. Restart the IDE to apply the new setting.

The fuses are written when you select the "burn bootloader" option in the Arduino IDE.

  • @TobiasWeiß, you could accept the answer – Juraj Mar 19 at 17:32
  • I feel like editing the boards.txt file is a bit less "portable" than I'd prefer. I believe checking whether an EEPROM that's guaranteed to be 0 after initialization is 1 (after flashing) is cleaner. – towe Mar 20 at 9:47
  • portable? someone else will flash it over ISP? – Juraj Mar 20 at 9:52
  • Yes, unfortunately. I've described how to wire the ArduinoISP up to the project board and how to flash it using the IDE, but editing the file seems a bit too much. – towe Mar 20 at 10:00
1

I've actually done some tinkering with this sort of thing, or alternatively how to ensure previous EEPROM (or similar) settings are formatted on upload of a new sketch.

There are two values (C macros, in this case) that are baked into a program when it is compiled (for Arduino, the program is recompiled on each upload) that can be used to tell if the programming is "fresh."

The values you'd want are __DATE__ and __TIME__. They are converted to char arrays (strings, basically) at the time the compiler is run. You can store them directly to EEPROM, or use some sort of hash to convert it to a convenient number to store instead. Then, whenever the code boots, compare the stored value with the one computed from the values coded into the program. If they differ, overwrite the stored value with the new one and execute the run-once code.

Something along the lines of

byte i=0;
char checkVal[]=__TIME__ __DATE__;
for (int j=0; j<strlen(checkVal); j++){
  i+=(byte)checkVal[j];//Creates a modulo 256 sum of the ASCII values of the chars (really poor hash)
}
if(EEPROM.read(26)!=i){//stored EEPROM location (arbitrary) -- feel free to use wear leveling, though, or some other method
  //DO RUN-ONCE CODE HERE
  EEPROM.write(26,i);//store the new value to stop it running again
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.