While Schleife durch Tastendruck oder abgelaufener zeit beenden

Hallo Zusammen.
Ich habe ein Problem, bei dem ich einfach nicht weiter komme. Wahrscheinlich ist es irgend ein "blöder Fehler" den ich einfach übersehe oder ich steh auf dem Schlauch. Ich hoffe ihr könnt mir helfen.

Ich möchte lediglich eine Warteschleife programmieren, die entweder durch die Betätigung einer Taste oder nach Ablauf einer bestimmten Zeit beendet wird. Ein LCD zeigt an durch welche Bedingung die Schleife verlassen wurde.

Im Voraus schon mal vielen Dank für eure Unterstützung.

#include <LiquidCrystal.h> //Bibliothek LCD hinzufügen

const int rs = 22, en = 23, d4 = 24, d5 = 25, d6 = 26, d7 = 27; //Pins um LCD anzusprechen
LiquidCrystal lcd(rs, en, d4, d5, d6, d7);

//Eingänge deklarieren
int Start = A0;

//sonstige Variablen
long currentMillis = 0; // Variable aktuelle Zeit
long previousMillis = 0; // Variable vergangene Zeit


void setup() {
  //Serielle Verbindung aufbauen
  Serial.begin(9600);

  //Eingänge konfigurieren
  pinMode(A0, INPUT_PULLUP);

  // LCD aktivieren und dessen Eigenschaften angeben + Serielle Verbindung aktivieren
  lcd.begin(16, 2);
  Serial.begin(9600);

  // Text am LCD ausgeben
  lcd.clear();
  lcd.print(" Versuchsaufbau");
  delay(2000);
  currentMillis = millis(); //Aktueller Zeitstempel speichern

  while ((digitalRead (Start) == HIGH) && (previousMillis - currentMillis < 5000)); //Warten auf Tastendruck oder Zeit abgelaufen ist
  {
    previousMillis = millis();
    Serial.println(previousMillis - currentMillis);//vergangene Zeit über Serielle Schnittstelle für Testzwecke ausgeben
  }

  if (digitalRead (Start) == LOW)
  {
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("Taste wurde");
    lcd.setCursor(0, 1);
    lcd.print("gedrueckt!");
  }
  else
  {
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("Zeit ist");
    lcd.setCursor(0, 1);
    lcd.print("abgelaufen!");
  }

  delay(5000); //kurze Pause bevor Textumschaltung

}


void loop() {
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("Im Hauptprogramm");
  lcd.setCursor(0, 1);
  lcd.print("angekommen");
  delay(5000);
}

Hallo,

wenn du Start mit A0 definierst, solltest du auch pinmode mit Start verwenden. Das am Rande.
Besser const byte Start = A0

Der Abbruch mit Taste sollte eigentlich funktionieren. Wobei es passieren kann das eine LCD Aktualisierung nicht mehr stattfindet. Je nachdem wer zuerst abfragt. Die while oder dein innerer Vergleich auf Low.

Dein Problem scheint zu sein das du previous mit current millis verwechselst und long statt unsigned long verwendest.

Ewiges lcd.clear ist auch nicht so toll, einfach die Zeile überschreiben ist schneller.

Das Semikolon ist zu viel:

while ((digitalRead (Start) == HIGH) && (previousMillis - currentMillis < 5000));

Hallo,

Arduuli:
Ich möchte lediglich eine Warteschleife programmieren, die entweder durch die Betätigung einer Taste oder nach Ablauf einer bestimmten Zeit beendet wird. Ein LCD zeigt an durch welche Bedingung die Schleife verlassen wurde.

