[Hilfe] Starte LED blinken nach buttonclick und aufhören nach weiterem click

Hallo, ich programmiere gerade eine Ampel und brauche Hilfe.
Ich möchte dass mein gelbes LED nach einem Buttonclick beginnt zu blinken, so lange bis der button ein weiteres mal geklickt wird.

Version - Startet blinken nach dem Buttonklick
Diese version funktioniert, ist aber nicht wie ich es mir vorstelle da es so lange gehen soll bis der Button wieder geklickt wird.

int carred = 8, caryellow = 9, cargreen = 10, pedred = 12, pedgreen = 13, pedbutton = 4, nightbutton = 5;
const int buzzer = 3;


void setup()
{  
 //LED init
  pinMode(carred, OUTPUT);
  pinMode(caryellow, OUTPUT);
  pinMode(cargreen, OUTPUT);
  pinMode(pedred, OUTPUT);
  pinMode(pedgreen, OUTPUT);
 //Button init
  pinMode(pedbutton, INPUT); 
   //Buzzer init
  pinMode(buzzer, OUTPUT);
  
 //LED default 
 //(car=green;pet=red)
  digitalWrite(carred, LOW);
  digitalWrite(caryellow, LOW);
  digitalWrite(cargreen, HIGH);
  digitalWrite(pedred, HIGH); 
  digitalWrite(pedgreen, LOW);  
}
 
 
//Buzzer Sound when Ped is green and car red 
void Pedgreentone(){
int i;

for(i=0;i<10;i++){ 
 tone(buzzer, 1000); 
 delay(500);         
 noTone(buzzer);     
 delay(500);      
}
} 
 
 
void loop()
{
int i;

 //Night-Button = 1 (on_click)
  if(digitalRead(nightbutton) == HIGH)
  { 
 delay(2000);
 digitalWrite(carred, LOW);  
 digitalWrite(cargreen, LOW); 
 digitalWrite(pedred, LOW); 
 digitalWrite(pedgreen, LOW); 
 
 //Yellow light blink
 for(i=0;i<10;i++){
 digitalWrite(caryellow, HIGH);    
 delay(1000);                        
 digitalWrite(caryellow, LOW);    
 delay(1000);   
 } 
  }


 //Ped-Button = 1 (on_click)
  if(digitalRead(pedbutton) == HIGH)
  {
 //(car=yellow;pet=red)
 delay(5000);
 digitalWrite(caryellow, HIGH);  
 digitalWrite(cargreen, LOW);
 
 //(car=red;pet=red)
 delay(2000);
 digitalWrite(caryellow, LOW);
 digitalWrite(carred, HIGH);
 
 //(car=red;pet=green)
 delay(2000);
 digitalWrite(pedgreen, HIGH);
 digitalWrite(pedred, LOW);
 Pedgreentone(); 
 
 //(car=red;pet=red) 
 digitalWrite(pedgreen, LOW);
 digitalWrite(pedred, HIGH);
 
 //(car=red+yellow;pet=red)
 delay(2000);
 digitalWrite(caryellow, HIGH); 
 
 //(car=green;pet=red)
 delay(2000);
 digitalWrite(carred, LOW); 
 digitalWrite(caryellow, LOW); 
 digitalWrite(cargreen, HIGH); 
  }
  
  
  //Ped-Button = 0
  else
  { 
    digitalWrite(pedred, HIGH); 
    digitalWrite(pedgreen, LOW);  
 digitalWrite(carred, LOW); 
 digitalWrite(caryellow, LOW); 
 digitalWrite(cargreen, HIGH); 
  }
}

Version - Starte das blinken nach dem Buttonklick, nach einem weiteren klicken soll aufgehört werden zu blinken.
Diese version funktioniert nicht. Das problem ist die funktion delay(); diese macht es unmöglich den buttonklick zu erkennen. Ich brauche eine Lösung dafür dass der Buttonklick erkannt wird. Ich hab es mit interupt versucht, konnte es aber nicht zum laufen bringen.

