Schleife einmal durchlaufen lassen

Guten Tag zusammen, ich habe folgenden Sketch: Ich möchte erreichen, dass die if bzw. else Schleife bei betätigen des Tasters nur einmal durchläuft und dann bei jeweils grün = HIGH oder rot = HIGH bleibt.
Wie kann ich das erreiche beziehungsweise welcher Code ist dafür nötig.

Vielen Dank im Voraus

/*

*/

int tasterstatus1 = 0;
int gruen1 = 6;
int gelb1 = 7;
int rot = 8;
int ampel1 = 9;

void setup() {
    pinMode(gruen1,OUTPUT);
    pinMode(gelb1,OUTPUT);
    pinMode(rot1,OUTPUT);
    pinMode(ampel1,INPUT);
}

void loop() {
    


tasterstatus1=digitalRead(ampel1);


if (tasterstatus1 == HIGH)
    {
    digitalWrite(gruen1,HIGH);
    digitalWrite(gelb1, LOW);
    digitalWrite(rot1, LOW);
    delay(1000);
    digitalWrite(gruen1,HIGH);
    digitalWrite(gelb1, HIGH);
    digitalWrite(rot1, LOW);
    delay(1000);
    digitalWrite(gruen1,LOW);
    digitalWrite(gelb1, LOW);
    digitalWrite(rot1, HIGH);
    
    
    
    
    }

else

    {
      digitalWrite(gruen1,LOW);
    digitalWrite(gelb1, LOW);
    digitalWrite(rot1, HIGH);
    delay(1000);
    digitalWrite(gruen1,LOW);
    digitalWrite(gelb1, HIGH);
    digitalWrite(rot1, LOW);
    delay(1000);
    digitalWrite(gruen1,HIGH);
    digitalWrite(gelb1, LOW);
    digitalWrite(rot1, LOW);
    }
}

(deleted)

Du benutzt eine Statusvariable. In der if Bedingung der "Schleife" kontrollierst Du ob die Statusvariable zB 0 ist. in der "Schleife" setzt Du die Statusvariable auf 1. Wenn die "Schleife" wieder ausgeführt werden soll setzt Du die Statusvariable wieder auf 0.
Grüße Uwe

dass die if bzw. else Schleife

if-schleife

Wie kann ich das erreiche beziehungsweise welcher Code ist dafür nötig.

Erreichen kannst du das in dem du das so programmierst.

Und welcher Code dafür nötig ist?
Natürlich einer, der das tut, was du willst.
Sicherlich Dutzende Möglichkeiten es gibt.

Leider habe ich dein Problem nicht verstanden...
Der Lauf soll nur einmal nach dem Einschalten stattfinden?
Warum steht er dann in loop() und nicht in setup()

Oder soll es bei jedem Betätigen durchlaufen werden?
Dann wirst du Betätigungen erkennen müssen.

Ablaufsteuerung
Meine Standardantwort zu Ablaufsteuerungen:

Eine Stichworte Sammlung für Google Suchen:
Endlicher Automat,
ProtoThreads,
State Machine,
Multitasking,
Coroutinen,
Ablaufsteuerung,
Schrittkette,
BlinkWithoutDelay,

Blink Without Delay
Die Nachtwächter Erklärung

[MicroBahner/MobaTools/url]
Intervall Macro
Multitasking Macros
INTERVAL Ersatzstoff
CooperativeTask[/quote]
](GitHub - MicroBahner/MobaTools: Arduino library for model railroaders)

Damit dein Beispiel überhaupt richtig und sicher funktioniert, solltest du dich komplett von den delays verabschieden.
Ersetze die delays durch Funktionen mit millis (Beispiel BlinkWithoutDelay) und berücksichtige die schon gemachten Vorschläge.

Also setze ich die schleife in setup?

vielen dank für eure Tipps. :slight_smile:

pronicolas:
Guten Tag zusammen, ich habe folgenden Sketch: Ich möchte erreichen, dass die if bzw. else Schleife bei betätigen des Tasters nur einmal durchläuft und dann bei jeweils grün = HIGH oder rot = HIGH bleibt.
Wie kann ich das erreiche beziehungsweise welcher Code ist dafür nötig.

Vielen Dank im Voraus

if (tasterstatus1 == HIGH)

