LED soll erst Blinken und dann an Bleiben

Hallo zusammen,
ich möchte gerade einen endlichen Automaten programmieren.

Momentan kann ich mit dem Schalter die LED an machen, aber sie geht dann nicht mehr aus & blinkt durchgehend.

Kann mir jemand zeigen wo hier mein Fehler ist?

Ziel ist, eine LED soll zuerst aus sein -> wenn der Taster des erste mal gedrückt wurde soll sie für eine bestimmte Zeit Blinken -> dann soll sie Dauerleuchten -> wenn der Taster das zweite mal gedrückt wurde soll sie wieder für eine bestimmte Zeit blinken -> dann aus bleiben

Das ganze läuft auf einem Arduino Uno

bool geschaltet = false;
int led = 13;        
int taster = 5;         
int Abfrage = 250;
 
void setup() {
 
  pinMode( taster, INPUT_PULLUP); 
  pinMode( led, OUTPUT);           
 
}
 
void loop() {
 
  if (digitalRead(taster) == LOW)  
  {
    if (geschaltet == false) {        
      geschaltet = true;             
    }
    else {
      geschaltet = false;             
    }
  }
 
  if (geschaltet == true) {   // LED soll hier für eine bestimmte Zeit blinken, dann auf HIGH bleiben       
    digitalWrite(led, HIGH);
    delay (1000);
    digitalWrite(led, LOW);
    delay (1000);
    digitalWrite(led, HIGH);
          
          
  }
 
  if (geschaltet == false) {  // LED soll hier für eine bestimmte Zeit blinken, dann auf LOW bleiben               
    digitalWrite(led, LOW);
    delay (1000);
    digitalWrite(led, HIGH);
    delay (1000);
    digitalWrite(led, LOW);

  }
 
  delay(Abfrage);             
}

Strukturiere deine Angabe ein wenig:

Ziel ist, eine LED soll zuerst aus sein → wenn der Taster des erste mal gedrückt wurde soll sie für eine bestimmte Zeit Blinken → dann soll sie Dauerleuchten → wenn der Taster das zweite mal gedrückt wurde soll sie wieder für eine bestimmte Zeit blinken → dann aus bleiben

Welche Status ergeben sich dadurch?
Wie benennst du sie?
Was passiert im jeweiligen Status
Durch welchen Event wird der Status verlassen bzw. in welchen wechselst du

noiasca:
Welche Status ergeben sich dadurch?
Wie benennst du sie?
Was passiert im jeweiligen Status
Durch welchen Event wird der Status verlassen bzw. in welchen wechselst du

meinst du so?

bool geschaltet = false;  // dient zum Speichern des Schaltzustands
int led = 13;             // led1 ist an Pin13 angeschlossen
int taster = 5;           // Taster an Pin 5
int Abfrage = 250;        // Abfrage speichert wie oft der Taster abgefragt wird
 
void setup() {
 
  pinMode( taster, INPUT_PULLUP); // Taster als Eingang definiert
  pinMode( led, OUTPUT);          // led als Ausgang definiert 
 
}
 
void loop() {
 
  if (digitalRead(taster) == LOW)  // Abfrage ob der Taster gedrückt ist
  {
    if (geschaltet == false) {     // Abfrage ob der logische Schalter aus ist   
      geschaltet = true;           // wenn ja, wird er auf true geschaltet 
    }
    else {
      geschaltet = false;          // wenn nein, auf false   
    }
  }
 
  if (geschaltet == true) {   // Taster wird das erste mal gedrückt -> Zustand auf True
    digitalWrite(led, HIGH);  // LED geht an   
    delay (1000);             // LED blinkt
    digitalWrite(led, LOW);
    delay (1000);
    digitalWrite(led, HIGH);  // LED dauer an
          
          
  }
 
  if (geschaltet == false) {  // Taster wird das zweite mal gedrückt -> Zustand auf False
    digitalWrite(led, LOW);   // LED blinkt
    delay (1000);
    digitalWrite(led, HIGH);
    delay (1000);
    digitalWrite(led, LOW);   // LED bleibt aus

  }
 
  delay(Abfrage);             
}