int carred = 8, caryellow = 9, cargreen = 10, pedred = 12, pedgreen = 13, pedbutton = 4, nightbutton = 5, nightstatus = 0;
const int buzzer = 3;


void setup()
{  
 //LED init
  pinMode(carred, OUTPUT);
  pinMode(caryellow, OUTPUT);
  pinMode(cargreen, OUTPUT);
  pinMode(pedred, OUTPUT);
  pinMode(pedgreen, OUTPUT);
 //Button init
  pinMode(pedbutton, INPUT); 
   //Buzzer init
  pinMode(buzzer, OUTPUT);
  
 //LED default 
 //(car=green;pet=red)
  digitalWrite(carred, LOW);
  digitalWrite(caryellow, LOW);
  digitalWrite(cargreen, HIGH);
  digitalWrite(pedred, HIGH); 
  digitalWrite(pedgreen, LOW);  
}
 
 
//Buzzer Sound when Ped is green and car red 
void Pedgreentone(){
int i;

for(i=0;i<10;i++){ 
 tone(buzzer, 1000); 
 delay(500);         
 noTone(buzzer);     
 delay(500);      
}
} 
 
 
void loop()
{
int i;

if(digitalRead(nightbutton) == HIGH)
  { 
  nightstatus++;
  }


 //Night-Button = 1 (on_click)
  if((nightstatus % 2) == 1)
  { 
 delay(2000);
 digitalWrite(carred, LOW);  
 digitalWrite(cargreen, LOW); 
 digitalWrite(pedred, LOW); 
 digitalWrite(pedgreen, LOW); 
 
 //Yellow light blink
 while((nightstatus % 2) == 1)
 {    
 digitalWrite(caryellow, HIGH);    
 delay(1000);                        
 digitalWrite(caryellow, LOW);    
 delay(1000);  
 if(digitalRead(nightbutton) == HIGH)
 { 
 nightstatus++;
 }
 }
  }


 //Ped-Button = 1 (on_click)
  if(digitalRead(pedbutton) == HIGH)
  {
 //(car=yellow;pet=red)
 delay(5000);
 digitalWrite(caryellow, HIGH);  
 digitalWrite(cargreen, LOW);
 
 //(car=red;pet=red)
 delay(2000);
 digitalWrite(caryellow, LOW);
 digitalWrite(carred, HIGH);
 
 //(car=red;pet=green)
 delay(2000);
 digitalWrite(pedgreen, HIGH);
 digitalWrite(pedred, LOW);
 Pedgreentone(); 
 
 //(car=red;pet=red) 
 digitalWrite(pedgreen, LOW);
 digitalWrite(pedred, HIGH);
 
 //(car=red+yellow;pet=red)
 delay(2000);
 digitalWrite(caryellow, HIGH); 
 
 //(car=green;pet=red)
 delay(2000);
 digitalWrite(carred, LOW); 
 digitalWrite(caryellow, LOW); 
 digitalWrite(cargreen, HIGH); 
  }
  
  
  //Ped-Button = 0
  else
  { 
    digitalWrite(pedred, HIGH); 
    digitalWrite(pedgreen, LOW);  
 digitalWrite(carred, LOW); 
 digitalWrite(caryellow, LOW); 
 digitalWrite(cargreen, HIGH); 
  }
}

Häufiges Thema.
delay stört (fast) immer.
Immerhin befiehlst du dem Controller nix zu tun, ja und das macht er doch auch brav.
Du brauchst eine "StateMaschine" die sich merkt welchen und wie oft du einen Knopf
gedrückt hast und entsprechend Zustände wechselt.
Suche für den Anfang mal nach "blink without delay".
Wenn du das Beispiel verstanden hast kommst du auch auf die Lösung deines Problems.

Ulli

Library ClickButton und OneButton, schau dir mal an.

arduinonub:
Hallo, ich programmiere gerade eine Ampel und brauche Hilfe.

Hier hast Du ein Programmbeispiel für zwei Pins:

BUTTONPIN zum Anschließen eines Tastschalters.

LEDPIN zum Anschließen einer LED.

Die Schaltung ist einfach und erfordert nur einen Vorwiderstand für die LED, aberKEINEN externen Pull-Widerstand für den Tastschalter.

