Führen Sie eine einmalige (einmalige) Ausführung in einer Endlosschleife oder einer Leerschleife durch?

Dec 12 2020

Ich möchte eine einmalige oder einmalige Ausführungssyntax in der forever-Schleife (void loop) für alle Programmsprachen erstellen.

Was ich gefunden habe, ist die Lösung, indem eine neue Variable boolesch "ausgeführt" und nach der Ausführung auf true gesetzt wird.

Es ist okay, aber was ist, wenn ich einmal eine Ausführung mit einer anderen Syntax machen möchte? Soll ich wieder eine neue Variable boolean machen? Es wird nicht effizient sein. Stellen Sie sich vor, es gibt viele Syntax, aber ich muss für jede Syntax eine neue Bool-Ausführung erstellen.

Die Lösung ist Funktion, denke ich

Zum Beispiel

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

Dies wird für immer gedruckt. Ich wünschte, es würde so funktionieren

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

"einmal" ist also eine Funktion mit einer Parameterzeichenfolge, die für Befehl / Syntax steht.

einmal ("Befehl")

Antworten

1 Paul Dec 12 2020 at 13:28

Mehrere Möglichkeiten, dies zu erreichen

Das Folgende ist eine sehr übliche Methode, wie eine solche Operation normalerweise durchgeführt wird. Wie Sie bereits vorgeschlagen haben, mit einem globalen Booleschen Wert :

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

Tun Sie etwas nur einmal nach einer bestimmten Zeit :

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");
  }
}

Und dank dieses Threads beim Verlassen der Schleife (möglicherweise nicht das, wonach Sie suchen):

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

Aber ich nehme an, Sie versuchen eine Art Schnittstelle zu erstellen, in der eine bestimmte Antwort in Bezug auf die Benutzereingabe gedruckt wird (wahrscheinlich viele Möglichkeiten)?! In diesem Fall hängt es davon ab, welche Eingaben Sie erhalten:

Bei Ganzzahlen :

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
  }
}

Im Fall von Stings / Zeichen müssen Sie mit einer "if-Schleife" durch jede mögliche Eingabe gehen (oder mit einem Array von Strings / Zeichen):

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
  }
}

Eine Funktion, nach der Sie suchen, bei der eine bestimmte Antwort nur EINMAL in Bezug auf eine Eingabe gedruckt wird, kann nur durch if / else- Schleifen archiviert werden. Wenn ein String beim Start nur einmal gedruckt werden soll, drucken Sie ihn im Konstruktor "setup ()". Ansonsten ist nur mit globalen Booleschen Werten so etwas möglich.

Beachten Sie, dass dies nur meine Vorschläge sind, die auf meinen Erfahrungen basieren. Dies bedeutet jedoch nicht unbedingt, dass andere Lösungen nicht verfügbar sind. Hoffe das hilft noch :)

1 AyxanHaqverdili Dec 12 2020 at 13:12

Hier ist eine Möglichkeit, wie Sie dies tun können:

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

Sie werden garantiert, dass diese Variable einmal initialisiert wird.

Wenn Sie die onceSyntax in Ihrer Frage haben möchten , können Sie mit einem Makro etwas Ähnliches erreichen:

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


void loop()
{
    ONCE(lcd.print("OK"))
}
1 Jarod42 Dec 12 2020 at 15:32

In C ++ gibt es std::call_oncesogar multi_thread, dann können Sie es generisch tun:

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

Da Lambda einen einzigartigen Typ hat, haben Sie eine Flagge von Lambda:

Demo