{
   digitalWrite(gruen1,HIGH);
   digitalWrite(gelb1, LOW);
   digitalWrite(rot1, LOW);
   delay(1000);
   digitalWrite(gruen1,HIGH);
   digitalWrite(gelb1, HIGH);
   digitalWrite(rot1, LOW);
   delay(1000);
   digitalWrite(gruen1,LOW);
   digitalWrite(gelb1, LOW);
   digitalWrite(rot1, HIGH);
[...]

Die Aufgabenstellung ist massiv ungenau.
Nimm einen Zettel und schreibe auf was Du willst.
Formuliere daraus deine Frage.

Nach dem, was Du oben schreibst und in dem Code zu stehen hast, würde ab hier nichts mehr passieren.

if (tasterstatus1 == HIGH)
{
digitalWrite(gruen1,HIGH);

Dann wären beide Bedingungen, die Du vorgibst erfüllt.

Also setze ich die schleife in setup?

Nein.

Was für eine Schleife?

Lies Mal, was combie so Feines gepostet hat ... #3

MfG

Ich komme mit combis Infos nicht so ganz weiter, ich kann es alt genauer formulieren: Wenn der Taster gedrückt wird soll erst die grüne led angehen dann wieder aus, dann die gelbe wieder aus und schlussendlich die rote, die dann auch rot bleiben soll. Wenn der taster nicht gedrückt wird, soll es genau umgelehrt passieren d.h rot aus, gelbe an/aus , grün an und grün an bleiben,

Ich komme mit combis infos nicht so ganz weiter, wenn mir jemand sagen könnte nach was ich ich suchen muss um den Befehl richtig auszuführen, dann wäre ich schon sehr dankbar.

Es geht mir weniger um das delay bzw. die zeitenabfolge.

pronicolas:
Ich komme mit combis Infos nicht so ganz weiter,

Naja - eigentlich nicht schwer.
if/else ist KEINE Schleife.

IF ist eine Bedingung.
ELSE wird ausgeführt, wenn genau diese Bedingung NICHT erfüllt ist.

Und dann zu Deiner Vorgabe....
Mit dem Start deines Ardu UND die Taste nicht gedrückt, bekommst Du den Zustand

Wenn der taster nicht gedrückt wird, soll es genau umgelehrt passieren d.h rot aus, gelbe an/aus , grün an und grün an bleiben,

umgehend.

Es wird der Zustand

Wenn der Taster gedrückt wird soll erst die grüne led angehen dann wieder aus, dann die gelbe wieder aus und schlussendlich die rote, die dann auch rot bleiben soll.

nur erreicht, wenn die Taste mehr oder weniger schon beim Anlegen der Betriebsspannung gedrückt ist.

Dann würde es auch im setup() reichen.

Das ist sicher nicht das, was Du willst.

Hi

Warum schreibst Du nicht einfach, WAS Es werden soll?
... eine Ampel, Die auf Knopfdruck (und gedrückt halten) die Fahrzeug-Ampel auf ROT schaltet.
... Die bei NICHT-Knopfdruck zurück nach GRÜN schalten soll.

Wäre Das ungefähr, Was Du vorhast?

Dann überlegen wir uns, welche Ampel-Phasen wir haben

  • ROT
  • ROT,GELB
  • GRÜN
  • GELB
  • ... wieder von Vorne

Wenn Knopf gedrückt ist (und die Wartezeit um ist) und noch nicht ROT, dann gehe einen Schritt weiter.
Wenn Knopf NICHT gedrückt ist (und die Wartezeit um ist) und noch nicht GRÜN, dann gehe einen Schritt weiter
Wenn Schritt >GELB, dann Schritt=ROT

Alles keine größere Hexerei - Du musst Dir NUR den Ablauf klar machen - und Diesen dann programmieren.

MfG

Ich komme mit combis infos nicht so ganz weiter,

Merke ich schon!

Allerdings habe ich deine Beschreibung mittlerweile, in etwa, verstanden.
Also kann ich dir zeigen, wie sowas bei mir aussehen könnte.

#include <TaskMacro.h>
#include <CombiePin.h>

using LedRed    = Combie::Pin::OutputPin<11>;
using LedYellow = Combie::Pin::OutputPin<12>;
using LedGreen  = Combie::Pin::OutputPin<13>;
using Taster    = Combie::Pin::TasterGND<2>;

const bool stromausfall { false };
const unsigned long ampeltakt { 500 }; //ms

Task ampel()
{
  taskBegin();

  // initialisierung
  Taster().initPullup();
  LedRed().init();
  LedYellow().init();
  LedGreen().init();

  LedRed()    = 1;
  LedYellow() = 0;
  LedGreen()  = 0;

  while(not stromausfall)
  {
    taskWaitFor(Taster()); // auf tastendruck warten
    LedRed()    = 0;
    LedYellow() = 1;
    LedGreen()  = 0;

    taskPause(ampeltakt);
    LedRed()    = 0;
    LedYellow() = 0;
    LedGreen()  = 1;

    taskPause(ampeltakt); // mindest green phase

    taskWaitFor(not Taster());    // auf taste loslassen warten

    taskPause(ampeltakt);
    LedRed()    = 0;
    LedYellow() = 1;
    LedGreen()  = 0;

    taskPause(ampeltakt);
    LedRed()    = 1;
    LedYellow() = 0;
    LedGreen()  = 0;
    
    taskPause(ampeltakt); // mindest red phase

  }
  taskEnd();
}


void setup(void)
{
}

void loop(void)
{
  ampel();
}

Ach ja...
Die Reihenfolge stimmt nicht ganz für dich, aber das wirst du schon umbauen können.
Nicht wahr?

CombieLib.zip (76.1 KB)

Wo finde ich die beiden library die oben gennant werden als taskmacro und combie, sonst lässt sich der sketch nicht laden. Besten Dank!!

Vielleicht in der Datei, welche ich da angehangen habe?

combie:
bei mir

Vorsicht, da wirst du eine Menge lernen müssen.

void setup(void)
{
}

void loop(void)
{
  ampel();
}

Im eigentlichen Sketch sieht man, dass man hier nichts sieht. Das ist elegant, es zwingt zum genauer hinschauen.
Das mit dem const bool stromausfall; ist übrigens nur Spaß :slight_smile:

Ja, das ist ein Gag.
... mit Geschichte ...

Und meinen Dank, für das "elegant" Attribut!
(geht runter wie Butter)

Den sketch habe ich soweit verstanden und dieser funktioniert auch, jetzt muss ich es nur noch schaffen diesen auf weitere Ampel zu übertragen. Besten Dank an Combie und alle anderen.

Den sketch habe ich soweit verstanden und dieser funktioniert auch,

Meinen?

Du, verstanden?
Glückwunsch!
Das ist das ein Hauptgewinn! (auch für mich)

jetzt muss ich es nur noch schaffen diesen auf weitere Ampel zu übertragen.

Ja, die Salami!
In möglichst dünne Scheiben schneiden.
Dann wird das Aroma am intensivsten und man kann am meisten aus einem solchen Thread herausholen.

Oder ohne jede Ironie:
Wäre das vorher ans Licht gekommen, hätte ich evtl eine skalierbare Variante hier gepostet.

Ja ich habe deinen verstanden, und die Ironie verstehe ich auch.

Man soll sich ja bekanntlich die guten Menschen ins Boot holen, bevor man ablegt.

#include <TaskMacro.h>
#include <CombiePin.h>


const bool stromausfall { false };
const unsigned long ampeltakt { 500 }; //ms

template<byte taster, byte red, byte yellow, byte green>
Task ampel()
{
  using LedRed    = Combie::Pin::OutputPin<red>;
  using LedYellow = Combie::Pin::OutputPin<yellow>;
  using LedGreen  = Combie::Pin::OutputPin<green>;
  using Taster    = Combie::Pin::TasterGND<taster>;
  taskBegin();

  // initialisierung
  Taster().initPullup();
  LedRed().init();
  LedYellow().init();
  LedGreen().init();

  LedRed()    = 1;
  LedYellow() = 0;
  LedGreen()  = 0;

  while (not stromausfall)
  {
    taskWaitFor(Taster()); // auf tastendruck warten
    LedRed()    = 0;
    LedYellow() = 1;
    LedGreen()  = 0;

    taskPause(ampeltakt);
    LedRed()    = 0;
    LedYellow() = 0;
    LedGreen()  = 1;

    taskPause(ampeltakt); // mindest green phase

    taskWaitFor(not Taster());    // auf taste loslassen warten

    taskPause(ampeltakt);
    LedRed()    = 0;
    LedYellow() = 1;
    LedGreen()  = 0;

    taskPause(ampeltakt);
    LedRed()    = 1;
    LedYellow() = 0;
    LedGreen()  = 0;
    
    taskPause(ampeltakt); // mindest red phase

  }
  taskEnd();
}


void setup(void)
{
}

void loop(void)
{
 //  ampel<taster,red,yellow,green>(); // muster
  ampel<2,11,12,13>();
  ampel<3,4,5,6>();
  ampel<A0,A1,A2,A3>();
}

Ja, in diesem Umbau ist das Temlplate nötig, da sich sonst alle Funktionen die geheimen versteckten statischen Variablen teilen.