Beschaltung des Tastschalters:

  • einen Pol des Tastschalters an BUTTONPIN
  • anderen Pol des Tastschalters an GND

Und jedesmal beim Schließen des Schalters wechselt das Programm die Variable 'blinking' zwischen true und false, und je nachdem wird entweder geblinkt oder nicht.

Hier der Code:

const byte BUTTONPIN=8 ;
const byte LEDPIN=13;

bool blinking=false;



bool buttonPressed()
{
 static unsigned long lastRunTime;
 static byte lastButtonState;
 if (millis()-lastRunTime<5) return false; // entprellen für max. 5ms Prellzeit
 lastRunTime=millis();
 bool result=false;
byte buttonState = digitalRead(BUTTONPIN);
 if (buttonState == LOW && lastButtonState == HIGH) result=true;
 lastButtonState=buttonState;
 return result;
}



void setup() 
{
  pinMode(BUTTONPIN,INPUT_PULLUP);
  pinMode(LEDPIN,OUTPUT);  


}

void loop() 
{
  if(buttonPressed()) blinking=!blinking; // invertieren beim Drücken des Tasters
  if(blinking) digitalWrite(LEDPIN,(millis()/500)%2); // blinken aktiv, Wechsel im Sekundentakt
  else digitalWrite(LEDPIN,LOW); // kein blinken aktiv
}

Wenn Du Fragen zum Code hast, einfach hier fragen.

Und ein kleiner Tipp noch: Sobald Du in einem Programm auch nur ein einziges mal den Idiotenbefehl "delay() verwendest, it es mit der Interaktivität vorbei.

Dann kannst Du nämlich nicht, so wie es mein Programmbeispiel macht, zweihundertmal pro Sekunde prüfen, ob ein Tastschalter gedückt wurde, und nebenbei noch diverse andere Dinge "gleichzeitig" machen, zum Beispiel eine LED blinken.

Und wenn Du eine Ampel programmieren möchtest: Hast Du Dir eigentlich schon einen Ampelphasen-Umlaufplan gemacht?

Wenn Du nämlich bei einer Ampelanlage keinen Plan hast, welches Licht an welcher Ampel in welcher Phase des Ampelumlaufs an sein soll, dann kannst Du das auch nicht programmieren.

Ohne Plan wird's wohl eher ein planloses an und aus an den Ampeln.

jurs:
Und ein kleiner Tipp noch: Sobald Du in einem Programm auch nur ein einziges mal den Idiotenbefehl "delay() verwendest, it es mit der Interaktivität vorbei.

Und wer delay() einen Idiotenbefehl nennt, ist ein Idiot.

Gruß

Gregor :wink:

delay() hat gleich wie goto() seine Berechtigung, aber nur in sehr speziellen Fällen.

Grüße Uwe

uwefed:
delay() hat gleich wie goto() seine Berechtigung, aber nur in sehr speziellen Fällen.

Ich widerspreche. Goto() ist wirklich sehr speziell. Warum es überhaupt ein goto() gibt, musste ich erst in meinem K+R nachsehen. Delay() ist vielleicht häufig unnötig oder gar störend, aber es entspricht halt sehr der Art, wie man als wenig oder gar nicht erfahrener Programmierer denkt.

Gruß

Gregor

jurs:

const byte BUTTONPIN=8 ;

const byte LEDPIN=13;

bool blinking=false;

bool buttonPressed()
{
static unsigned long lastRunTime;
static byte lastButtonState;
if (millis()-lastRunTime<5) return false; // entprellen für max. 5ms Prellzeit
lastRunTime=millis();
bool result=false;
byte buttonState = digitalRead(BUTTONPIN);
if (buttonState == LOW && lastButtonState == HIGH) result=true;
lastButtonState=buttonState;
return result;
}

void setup()
{
  pinMode(BUTTONPIN,INPUT_PULLUP);
  pinMode(LEDPIN,OUTPUT);

}

