Initial setup routine ( Run once code ).

While helping someone in their thread, I devised a way to allow setting up initial EEPROM data, however the solution is usable for any one time action like setting up IP addresses, an RTC or other devices with persistent memory. This is a simple solution, however I felt its useful enough to post on the forums.

The method I used will cause the initial code to run once only then subsequent power cycles/resets have no effect.
However this code will automatically cause your initial code to run when you upload a new version of your code.

The added bonus of the code is you get a time of compilation string which you can use to initialize an RTC as the code runs straight after uploading, or maybe run it through a CRC and use it to seed randomSeed; great for debugging when random values do not repeat each change of code.

WARNING: You must place your initial code where the comment specifies. It is placed before a while loop so if a power outage occurs before the initial setup completes, the setup will still run the next time the device is powered.

Also you can add logic weather to run the loop at all ( skip if error ), and it will rerun next reset/power.

#include <avr/eeprom.h>
unsigned char _CompileTimeP[] PROGMEM = __DATE__ " " __TIME__,
              _CompileTimeE[ sizeof( _CompileTimeP ) ] EEMEM;

void setup() {

  unsigned char b, *e = _CompileTimeE - 1, *p = _CompileTimeP - 1;

  while( b = pgm_read_byte( ++p ) ){
    if( b !=  eeprom_read_byte( ++e ) ){
      //ADD YOUR EEMEM INITIAL SETUP HERE.
      while( b = pgm_read_byte( p++ ) ) eeprom_write_byte( e++, b );
      break;
    }
  }
  //NORMAL SETUP HERE
}

void loop() {}

EDIT: left in an variable that is not needed, fixed!

  unsigned char b, *e = _CompileTimeE - 1, *p = _CompileTimeP - 1;

  while( b = pgm_read_byte( ++p ) ){
    if( b !=  eeprom_read_byte( ++e ) ){

would make way more sense (to me) as:

  unsigned char b;
   unsigned char *e = _CompileTimeE;
   unsigned char *p = _CompileTimeP;

  while( b = pgm_read_byte( p++ ) )
  {
    if( b !=  eeprom_read_byte( e++ ) )
   {

I don't understand pointing to before the start of the array just so you can use prefix notation. Point to the right place and use postfix notation. One variable declaration per statement.

I don't understand pointing to before the start of the array just so you can use prefix notation. Point to the right place and use postfix notation...
would make way more sense (to me) as..

Even though it looks nice, it doesn't work.

It has to be prefix notation, postfix notation and starting from 0 will fail. The increment must happen after the nested loop, or in my case, at the start which is more efficient.

I agree that it is easier to read shorter sentences...

How about trying to get the Arduino team to fixing the original problem? The Arduino build does not include the EEMEM section and therefore the initialization of the EEMEM varables are not available. Cheers!

kowalski:
How about trying to get the Arduino team to fixing the original problem? The Arduino build does not include the EEMEM section and therefore the initialization of the EEMEM varables are not available. Cheers!

It does work if you use an ISP, but EEMEM can be used like I have in the IDE to simply locate a variable there. I think the option of making the eeprom persistent was a good choice for beginners. However a toggle to enable write on upload would be good.

Also my code gives you the advantage of being able to initialize things other than the eeprom.

Here is an issue that I filed a year ago. EEMEM variable initialization not performed · Issue #256 · arduino/ArduinoCore-avr · GitHub
Cheers!