Do one time (once) execution in forever loop or void loop?

Viewed 422

I want make one time or once execution syntax inside forever loop (void loop) for any program languages.

What i found the solution is with make new variable boolean "executed" and set to true after executed.

It's okay, but what if i want do once execution to other syntax? Should i make new variable boolean again? It will not effecient. Imagine theres many syntax but i must make new bool executiin for each syntax.

The solution is function i think

For example

void loop()
{
lcd.print("OK");
}

THIS IS WILL PRINT FOREVER I wish theres function like this

void loop()
{
once(lcd.print("OK"));
}

so "once" is a function with parameter string which its for command/syntax.

once("command")

3 Answers

Here is one way you can do it:

void loop()
{
    { // execute once. Can put this in a separate function also
        static bool executed = (lcd.print("OK"), true);
    }
}

You're guaranteed that this variable is initialized once.

If you want the once syntax in your question, you can achieve something similar with a macro:

#define ONCE(...) \
{\
 static bool executed = ([&]{__VA_ARGS__;}(), true); \
}


void loop()
{
    ONCE(lcd.print("OK"))
}

Several ways to approach this

Following is a very common way of how such an operation is usual made. As you already suggested, with an global boolean:

bool once = true; // global variable
void loop() {
  if (once) { // being called only once
    lcd.print("OK");
    once = false;
  }
}

Do something only once after a specific time:

void loop() {
  // millis() is the time in milliseconds after the startup 
  //if you want to print something once after a specific amount of time
  //this also includes a little "wait time" of 100 milliseconds as the statement might be asked with a delay
  if (mills() >= 1000 && mills() <= 1100) {// time in milliseconds
    lcd.print("OK");
  }
}

And thanks to this thread, with exiting the loop (might be not what you are searching for):

void loop() {
  lcd.print("OK");
  exit(0);  //The 0 is required to prevent compile error.
}

But I suppose you are trying to make some kind of an interface, where a specific answer is printed regarding to the user input (probably many possibilities)?! In that case it kind of depends on what inputs you are getting:

In case of Integers:

void loop() {
  switch (input) { //input must be an integer
    case 0:
      lcd.print("OK"); //prints "ok" if input is 0
    case 1:
      lcd.print("Hello"); //prints "Hello" if input is 1
  }
}

In case of Stings/chars, you need to go with an "if loop" trough every possible input(or with an array of Strings/chars):

void loop() {
  lcd.print("Turn off?"); //asks if it should do something
  if (input == "yes") { //String input
    lcd.print("OK, shut down!");
    //do something
  }
  else if (input == 'n' || input == 'N') { //char input
    lcd.print("OK, no shut down!");
    //do something
  }
}

A function you are looking for, where a specific answer only prints ONCE regarding to an input can be just archived by if/else loops. If a String should be just printed once at startup, print it in the "setup()" constructor. Otherwise just with global booleans something like that is possible.

Note that those are only my suggestions based on my experience, but it does not necessarily mean that other solutions are not available. Hope that helps still :)

In C++, there is std::call_once which is even multi_thread, then you can do it generically:

template <typename F>
void simple_do_once(F f)
{
    static std::once_flag flag;
    std::call_once(flag, f);
}

As lambda have unique type, you have one flag by lambda:

Demo

Related