Run code once after programming
Clash Royale CLAN TAG#URR8PPP
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 0xFF
s 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
add a comment |
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 0xFF
s 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
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
add a comment |
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 0xFF
s 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
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 0xFF
s 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
arduino-uno atmega328 eeprom startup
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
add a comment |
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
add a comment |
2 Answers
2
active
oldest
votes
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.
add a comment |
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
add a comment |
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
);
);
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
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.
add a comment |
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.
add a comment |
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.
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.
answered Feb 12 at 10:22
JurajJuraj
7,65521027
7,65521027
add a comment |
add a comment |
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
add a comment |
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
add a comment |
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
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
answered Feb 15 at 17:47
RDragonrydrRDragonrydr
12
12
add a comment |
add a comment |
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.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
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
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