void loop()
{
  if(buttonPressed()) blinking=!blinking; // invertieren beim Drücken des Tasters
  if(blinking) digitalWrite(LEDPIN,(millis()/500)%2); // blinken aktiv, Wechsel im Sekundentakt
  else digitalWrite(LEDPIN,LOW); // kein blinken aktiv
}

Danke genau das hab ich gesucht!

arduinonub:
Danke genau das hab ich gesucht!

Danke für die Rückmeldung!

Leider sind Rückmeldungen von Themenstartern zu geposteten Codebeispielen inzwischen in diesem Forum selten geworden. Egal ob ich hier ein einfaches und kleines und schnell hingeschriebenes Programm ausarbeite und poste, oder ob ich erst umfangreich recherchieren, stundenlang programmieren und testen muss, um ein Programm mit einhundert, zweihundert, dreihundert oder noch mehrCodezeilen zu posten: Für inzwischen nahezu jeden drittenThemenstarter scheint es bereits zuviel zu sein, als Rückmeldung ein "Danke, das hat mir weitergeholfen" oder "danke, aber das hat mir NICHT weitergeholfen als Rückmeldung zu posten.

Und deshalb werde ich in nicht allzu ferner Zukunft in diesem Forum mein letztes Beispielprogramm gepostet haben, das ich für irgendeinen Themenstarter speziell geschrieben habe.

Und dann können sich die Neu-Themenstarter hier meinetwegen jeden Tag hundertfach gegenseitig zufufen "Ich bin Anfänger und brauche Hilfe beim Programmieren".

Das ist mir dann gleichgültig.

Ich habe hier fünf Jahre lang im Schnitt jede Woche ein bis zwei Beispielprogramme erstellt und ins Forum gepostet, zusammen sind das hunderte Codebeispiele.
Mal waren es nur wenige Zeilen, mal aber auch hunderte Codezeilen in einem einzigen Beispielprogramm.
Seit dem vergangenen Jahr bin ich dazu übergegangen: Wenn innerhalb von zwei Wochen nach dem Posten eines Beispielprogramms vom Themenstarter keine Rückmeldung gekommen ist, ob ihm der Code weiterhilft oder nicht, dann lösche ich das Beispielprogramm wieder. Seitdem blösche ich wohl jedes dritte hier gepostete Beispielprogramm von mir irgendwann nachträglich wieder, weil der Themenstarter einfach wortlos verschwindet, ohne kurze Rückmeldung, ob ihm das Beispielprogramm weiterhilft oder nicht.

Das geht mir total auf die Nüsse: Nicht nur das Schreiben der zahlreichen Beispielprogramme macht Arbeit, sondern auch das Nachscauen zweimal im Monat, ob die letzten geposteten Beispielprogramme von den Themenstartern inzwischen kommentiert wurden oder nicht. Und es ist frustrierend festzustellen, dass immer häufiger gepostete Beispielprogramme vom Themenstarter nicht kommentiert, sondern wortlos ignoriert werden. Und deshalb werde ich es hier bald genau so machen, wie es 99,99% der Forenteilnehmer machen: Ich werde KEINE Beispielprogramme mehr posten.

Wie gesagt, Danke für Deine Rückmeldung!
Aber es sind inzwischen zu viele Neuanmelder hier, die nur ein "Neues Thema" starten und jammern, dass sie Hilfe benötigen, aber wenn sie als Hilfestellung ein vollständiges Beispielprogramm erhalten, das hier im Forum diskutiert werden kann, sind sie weg und geben keinerlei Feedback/Rückmeldung.

Na ja, ich bin dann mal weg.

Und für die Foren-Neuanmelder die hier zukünftig Hilfe beim Programmieren erwarten, und von mir dann genau so wenig Beispielcode zur Verfügung gestellt bekommen wie von den 99,99% anderen Forenteilnehmern, die sowieso nie fertige Beispielprogramme posten, wird der Unterchied kaum wahrnehmbar sein: Ob ihr Ruf nach "Hilfe beim Programmieren" von 99,9% der Forenteilnehmer ignoriert wird oder von 100,0% der Forenteilnehmer, macht in der Praxis ja fast keinen Unterschied.
BYE