bei Tastendruck Sketch nur ein mal abspielen

Hallo miteinander,

habe einen Taster der als Auslöser für mein Programm dienen soll, das Programm soll aber nur ein mal abgespielt werden wenn der Taster gedrückt wird.

Problematik, auch wenn der Taster nicht wider los gelassen wird soll das Programm nicht wider von neuen Starten.
erst wenn das Programm durchgelaufen ist und der Taster danach nicht noch immer gedrückt ist kann / soll das Programm wider Start fähig sein.

Version 1:
Angenommen ich Drücke den Taster und lasse Ihn nicht wider los dann soll das Programm nur ein mal durchlaufen und nicht in einer Dauerschleife laufen.

Version 2:
Angenommen ich drücke den Taster 5 mal schnell hintereinander und halte Ihn dann immer noch gedrückt (das Programm braucht länger für einen Durchlauf) dann soll das Programm auch nur ein mal abgespielt werden.

Version 3:
Angenommen ich drücke den Taster nur ein mal Kurz, dann soll das Programm ein mal abgespielt werden.

was für alle gleich ist. wenn ich nach dem das Programm durchgelaufen ist den Taster erneut Drücke soll das Programm wider abgespielt werden.

habe das auch schon mal gemacht, doch heute ist mir dabei ein Fehler aufgefallen, wie ich das auch hin bekommen,
das Programm Läuft ein mal durch so wie es das auch nur soll, doch manchmal Startet es dann noch mal wenn ich den Taster los lasse :frowning:

Angenommen ich Drücke den Taster 5 mal hintereinander und halte Ihn dann Gedrückt dann läuft das Programm ein mal durch und Startet wider wenn ich den Taster nach Durchlauf des Programms los lasse. Was mich wundert das ist nicht immer so, keine Ahnung was ich da Falsch mache.

Das ist mein Code habe alles raus geschmissen was gerade mal unwichtig ist,
und der Fehler kommt dennoch :frowning:

Code Versuch 1:

int startPin  = A4;   // Starttaster
int Lauf      = 0;    // Kurzzeitgedächtnis 
   
void setup() 
  {
    pinMode(startPin, INPUT);
  }  

void loop() 
{  
  if(digitalRead(startPin) == HIGH && Lauf == 0)
   {
    Lauf = 1;
    for (int i=2; i < 11; i++)
     {
      pinMode(i,OUTPUT);       // Pin als Ausgang definiren
      digitalWrite(i, HIGH);   // LED an
      delay(300);              // Pause
      digitalWrite(i, LOW);    // LED aus 
     }
   }
  else if (digitalRead(startPin) == LOW && Lauf == 1) {Lauf = 0;}
}

Code Versuch 2:

int startPin  = A4;   // Starttaster
int Lauf      = 0;    // Kurzzeitgedächtnis 
   
void setup() 
  {
    pinMode(startPin, INPUT);
  }  

void loop() 
{  
  if (Lauf == 0) 
   {
     if(digitalRead(startPin) == HIGH)
     {
      Lauf = 1;
      for (int i=2; i < 11; i++)
       {
         pinMode(i,OUTPUT);       // Pin als Ausgang definiren
         digitalWrite(i, HIGH);   // LED an
         delay(300);              // Pause
         digitalWrite(i, LOW);    // LED aus 
       }
     }
   }  
  else if (digitalRead(startPin) == LOW && Lauf == 1) {Lauf = 0;}
}

bei beiden Codes habe ich das Problem.

ich dachte mir das ich mir den Zustand des Tasters merke
und erst nach dem Durchlauf des Programms den Zustand wider abfrage
und frei geben muss, ich bin auch davon überzeugt das das der Richtige weg ist
mir ist nur nicht klar warum beim tasten loslassen das Programm noch mal durchlaufen wird.

wie gesagt das passiert nicht immer.

Kann mir da jemand etwas weiterhelfen?

Gruß Mücke

Es gibt ne ClickButton Lib und OneButton Lib.

Gut für Anfänger, man kanns aber auch anders sehen, denn man lernt da nicht viel.

Das könnte funktionieren, muss aber nicht. Habe es ohne zu testen ebend verfasst.