nein. Ich meine so etwas hättest dir aufmalen sollen:

Status    zu tun           verlassen bei       nächster Status
--------------------------------------------------------------
AUS       button lesen     button gedrückt     BLINKEN
BLINKEN   LED blinken      Zeitablauf 3sec     EIN
EIN       button lesen     button gedrückt     AUS

verstanden?

simons_arduinoprojects:
meinst du so?


noiasca hats schon beantwortet - ich hab dann noch eine Anmerkung:
Warum müsst ihr immer soviele unnütze Leerzeolen und so verschobenen Code ausgeben.
Drückt doch bitte STRG-T bevor ihr das hierher kopiert.

So und nu mal die Frage aller Fragen:
Wenn Du sowieso für alles die gleichen Zeiten nimmst, kannst das auch abkürzen.
Nun, es ist immernoch delay dabei und wenn Du lange auf die Taste drückst, wird das nicht abgefangen.

int led = 13;             // led1 ist an Pin13 angeschlossen
int taster = 5;           // Taster an Pin 5
int Abfrage = 250;        // Abfrage speichert wie oft der Taster abgefragt wird

void setup()
{
  pinMode (taster, INPUT_PULLUP); // Taster als Eingang definiert
  pinMode (led, OUTPUT);         // led als Ausgang definiert
}

void loop()
{
  if (digitalRead (taster) == LOW) // Abfrage ob der Taster gedrückt ist
  {
    digitalWrite (led, !digitalRead (led));
    delay (1000);                          
    digitalWrite (led, !digitalRead (led));
    delay (1000);
    digitalWrite (led, !digitalRead (led));
  }
  delay (Abfrage);
}

noiasca:
verstanden?

Ah okay, ja jetzt hab ichs verstanden, sorry :slight_smile:

my_xy_projekt:
noiasca hats schon beantwortet - ich hab dann noch eine Anmerkung:
Warum müsst ihr immer soviele unnütze Leerzeolen und so verschobenen Code ausgeben.
Drückt doch bitte STRG-T bevor ihr das hierher kopiert.

So und nu mal die Frage aller Fragen:
Wenn Du sowieso für alles die gleichen Zeiten nimmst, kannst das auch abkürzen.
Nun, es ist immernoch delay dabei und wenn Du lange auf die Taste drückst, wird das nicht abgefangen.

Moin, danke auch für deine Antwort.

Ich bin absoluter Anfänger und schon froh wenn mein Sketch so läuft wie ich mir das vorstell. In zukunft kann ich das mit STRG+T aber gerne machen.

noiasca:
Da kann ich jetzt natürlich nicht mehr mithalten.

Wieso? (nicht). Ist doch schick - mit Abfangroutine.
Aber ich sehe, das Du das Artisticstyle angepasst hast :wink: :wink: :wink:

noiasca:
ungetestet, der Poster soll ja auch noch ein wenig Spaß haben.

Danke Noiasca - ich verstehe grad nur noch nicht wie ich das CheckButton im Sketch richtig definieren kann - ist es dann auch wieder ein 'bool'?

Was für funktionen hat es?

verstehe deine Frage nicht.
checkButton liefert ein bool.
checkButton kontrolliert auf Tastendruck und liefert true oder false zurück.
checkButton wird im Code an zwei Stellen aufgerufen.

noiasca:
verstehe deine Frage nicht.
checkButton liefert ein bool.
checkButton kontrolliert auf Tastendruck und liefert true oder false zurück.
checkButton wird im Code an zwei Stellen aufgerufen.

checkbutton ist im sketch nicht declared

wenn ich ihn als bool definier & in die klammern true/false schreib kommt die Fehlermeldung das checkButton nicht als Funktion benutzt werden kann.

eher ein tippfehler oder? checkButton
mein Sketch kompiliert ja auch.