Du brauchst eine Schleife die man mit 2 verschiedenen Bedienungen verlassen kann. Eine Bedienung ist die Zeit, also musst Du die Zeit auch definieren und Du brauchst ein "if" dazu, sprich: "Wenn 1 Minute nicht gedrückt werde verlasse ich die Schleife". Innerhalb dieser Minute musst Du permanent den Taster Abfragen. Wird der Taster gedrückt, in einer Variable speichern und raus aus der Schleife. Nach einer Minute bzw. die von Dir vordefinierte Zeit, ist Schluss. Das speicherst Du am besten in der selben Variable die zB: 'wieWurdeDieSchleifeVerlassen' heissen könnte <-Bitte nenne diese Variable nicht so das ist ja grauenhaft!
So und jetzt erst kommt das Display ins Spiel (ja initialisieren kannst/sollst Du es schon vorher.)

while(escape){

  if (tasterGedrueckt) {
    escape = ture;
    loopEscape = "taster"; // Bitte kein char nehmen, ist nur zur Veranschaulichung
  }
  if (zeitIstAbgelaufen) {
    escape = ture;
    loopEscape = "time"; // Bitte kein char nehmen, ist nur zur Veranschaulichung
  }

}

if(loopEscape == "time") { // 
  // Display print "time"
}
else {
  // Display print "taster"
}

Bitte schön... die Programmlogik. Ausprogrammieren darfst Du es selber. :wink: Fragen stellen übrigens auch.

edit: Das geht ja sogar noch einfacher:

while ((digitalRead (Start) == HIGH) && (previousMillis - currentMillis < 5000));

durch

while ((digitalRead (Start) == HIGH) || (previousMillis - currentMillis < 5000));

ersetzen.

Hoffentlich habe ich jetzt keinen Denkfehler drinnen. :sleeping: gn8

Grüße,
Donny

War nicht der Strichpunkt am ende dieser Zeile falsch?
Dieser schließt die While-Schleife sofort und dadurch bezieht sich der while nicht auf den nachfolgenden Code in geschwungen Klammern.
Grüße Uwe

Guten morgen,

uwefed:
War nicht der Strichpunkt am ende dieser Zeile falsch?
Dieser schließt die While-Schleife sofort und dadurch bezieht sich der while nicht auf den nachfolgenden Code in geschwungen Klammern.

Aber natürlich! Danke Uwe!
Ein Grund mehr (zumindest für mich) die geschwungene Klammer NICHT erst in er nächsten Zeile zu haben.

while ((digitalRead (Start) == HIGH) || (previousMillis - currentMillis < 5000)) { // <- So ist das doch übersichtlicher? IMHO
// Code der während der while ablaufen soll
}

Wenn eine UND (&&) Verknüpfung drinnen ist, muss zuerst die Zeit Ablaufen UND dann erst 'darfst' Du drücken. Was Du auch musst um die while zu verlassen!
Bei der ODER (||) Verknüpfung tritt der gewünschte Effekt auf.

Grüße,
Donny

dony:
Hoffentlich habe ich jetzt keinen Denkfehler drinnen. :sleeping: gn8

Doch, hast Du. Nur das ";" muß weg, ich habe es probiert.

Bitte ausschlafen und dann betrachte nochmal Deinen Beitrag. Der Taster ist LOW-aktiv, daher stimmt auch das UND.

agmue:
Bitte ausschlafen....

Ja, damit hast Du wirklich Recht.

Sorry!

agmue:
Das Semikolon ist zu viel:

ja ja das leidvolle Semikolon. Wenigstens einer der aufpasst. :slight_smile: Wobei ich sagen muss. Die Vermischung von previous und current millis wird ihm irgendwann auf die Füße fallen, weil die Variablen nicht mehr das machen was der Name suggeriert. long mit unsigned long vermischen genauso. Das sollte man nicht unter den Tisch fallen lassen.

Doc_Arduino:
Wenigstens einer der aufpasst. :slight_smile:

Der Prozessor zwischen den Ohren brauchte Unterstützung vom UNO, um es zu sehen :slight_smile:

Doc_Arduino:
Das sollte man nicht unter den Tisch fallen lassen.

Keinesfalls ;D

Hallo zusammen.
Vielen Dank für eure gute und vor allem schnelle Hilfe. Es lag tatsächlich an dem Semikolon.
Jetzt kann ich unbeschwert an meinem Programm weiter basteln.

LG