C++ Methoden um einen Zustand innerhalb des loops nicht ständig zu schalten

Hallo zusammen,

Es geht mir in meiner Frage um eine Programmier-Methode, um einen Zustand innerhalb des Loops einmalig zu schalten. Wie meine ich das jetzt?

Nun nehmen wir als Beispiel die einfache Kontrolle mit IF einer bool Variable auf den Zustand false.

Sobald also diese Variable einmal auf false steht, soll etwas geschehen. Sagen wir mal als Beispiel es wird ein PIN mit einer LED auf HIGH gesetzt.

In größeren Projekten die komplexer sind könnte das aber allein bereits zum Problem werden, da jetzt sobald der Zustand false erreicht ist, der Loop diese Aktion immer wiederholt ausführt.

Im Falle der LED wird sich nichts bemerkbar machen. Aber im Grunde genommen setzt der Controller trotzdem sekündlich bei jedem Loop den PIN der LED auf HIGH.

Ich finde das je nach gewünschter Funktion nicht so schick/schön.

Wenn man jetzt noch eine serielle Ausgabe mit dem Text LED AN /LED AUS mit ausgibt, dann wird ja auch nach jedem Loop der Text erneut gepostet. Das wäre aber auch nicht immer gewünscht.

Ich würde also gerne eine einfache Methode anwenden können um die entsprechende Aktion erstmal nur einmalig auszuführen, bis dann der Zustand sich wieder ändert, worauf die Aktion wieder nur einmalig ausgeführt wird.

Und ich denke jetzt nicht an die Nutzung von Delays, in denen der Controller einfach wartet und nichts passiert.

Ich habe so einen Ansatz mal mit millis() programmiert wenn mein timestamp zwischen 0 und 100ms liegt dann wird die Aktion ausgeführt. Das garantiert natürlich nicht die einmalige Ausführung, dann wird aber das ganze zumindest nur 100ms lang ausgeführt und nicht ewig. Ist aber programmiertechnisch auch sehr aufwendig und es gibt sicherlich noch bessere lösungen.

Und die suche ich hier. :slight_smile:

Standardvorgehen: alten Zustand merken. Wenn neuer Zustand != alter Zustand --> alter Zustand = neuer Zustand und tue was (evtl. nur bei bestimmten Zustand).

Gruß Tommy

Hallo
Eine Verriegelung mit alt/neu wird helfen.

Siehe auch die Beispiele in der Arduino-IDE:
Beispiele / 02.Digital / StateChangeDetection

Perfekter Verweis, super

ich hab vor kurzer Zeit hier ein Progrämmchen gepostet, das schaltet einmal die LED um.
Im primitivsten Fall hängt man einfach ein digitalRead in die Bedingung dazu und schaltet eben nur, wenn der gewünschte Zustand des Ausgangspins noch nicht erreicht ist.

Das müsstest du mir bitte tatsächlich mal an einem kleinen Code darstellen, damit ich das genau verstehe.

Guter Tipp, ist direkt ein Beispiel das schaue ich mir auch sehr gern an!

Ah ich lese schon... das Beispiel ist genau das was Tommy auch meint.

Der Erste ist einfach:

bool start = true;

void setup()
{
  pinMode(LED_BUILTIN, OUTPUT);
  digitalWrite(LED_BUILTIN, LOW);
}

void loop()
{
  if (!start)  // Wenn start false ist
  {
    digitalWrite(LED_BUILTIN, HIGH);
  }
}

Das zweite ist nicht weit genug gedacht.
In Deinem Fall kannst Du die gesetzte Variable / den gesetzten Pin als "Erinnerung" nutzen, den Teil nicht mehr auszuführen.

void loop()
{
  if (!start && !digitalRead(LED_BUILTIN)) // Nur wenn start false ist und die LED noch nicht gesetzt
  {
    // mache hier was
    digitalWrite(LED_BUILTIN, HIGH);
  }
}

Und damit ist Absatz 3 obsolet, weil eben die LED nie mehr angesprochen wird, wenn nicht BEIDE Bedingungen erfüllt sind.
Aber nur als Hinweis:
Das ist nicht sekündlich sondern mit jedem Umlauf, und das ist im besten Fall microsekündlich.

Die serielle Ausgabe musst Du sowieso anders abhandeln.
Wenn Du prüfst, ob start true ist, bekommst du solange die Ausgabe "LED AUS" mit jedem Umlauf.
Wenn Du prüfst, ob start false ist, bekommst du solange die Ausgabe "LED AN" mit jedem Umlauf.
Also braucht es einen zusätzlichen bool.

bool start = true;
bool ausgabe = true;
void setup()
{
  Serial.begin(115200);
  Serial.println(F("Start..."));
  pinMode(LED_BUILTIN, OUTPUT);
  digitalWrite(LED_BUILTIN, LOW);
}

void loop()
{
  if (ausgabe == true)
  {
    ausgabe = false;
    if (start == true)
    {
      Serial.println(F("neustart"));
    }
    else
    {
      Serial.println(F("neustart beendet"));
    }
  }
  if (!start && !digitalRead(LED_BUILTIN)) // Nur wenn start true ist und die LED noch nicht gesetzt
  {
    // mache hier was
    digitalWrite(LED_BUILTIN, HIGH);
    {ausgabe = true;}
  }
}

Zum letzten Absatz: du musst nur "start" ändern.

na dann....

Was?

Ich vermute, dass in deinen Grundannahmen schon ein Irrtum steckt.

Mein Rat ...
Naivität: Was getan werden muss, muss getan werden!
Pragmatismus: Wenn die Prüfung, ob der Eimer voll, ist länger dauert als das Füllen, einfach blind füllen!

Bis zu 5,2 Millionen mal, kann man einen Pin pro Sekunde toggeln, auf einem UNO.

Disklaimer