void function()
{
  // Taster einlesen
  int8_t button_value = digitalRead(button);
  static int8_t first_run;
  static uint32_t last_millis;

  if(button_value && !first_run) 
  { 
    first_run = 1;
    // Einfaches Debouncing sollte hier ausreichen
    delay(30); 
    last_millis = millis(); 
  }
  else if(!buton_value && first_run) 
  {
    first_run = 0;

    for(int8_t i = 2; i <= 10; i++) digitalWrite(i, 0); // Led an Pin 2 - 10
  }

  if(first_run)
  {
    static uint32_t last_millis2;
    uint8_t value = (millis() - last_millis) / 300;
    static uint8_t last_value;

    // Wenn Modus Max erreicht hat, abbrechen 
    // value >=  LED Anzahl * 2 (High/LOW) 
    if(value >= 16) 
    {
      first_run = 0;   
      // Leds zurücksetzen
      for(int8_t i = 2; i <= 10; i++) digitalWrite(i, 0); // Led an Pin 2 - 10      
    }
    else if(last_value != value)
    {
      last_value = value;
      digitalWrite(2+(value/2), value%2);
    }
  }
}

Servus Mücke!

Ich muss gestehen, dass ich mir das Programm nicht genau angesehen habe - ich habe nur eine Idee, warum das Programm manchmal startet und manchmal nicht: Wenn du den Taster loslässt, prellt er kurz und daher startet die Schleife. Vermeiden kann man das, indem man den Taster nach dem Erkennen des Loslassens zB 10ms wartet bevor man wieder die Taste abfragt.

lg, Robert

@sschultewolter: Öm ja, ok, verstehe nichts. :frowning:

@flyingangel: habe eine Pause von 10ms eingebaut, bisher konnte ich das Phänomen nicht wider sehen oder provozieren, ich hoffe das es das war.

@skorpi08: was es alles gibt, ich glaube das es nur etwas überdimensioniert ist für meine Anwendung.

Danke euch allen. für die Schnelle Antwort, werde das jetzt mal so weiter Testen und schauen ob das Problem noch mal auftritt oder nicht. Danke

Muecke, könntest du mal genau schreiben, was du nun hinbekommen musst?

Version 1:
Angenommen ich Drücke den Taster und lasse Ihn nicht wider los dann soll das Programm nur ein mal durchlaufen und nicht in einer Dauerschleife laufen.

Version 2:
Angenommen ich drücke den Taster 5 mal schnell hintereinander und halte Ihn dann immer noch gedrückt (das Programm braucht länger für einen Durchlauf) dann soll das Programm auch nur ein mal abgespielt werden.

Version 3:
Angenommen ich drücke den Taster nur ein mal Kurz, dann soll das Programm ein mal abgespielt werden.

was für alle gleich ist. wenn ich nach dem das Programm durchgelaufen ist den Taster erneut Drücke soll das Programm wider abgespielt werden.

Sehe ich das so richtig.

Variante 1: Solange Taster gedrückt, sollen die LEDs EINMAL hochzählen, ansonsten aus.
Variante 2: mit Modus 3 realisierbar.
Variante 3: Wenn Taster kurz gedrückt wurde, sollen die LEDs EINMAL hochzählen. ansonsten aus.

Alle 2(3) Varianten brauchst du? Dann würde ich mich gleich mal ransetzen und das Aufbauen und entsprechend vielleicht der Code etwas weiter mit Kommentaren ausschmücken. ^^

Wieso solls überdeminseoniert sein?
Da haste Taster entprellt, doppelklick, dreifachklick, lange halten, alles was dein Herz begehrt.

das mit dem

delay(10);

scheint zu reichen :slight_smile:

glaube der begriff Version ist glaube ich Falsch gewählt gewesen.

das mit den LED`s ist nur als Platzhalter drin, da kann alles mögliche stehen.

Ich hatte das Problem das ich mit einem Taster meine Tropfenbox ausgelöst habe,
jedoch nicht immer sofort wider vom Taster herunter gegangen bin, oder
vor lauter Aufregung öfter gedrückt habe bevor das "Programm" der Ablauf der
Ventile und Blitze / Kamera vollständig abgearbeitet wurde.

und wenn ich denn Taster dann nach Ablauf des "Programms" losgelassen habe
wurde mein "Programm" sofort wider ausgeführt jedoch wurde das nicht immer
gemacht.

Das mit dem Sleep war es anscheinend ich habe bisher keine Probleme mehr :slight_smile:

@skorpi08: das benötige ich alles nicht für meine aktuelle Anwendung.
und scheinbar klappt es mit dem delay(10);
daher ist alles andere zu viel :smiley:

@Mücke: freut mich geholfen zu haben :slight_smile:

lg, Robert

manchmal sind es die Kleinen Dinge die zählen :wink: