12

Question: Where do I put code if I want it to execute only once per Arduino startup?

Background: I tend to use my Arduino to perform tasks that should be executed once per power cycle. (For example, my robot should only drive forward once every time I turn it on--more than that, and it might fall off the table.)

The standard Arduino IDE "template" consists of a loop() and a setup() function. The setup code is run once per power cycle, and the loop is re-started every time it finishes.

I see two approaches to code "1 time tasks:"

Method 1: "Loop once"

void setup() {
  //do setup stuff
}

void loop() {
  //do task

  while(1) ; //Repeat forever, preventing function from re-starting
}

Method 2: "Setup only"

void setup() {
  //do setup stuff

  //do task
}

void loop() {
  //do nothing
}

More detailed form of question: Is one of these methods "better" from a hardware/software sense? (e.g. is there anything "special" about the setup function, like it can only run for so much time?)
And, if they are the same from a hardware/software perspective, is there a "best practice" or standard way of writing code for these situations in the Arduino community?

13

I'm kind of confused by your question. You ask where you want to put once-per-startup setup functions, and then discuss the setup function. That's what the setup function is for.

As such, one-time setup functionality goes in the setup function.

FWIW, if you look in the file that calls the setup and loop functions:

#include <Arduino.h>

int main(void)
{
    init();

#if defined(USBCON)
    USBDevice.attach();
#endif

    setup();
    for (;;) {
        loop();
        if (serialEventRun) serialEventRun();
    }
    return 0;
}

For all intents and purposes, the two options are completely identical. Either way, you get a empty busy-wait loop. Frankly, I'd expect the two different options to probably emit the same machine code anyways, so the whole thing is a non-issue.

Note:
if (serialEventRun) serialEventRun(); appears to be a facility to allow you to attach a function that is called upon reception of serial data, but if you do not define a function void serialEvent(){} in your code, it will compile out completely and not be present in the produced machine code.

  • It feels weird to accept an answer that isn't (yet) the highest-voted. But, seeing the main() function definition was really helpful to my question. (And, you do indicate a consensus with the group with using setup instead of loop). Thank you for your help. – apnorton Feb 13 '14 at 13:59
  • 1
    @anorton - When in doubt, look under the covers. I find the arduino platform convenient for prototyping, but it's largely just boilerplate code. Understanding what it's doing can be tremendously helpful in deciding how to architect something. – Connor Wolf Feb 13 '14 at 21:04
6

I usually go with Method 2, but end up doing this:

void setup() {
  //do setup stuff

  //do task
  init(); //Do start-up initialization steps
}

void init() {
  // do tasks on startup
}

void loop() {
  //do looping code
}

With the above setup it allows my code to be even more organized.

  • the best answer so far +1, thanks dude you saved me! – Kyle Jan 19 '16 at 11:02
5

I would strongly prefer Method 2. If you ever plan to add code to handle input, output, etc, it's easy with Method 2 -- just fill in loop(), but requires reworking/refactoring in Method 1.

3

There is no time limit on the setup function. I prefer method 2 because the loop can be filled with whatever you need to later.

1

Definitely go with method two. That's what the setup function is there for. It's much easier to read as well. Anything in the loop() implies it will be run in a loop.

0

As most other answers, I would go for method 2.

But I would try to avoid the call, by Arduino library, to an an empty loop() that makes the Atmel consume "a lot" of current for nothing.

Edit:

As some comments pointed out though, using delay() in loop() will change nothing to power consumption.

Hence, if you would like to reduce power consumption once your setup() has run, you will have to play with Atmel sleep modes. You can take a look at this article that shows how to deal with sleep modes from your Arduino sketches; it does more than just putting the Atmel to sleep but it is a good (and simple) read if you want to play with sleep modes.

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.