noiasca:
eher ein tippfehler oder? checkButton
mein Sketch kompiliert ja auch.

jup - stimmt, deswegen hat er nicht kompiliert.

Trotzdem schaltet die LED nich komplett ab..

Trotzdem schaltet die LED nich komplett ab..

in welchem zustand - bei welcher Aktivität?
Was schreibt dabei der Serial-Monitor raus?

Was passiert genau? fängt wieder zum blinken an, oder?
Hast du irgendwas am Sketch verändert? ja dann poste ihn.

noiasca:
in welchem zustand - bei welcher Aktivität?
Was schreibt dabei der Serial-Monitor raus?

Was passiert genau? fängt wieder zum blinken an, oder?
Hast du irgendwas am Sketch verändert? ja dann poste ihn.

Er leuchtet immer Dauerhaft, wenn ich ihn drücke blinkt er und leuchtet dann wieder dauerhaft.
Sketch ist unverändert.

Serial Monitor:

button pressed
19:29:59.015 -> Ende Blinken - Dauer ein
19:30:01.947 -> button pressed
19:30:01.947 -> button pressed
19:30:04.942 -> Ende Blinken - Dauer ein

naja siehst eh, du musst schneller den Button loslassen.

.
.
.
.
.
Scherzerl, ja da musst den Button doch debouncen / auf Status-Änderung abfragen.
Schaffst du das? Da gibts ein entsprechendes Beispiel in der IDE.

noiasca:
in welchem zustand - bei welcher Aktivität?
Was schreibt dabei der Serial-Monitor raus?

Hi, kann es sein, das das tastenprellen Dir dazwischenfunkt?

Wenn hier:

    case State::LEUCHTEN :
      if (checkButton())
      {
        digitalWrite(ledPin, LOW);
        state = State::AUS;
      }
      break;
  }

hier die Taste prellt, kommt als nächstes:

    case State::AUS :
      if (checkButton())
      {
        state = State::BLINKEN;
        previousMillis = millis();
      }
      break;

Bei bool checkButton() wird ein bounce nicht vermieden.
Das könnte zu dem Effekt führen.

@TO!
Schiebe bitte - in der Reihenfolge - neue Zeilen ein:
nach Zeile 45 wird eine neue Zeile 46;
Serial.println(F("State: Leuchten"));

nach Zeile 30 wird eine neue Zeile 31:
Serial.println(F("State: Blinken"));

nach Zeile 22 wird eine neue Zeile 23:
Serial.println(F("State: aus"));

Gib die Ausgaben vom SerMon mal her.

/OK ich geb zu, ich war zu langsam...

naja ich hab ja gewusst wo es krankt :wink:
das kommt davon wenn man abkürzungen macht.

in etwa so.

Teilfertiger Sketch entfernt. Kommt noch im laufe des Threads was besseres.

noiasca:
naja ich hab ja gewusst wo es krankt :wink:
das kommt davon wenn man abkürzungen macht.

:wink:

Ich geb zu, ich hab auch so angefangen. Mich aber maßlos drüber geärgert.
Trotzdem mal versucht eine Abkürzung zu bauen.
Mich würde interessieren, ob der TO Lust hat, die Funktion mal auszutauschen und zurück gibt, obs funktioniert - ich hab leider nichts hier....

bool checkButton()   // mit debounce
{
  static uint32_t lastDebounceTime = 0;  // the last time the output pin was toggled
  static bool lastButtonState = HIGH;     // the previous reading from the input pin

  if ((digitalRead(buttonPin)!=lastButtonState) && (millis() - lastDebounceTime) > debounceDelay) {
    lastDebounceTime = millis();
    lastButtonState = !lastButtonState;
  }
  return lastButtonState;
}

noiasca:
in etwa so.
Wieder ungetestet.

funktioniert überhaupt nicht mehr.. Ich find auch keinen Fehler..

Der Serielle Monitor spuck nur das aus:

20:23:11.066 -> FSM Grundgerüst