Run code once after programming

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP












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.










share|improve this question

















  • 2





    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)?

    – Tobias Weiß
    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















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.










share|improve this question

















  • 2





    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)?

    – Tobias Weiß
    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













5












5








5


1






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.










share|improve this question














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.







arduino-uno atmega328 eeprom startup






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Feb 12 at 8:49









Tobias WeißTobias Weiß

3327




3327







  • 2





    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)?

    – Tobias Weiß
    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












  • 2





    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)?

    – Tobias Weiß
    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







2




2





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





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




2





change the high fuse setting in boards.txt to preserve the EEPROM content at ISP

– Juraj
Feb 12 at 9:49





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)?

– Tobias Weiß
Feb 12 at 10:16





@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)?

– Tobias Weiß
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





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










2 Answers
2






active

oldest

votes


















6














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.






share|improve this answer






























    0














    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






    share|improve this answer






















      Your Answer






      StackExchange.ifUsing("editor", function ()
      return StackExchange.using("schematics", function ()
      StackExchange.schematics.init();
      );
      , "cicuitlab");

      StackExchange.ready(function()
      var channelOptions =
      tags: "".split(" "),
      id: "540"
      ;
      initTagRenderer("".split(" "), "".split(" "), channelOptions);

      StackExchange.using("externalEditor", function()
      // Have to fire editor after snippets, if snippets enabled
      if (StackExchange.settings.snippets.snippetsEnabled)
      StackExchange.using("snippets", function()
      createEditor();
      );

      else
      createEditor();

      );

      function createEditor()
      StackExchange.prepareEditor(
      heartbeatType: 'answer',
      autoActivateHeartbeat: false,
      convertImagesToLinks: false,
      noModals: true,
      showLowRepImageUploadWarning: true,
      reputationToPostImages: null,
      bindNavPrevention: true,
      postfix: "",
      imageUploader:
      brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
      contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
      allowUrls: true
      ,
      onDemand: true,
      discardSelector: ".discard-answer"
      ,immediatelyShowMarkdownHelp:true
      );



      );













      draft saved

      draft discarded


















      StackExchange.ready(
      function ()
      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2farduino.stackexchange.com%2fquestions%2f61533%2frun-code-once-after-programming%23new-answer', 'question_page');

      );

      Post as a guest















      Required, but never shown

























      2 Answers
      2






      active

      oldest

      votes








      2 Answers
      2






      active

      oldest

      votes









      active

      oldest

      votes






      active

      oldest

      votes









      6














      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.






      share|improve this answer



























        6














        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.






        share|improve this answer

























          6












          6








          6







          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.






          share|improve this answer













          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.







          share|improve this answer












          share|improve this answer



          share|improve this answer










          answered Feb 12 at 10:22









          JurajJuraj

          7,65521027




          7,65521027





















              0














              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






              share|improve this answer



























                0














                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






                share|improve this answer

























                  0












                  0








                  0







                  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






                  share|improve this answer













                  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







                  share|improve this answer












                  share|improve this answer



                  share|improve this answer










                  answered Feb 15 at 17:47









                  RDragonrydrRDragonrydr

                  12




                  12



























                      draft saved

                      draft discarded
















































                      Thanks for contributing an answer to Arduino Stack Exchange!


                      • Please be sure to answer the question. Provide details and share your research!

                      But avoid


                      • Asking for help, clarification, or responding to other answers.

                      • Making statements based on opinion; back them up with references or personal experience.

                      To learn more, see our tips on writing great answers.




                      draft saved


                      draft discarded














                      StackExchange.ready(
                      function ()
                      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2farduino.stackexchange.com%2fquestions%2f61533%2frun-code-once-after-programming%23new-answer', 'question_page');

                      );

                      Post as a guest















                      Required, but never shown





















































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown

































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown






                      Popular posts from this blog

                      How to check contact read email or not when send email to Individual?

                      Displaying single band from multi-band raster using QGIS

                      How many registers does an x86_64 CPU actually have?