Ein Countdown soll die verbleibende Wartezeit anzeigen

Lieber Tommy56,

Danke für den Tipp mit dem +T! Das spart einem häufiges Leerzeichen- Drücken:D.
Danke auch für den Tipp mit der Pin- Vergabe, ich habe diese geändert.

Mit dem komischen Aussehen meine ich folgendes:

Bei "WAIT", sieht das ganze so aus (so wie es sein sollte):

Und bei "PLAY" sieht das ganze so aus (komisch):

Der Countdown erscheint übrigens garnicht mehr auf dem LCD. Kann mir jemand sagen wo der Fehler liegt?

Und hier der besser lesbare Code:

// LiquidCrystal Library

#include <LiquidCrystal.h>

int s = 60;                                     // Wert für Variable s  = 60
int m = 29;                                     // Wert für Varaible m = 30
unsigned long timestore_Sekunden;               // Variabler Speicher für Systemzeit

unsigned long timestore;                        // Variabler Speicher für Systemzeit
int KompressorStatus = LOW;                     //Kompressor is normally off
int KompressorPin = 2;
int VentilStatus = LOW;                         //Ventil is normally closed
int VentilPin = 3;

//initialize the library with the numbers of the interface pins
LiquidCrystal lcd(7, 8, 9, 10, 11, 12);


void setup() {

  lcd.begin(16, 2);
  pinMode (2, OUTPUT);                            //Kompressor
  pinMode (3, OUTPUT);                            //Ventil

}

void loop() {

  if (millis() - timestore > 1800000) {
    timestore = millis();
  }

  // 1. Vorbereitungsphase: Kompressorkessel wird aufgefüllt. Das Kompressorventil ist geschlossen. Auf dem LCD wird während dieser Phase "WAIT" angezeigt.

  if (KompressorStatus == LOW) {                  // wenn der Kompressor aus ist
    if (millis() - timestore > 0) {         // auf die Uhr sehen, ob die 0 Minuten schon rum sind, wenn ja
      digitalWrite(KompressorPin, HIGH);            // Kompressor einschalten
      KompressorStatus = HIGH;                      // notieren, dass der Kompressor angeschaltet ist
    }
  } else {                                        // wenn der Kompressor an ist
    if (millis() - timestore > 300000) {            // auf die Uhr sehen ob die 5 Minuten schon rum sind, wenn ja
      digitalWrite (KompressorPin, LOW);            // Kompressor ausschalten
      KompressorStatus = LOW;                       // notieren, dass der Kompressor ausgeschaltet ist
      lcd.clear();


      // 2. Spielphase: Das Ventil ist geöffnet, dadurch wird das Spiel mit Druckluft versorgt. Während des Spiels wird auf dem LCD "PLAY" angezeigt.

      digitalWrite (VentilPin, HIGH);               // Ventil öffnen
      VentilStatus = HIGH;                          // notieren, dass das Ventil geöffnet ist
    }                                              // wenn die 5 Minuten noch nicht rum sind: weitergehen
  }

  if (VentilStatus == HIGH) {                     // wenn das Ventil geöffnet ist
    if (millis() - timestore > 600000) {          // auf die Uhr sehen, 10 Minuten schon rum sind, wenn ja
      digitalWrite(VentilPin, LOW);                 // Ventil öffnen
      VentilStatus = LOW;                           // notieren, dass das Ventil geschlossen ist
      lcd.clear();
    }
  }



  // Spielpause: Jetzt soll der Countdown, der im Hintergrund abläuft auf dem LCD erscheinen. Ich habe den Countdown an eine if- Bedingung geknüpft, dass dieser nur auf dem LCD erscheint, wenn KompressorStatus und VentilStatus == LOW sind.

  if (millis() - timestore_Sekunden > 1000) {     // wenn eine Sekunde vergangen ist...
    s = s - 1;                                    // wird s um 1 dezimiert
    timestore_Sekunden = millis();                // dann wird timestore_Sekunden = millis()
  }

  if (s == 0) {                                    // wenn s bei 0 angekommen ist
    s = 60;                                       // wird s wieder 60
    m = m - 1;                                    // gleichzeitig wird m um eins dezimiert
  }

  if ( m == 0) {                                   // wenn m bei 0 angekommen ist
    m = 30;                                         // wird m wieder 30
  }

  if (KompressorStatus == HIGH) {                 // während der Kompressor eingeschaltet ist wird "WAIT" auf dem LCD angezeigt
    lcd.setCursor(0, 0);                          // Beginn beim ersten Zeichen in der ersten Zeile
    lcd.print("WAIT");                            // mit dem Text „WAIT“
  }
  if (VentilStatus == HIGH) {                   // während das Ventil geöffnet ist wird "PLAY" auf dem LCD angezeigt
    lcd.setCursor(0, 0);                          // Beginn beim ersten Zeichen in der ersten Zeile
    lcd.print("PLAY");                            // mit dem Text „PLAY“
  }

  if (millis() - timestore_Sekunden > 600000 && millis() - timestore_Sekunden < 1800000 ) { // Wenn die 10 Minuten vergangen sind (in denen der Kompressor Druck aufgebaut hat (5 Minuten) und das Ventil geöffnet war (5 Minuten), dann...
    lcd.setCursor(0, 0);                                // Startposition der Darstellung auf dem LCD festlegen. lcd.setCursor(0,0) bedeutet: Erstes Zeichen in der ersten Zeile.
    lcd.print("time to next game:");                    // Dort soll der Text „time to next game: “ erscheinen.
    lcd.setCursor(0, 1);                                // Startposition der Darstellung auf dem LCD festlegen.
    lcd.print(m);                                       // Dort soll die variable m erscheinen.
    lcd.print (":");                                    // dann der Text ":"
    lcd.print(s);                                       // dann s
  }
}

Du schreibst immer von Kompressor und Magnetventil. Wie steuerst Du die denn an?
Da könnten Störungen einstreuen. Es könnte auch einfach nur ein Wackelkontakt sein.

Gruß Tommy

Ich werde den Kompressor und das Magnetventil jeweils über ein Relais ansteuern. Die Relais sind aber noch nicht an den µC angeschlossen.

Dann kann ich mir eigentlich nur Wackelkontakt, kalte Lötstelle oder defektes Display vorstellen.
Mach doch mal einen ganz einfavhen Sketch:

#include <LiquidCrystal.h>

LiquidCrystal lcd(7, 8, 9, 10, 11, 12);

void setup() {
  lcd.begin(16, 2);
  lcd.clear();
}

void loop() {
    lcd.setCursor(0, 0);                          // Beginn beim ersten Zeichen in der ersten Zeile
    lcd.print("WAIT");                            // mit dem Text „WAIT"
    delay(1000);
    lcd.setCursor(0, 0);                          // Beginn beim ersten Zeichen in der ersten Zeile
    lcd.print("PLAY");                            // mit dem Text „PLAY"
    delay(1000);
}

Tritt das damit immer noch auf?

Gruß Tommy

Hi

Deine 08/15-Grafik - genial :slight_smile:
Eigentlich schade, Das nun doch mit einem µC zu machen ... ist ein Güde-Kompressor, wa?

Das Display- entweder das Display selber - das Zebra-Gummi ist nicht fest (zwiaschen Platine und Glas) - alternativ passt der Kontrast nicht (denke ich aber eher nicht).

Verbesserungspotential:

  • s und m werden die 60 nicht überschreiten - byte wäre dicke ausreichend (spart je ein Byte Platz)
  • Status (Mehrzahl ebenfalls) Kompressor und Ventil würde boolean reichen - kann nur true und false aufnehmen, nimmt sich trotzdem ein Byte Platz - immerhin nur die Hälfte vom int. (HIGH und LOW ist identisch mit TRUE und FALSE - als Zahlwert Beides gleich)
  • Pins werden wohl auch unter 256 angesiedelt sein - byte reicht. Da sich Diese während der Laufzeit nicht ändern, auch const. const byte KompressorPin=2;
  • Du definierst die Pins, benutzt in setup() aber wieder 'magic numbers' - also irgend welche zahlen, wo Keiner weiß, wo Die her kommen. Packe dort ebenfalls die Namen Deiner Pins rein - also z.B. pinMode(KompressorPin,OUTPUT);
  • millis() - timestore > 0 Das trifft 'nahezu immer' zu - einzig eine Millisekunde nach dem (Neu)Start nicht - kannst Du Dir somit auch sparen denk
  • hattest Du den Sketch schon laufen? Denke, Dein Kompressor geht nur für wenige ms aus - danach greift die obere IF und schaltet den Kompressor wieder an - oder?

Wäre immer noch dafür, Das in STATUS abzuhalten.

  • Status=Start
    -> Kompressor an, Status='warte_auf_Ende_Laufzeit_Kompressor'
    ->Kompressor AUS, Ventil AUF, Status= 'warte_auf_Ende_Laufzeit_Ventil'
    ->Ventil ZU, Status='Countdown'
    ->Uhrzeit anzeigen, wenn sich was geändert hat - bei 0 status=start

Auch wird der Kompressor nur im Status 'Start' eingeschaltet, wie im Status 'warte_auf_Ende_Laufzeit_Kompressor' ausgeschaltet, wie das Ventil angesteuert.

Wenn Dein Sketch So läuft - und Dir Das so reicht - lasse Es so!
Jeder Sketch, Der macht, was Du willst, ist ein guter Sketch (auch mit delay() und so Kram).

MfG

PS: Wenn Du das Display NUR mit Strom verbindest - Du bekommst die Hälfte des Display weiße Balken angezeigt (typisches Zeichen für eine fehlende Initialisierung) - sind diese Balken ebenfalls löchrig?

Mit dem komischen Aussehen meine ich folgendes:

Das Play schaut aus wie ein WAIT mit einem PLAY schnell abgewechselt.
Bist Du sicher daß Du nur PLAY draufschreibst oder in schneller folge WAIT und PLAY?
Grüße Uwe

Deshalb hatte ich ihm ja zu dem einfachen Testsketch geraten, um einen Defekt auszuschließen.

Gruß Tommy

Danke für Eure Antworten!

Ich habe den Testsketch laufen lassen. Der funktioniert ohne Probleme! Ich befürchte auch, dass sich "WAIT" und "PLAY" in schneller Folge abwechseln.

Hi

Dazu ein Blick in den aktuellen Sketch?
Dort müsste ja zu sehen sein, WO das Play und das Wait her kommen und warum Diese zur gleichen Zeit ausgegeben werden.

MfG

LeonardoFiando:
Ich habe den Testsketch laufen lassen. Der funktioniert ohne Probleme!

Damit können wir ein defektes Display ausschließen und wohl auch Kabel und Lötstellen. Das war das Ziel der Übung.

Gruß Tommy

Hänge doch hier mal mserielle Ausgaben rein:

if (KompressorStatus == HIGH) {                 // während der Kompressor eingeschaltet ist wird "WAIT" auf dem LCD angezeigt
    lcd.setCursor(0, 0);                          // Beginn beim ersten Zeichen in der ersten Zeile
    lcd.print("WAIT");                            // mit dem Text „WAIT"
    Sereil.println("WAIT");
  }
  if (VentilStatus == HIGH) {                   // während das Ventil geöffnet ist wird "PLAY" auf dem LCD angezeigt
    lcd.setCursor(0, 0);                          // Beginn beim ersten Zeichen in der ersten Zeile
    lcd.print("PLAY");                            // mit dem Text „PLAY"
    Sereil.println("PLAY");
  }

Ins setup dafür noch ein

Serial.begin(9600);

rein und auf dem seriellen Monitor kontrollieren.

Gruß Tommy

#24:

  • hattest Du den Sketch schon laufen? Denke, Dein Kompressor geht nur für wenige ms aus - danach greift die obere IF und schaltet den Kompressor wieder an - oder?

Ich habe Deinen Rat befolgt Tommy56,

ich kann jetzt auch im seriellen Monitor sehen, dass sich "WAIT" und "PLAY" dauernd abwechseln. Und nun leuchtet mir auch ein, dass es daran liegt, dass die oberste If- Funktion:

  if (KompressorStatus == LOW) {                  // wenn der Kompressor aus ist
    if (millis() - timestore > 0) {                // auf die Uhr sehen, ob die 0 Minuten schon rum sind, wenn ja
      digitalWrite(KompressorPin, HIGH);            // Kompressor einschalten
      KompressorStatus = HIGH;                      // notieren, dass der Kompressor angeschaltet ist
    }
  } else {                                        // wenn der Kompressor an ist
    if (millis() - timestore > 300000) {            // auf die Uhr sehen ob die 5 Minuten schon rum sind, wenn ja
      digitalWrite (KompressorPin, LOW);            // Kompressor ausschalten
      KompressorStatus = LOW;                       // notieren, dass der Kompressor ausgeschaltet ist
      lcd.clear();

sofort wieder erfüllt ist nachdem der Kompressor kurz ausgegangen ist. Aber wie kann ich das ändern?
Muss ich wie Du sagst ,postmaster-ino, auf den State-machine- Aufbau wechseln, oder lässt sich mein Vorhaben mit dem jetzigen Sketch doch noch irgendwie realisieren?

Ich habe die Verbesserungsvorschläge befolgt, die du mir in #24 gegeben hast, der Sketch sieht jetzt so aus:

void setup() {
  
  Serial.begin(9600);
  lcd.begin(16, 2);
  pinMode (KompressorPin, OUTPUT);                            //Kompressor
  pinMode (VentilPin, OUTPUT);                                //Ventil

}

void loop() {

  if (millis() - timestore > 1800000) {
    timestore = millis();
  }

  // 1. Vorbereitungsphase: Kompressorkessel wird aufgefüllt. Das Kompressorventil ist geschlossen. Auf dem LCD wird während dieser Phase "WAIT" angezeigt.

  if (KompressorStatus == LOW) {                  // wenn der Kompressor aus ist
    if (millis() - timestore > 0) {                // auf die Uhr sehen, ob die 0 Minuten schon rum sind, wenn ja
      digitalWrite(KompressorPin, HIGH);            // Kompressor einschalten
      KompressorStatus = HIGH;                      // notieren, dass der Kompressor angeschaltet ist
    }
  } else {                                        // wenn der Kompressor an ist
    if (millis() - timestore > 300000) {            // auf die Uhr sehen ob die 5 Minuten schon rum sind, wenn ja
      digitalWrite (KompressorPin, LOW);            // Kompressor ausschalten
      KompressorStatus = LOW;                       // notieren, dass der Kompressor ausgeschaltet ist
      lcd.clear();


      // 2. Spielphase: Das Ventil ist geöffnet, dadurch wird das Spiel mit Druckluft versorgt. Während des Spiels wird auf dem LCD "PLAY" angezeigt.

      digitalWrite (VentilPin, HIGH);               // Ventil öffnen
      VentilStatus = HIGH;                          // notieren, dass das Ventil geöffnet ist
    }                                              // wenn die 5 Minuten noch nicht rum sind: weitergehen
  }

  if (VentilStatus == HIGH) {                     // wenn das Ventil geöffnet ist
    if (millis() - timestore > 600000) {          // auf die Uhr sehen, 10 Minuten schon rum sind, wenn ja
      digitalWrite(VentilPin, LOW);                 // Ventil öffnen
      VentilStatus = LOW;                           // notieren, dass das Ventil geschlossen ist
      lcd.clear();
    }
  }



  // Spielpause: Jetzt soll der Countdown, der im Hintergrund abläuft auf dem LCD erscheinen. Ich habe den Countdown an eine if- Bedingung geknüpft, dass dieser nur auf dem LCD erscheint, wenn KompressorStatus und VentilStatus == LOW sind.

  if (millis() - timestore_Sekunden > 1000) {     // wenn eine Sekunde vergangen ist...
    s = s - 1;                                    // wird s um 1 dezimiert
    timestore_Sekunden = millis();                // dann wird timestore_Sekunden = millis()
  }

  if (s == 0) {                                    // wenn s bei 0 angekommen ist
    s = 60;                                       // wird s wieder 60
    m = m - 1;                                    // gleichzeitig wird m um eins dezimiert
  }

  if ( m == 0) {                                   // wenn m bei 0 angekommen ist
    m = 30;                                         // wird m wieder 30
  }

  if (KompressorStatus == HIGH) {                 // während der Kompressor eingeschaltet ist wird "WAIT" auf dem LCD angezeigt
    lcd.setCursor(0, 0);                          // Beginn beim ersten Zeichen in der ersten Zeile
    lcd.print("WAIT");                            // mit dem Text „WAIT“
    Serial.println("WAIT");
  }
  if (VentilStatus == HIGH) {                   // während das Ventil geöffnet ist wird "PLAY" auf dem LCD angezeigt
    lcd.setCursor(0, 0);                          // Beginn beim ersten Zeichen in der ersten Zeile
    lcd.print("PLAY");                            // mit dem Text „PLAY“
    Serial.println("PLAY");
  }

  if (millis() - timestore_Sekunden > 600000 && millis() - timestore_Sekunden < 1800000 ) { // Wenn die 10 Minuten vergangen sind (in denen der Kompressor Druck aufgebaut hat (5 Minuten) und das Ventil geöffnet war (5 Minuten), dann...
    lcd.setCursor(0, 0);                                // Startposition der Darstellung auf dem LCD festlegen. lcd.setCursor(0,0) bedeutet: Erstes Zeichen in der ersten Zeile.
    lcd.print("time to next game:");                    // Dort soll der Text „time to next game: “ erscheinen.
    lcd.setCursor(0, 1);                                // Startposition der Darstellung auf dem LCD festlegen.
    lcd.print(m);                                       // Dort soll die variable m erscheinen.
    lcd.print (":");                                    // dann der Text ":"
    lcd.print(s);                                       // dann s
  }
}

So wechseln sich "WAIT" und "PLAY" zwar nicht mehr im seriellen Monitor ab, aber "PLAY" wird leider nicht auf dem LCD angezeigt.

if (KompressorStatus == LOW) {                  // wenn der Kompressor aus ist
    if (millis() - timestore > 0&& millis() - timestore < 300000) {                // auf die Uhr sehen, ob die 0 Minuten schon rum sind, wenn ja
      digitalWrite(KompressorPin, HIGH);            // Kompressor einschalten
      KompressorStatus = HIGH;                      // notieren, dass der Kompressor angeschaltet ist
    }
  } else {                                        // wenn der Kompressor an ist
    if (millis() - timestore > 300000) {            // auf die Uhr sehen ob die 5 Minuten schon rum sind, wenn ja
      digitalWrite (KompressorPin, LOW);            // Kompressor ausschalten
      KompressorStatus = LOW;                       // notieren, dass der Kompressor ausgeschaltet ist
      lcd.clear();

Hi

Welche Zustände hast Du denn?
Kompressor LOW und Ventil LOW
Kompressor HIGH und Ventil LOW
Kompressor LOW und Ventil HIGH

Also einen Schritt wieder zurück.
Würde hier nur das Ventil mit in die obere Kompressor-Abfrage mit rein nehmen, dann sollte Das vorerst wieder 'tun'.

Ansonsten - wenn Du den ganzen Kram - dieses Mal OHNE 08/15-Elektronik :wink: - von Hand machen müsstest - WAS würdest Du WANN tun?
Wovon hängt Es ab, WANN Du den nächsten Schritt machst?
Und schon bist Du bei einer Schritt-Kette/State-Maschine/endlichem Automaten.
Dein Sketch ist gar nicht so weit davon entfernt - vll. nicht die gelungenste State Maschine, aber wir nähern uns.

MfG

LeonardoFiando:
So wechseln sich "WAIT" und "PLAY" zwar nicht mehr im seriellen Monitor ab, aber "PLAY" wird leider nicht auf dem LCD angezeigt.

Und wo sind die print-Ausgaben? Wie sollen wir Dir helfen, wenn wir immr nur Bröckchen bekommen, wo man das eigentliche Problem nicht sieht?

Ich verliere langsam Die Lust mit Dir.

Gruß Tommy

Ich habe das Löschen des LCD jetzt mal anders gelöst und dann wird auch das Play auf dem LCD richtig angezeigt.

 if (millis() - timestore == 300000) {
        lcd.clear();
      }

Ob das mit dem Abbilden des Countdown, nach dem zweiten Löschen des LCD

if (millis() - timestore == 600000) {
    lcd.clear();

auch funktioniert, kann ich leider noch nicht sagen. Dafür muss ich warten, bis genügend millis() abgelaufen sind...

Sorry Tommy56,

tut mir Leid. Meinst Du mit print- Ausgaben den Text aus dem seriellen Monitor?

Wenn Du auf einem LCD an der gleichen Position 4 Zeichen mit 4 neuen Zeichen überschreiben willst, brauchst Du überhaupt kein lcd.clear().

Gruß Tommy

Ich habe den Sketch nochmal verändert und auch vom Aufbau übersichtlicher gestaltet:

// LiquidCrystal Library
#include <LiquidCrystal.h>
//initialize the library with the numbers of the interface pins
LiquidCrystal lcd(7, 8, 9, 10, 11, 12);

// Variablen für Countdown

byte s = 60;                                        // Wert für Variable s  = 60
byte m = 29;                                        // Wert für Varaible m = 29
unsigned long timestore_Sekunden;                   // Variabler Speicher für Sekunden

// Variablen für zeitlichen Ablauf (Zyklus) von Kompressor, Ventil und Countdown

unsigned long timestore;                            // Variabler Speicher für 30 Minuten
boolean KompressorStatus = LOW;                     // Kompressor is normally off
const byte KompressorPin = 2;
boolean VentilStatus = LOW;                         // Ventil is normally closed
const byte VentilPin = 3;


void setup() {

  lcd.begin(16, 2);
  pinMode (KompressorPin, OUTPUT);                          //Kompressor
  pinMode (VentilPin, OUTPUT);                              //Ventil

}

void loop() {

  // Hier wird der Countdown geregelt

  if (millis() - timestore_Sekunden > 1000) {     // wenn eine Sekunde vergangen ist...
    s = s - 1;                                    // wird s um 1 dezimiert
    timestore_Sekunden = millis();                // dann wird timestore_Sekunden = millis()
  }

  if (s == 0) {                                    // wenn s bei 0 angekommen ist
    s = 60;                                       // wird s wieder 60
    m = m - 1;                                    // gleichzeitig wird m um eins dezimiert
  }


  // 1. Vorbereitungsphase: Kompressorkessel wird aufgefüllt. Das Kompressorventil ist geschlossen. Auf dem LCD wird während dieser Phase "WAIT" angezeigt.

  if (KompressorStatus == LOW) {                                                   // wenn der Kompressor aus ist
    if (millis() - timestore > 0 && millis() - timestore < 300000) {               // auf die Uhr sehen, ob die 0 Minuten schon rum sind, wenn ja
      digitalWrite(KompressorPin, HIGH);                                           // Kompressor einschalten
      KompressorStatus = HIGH;                                                     // notieren, dass der Kompressor angeschaltet ist
    }
  } else {                                                                         // wenn der Kompressor an ist
    if (millis() - timestore > 300000) {                                           // auf die Uhr sehen ob die 5 Minuten schon rum sind, wenn ja
      digitalWrite (KompressorPin, LOW);                                           // Kompressor ausschalten
      KompressorStatus = LOW;                                                      // notieren, dass der Kompressor ausgeschaltet ist
    }
  }

  if (KompressorStatus == HIGH) {                                                 // während der Kompressor eingeschaltet ist wird "WAIT" auf dem LCD angezeigt
    lcd.setCursor(0, 0);                                                          // Beginn beim ersten Zeichen in der ersten Zeile
    lcd.print("WAIT");                                                            // mit dem Text „WAIT“
  }


  // 2. Spielphase: Das Ventil ist geöffnet, dadurch wird das Spiel mit Druckluft versorgt. Während des Spiels wird auf dem LCD "PLAY" angezeigt.

  if (VentilStatus == LOW) {                                                      // wenn das Ventil geschlossen ist
    if (millis() - timestore > 300000 && millis() - timestore < 600000) {         // auf die Uhr sehen, ob die 5 Minuten schon rum sind, wenn ja
      digitalWrite(VentilPin, HIGH);                                              // Ventil öffnen
      VentilStatus = HIGH;                                                        // notieren, dass das Ventil geöffnet ist
    }
  } else {                                                                        // wenn das Ventil geöffnet ist
    if (millis() - timestore > 600000) {                                          // auf die Uhr sehen ob die 5 Minuten ( in den das Ventil offen war )schon rum sind, wenn ja
      digitalWrite (VentilPin, LOW);                                              // Ventil schließen
      VentilStatus = LOW;                                                         // notieren, dass das Ventil geschlossen ist
    }
  }

  if (VentilStatus == HIGH) {                                                     // während das Ventil geöffnet ist wird "PLAY" auf dem LCD angezeigt
    lcd.setCursor(0, 0);                                                          // Beginn beim ersten Zeichen in der ersten Zeile
    lcd.print("PLAY");                                                            // mit dem Text „PLAY“
  }

  if (millis() - timestore == 600000) {                                           // Wenn genau 10 Minuten vergangen sind, LCD löschen
    lcd.clear();
  }


  // Spielpause: Jetzt erscheint der Countdown, der im Hintergrund abläuft auf dem LCD. Der Countdown ist an eine if- Bedingung geknüpft, so dass dieser nur auf dem LCD erscheint, wenn KompressorStatus und VentilStatus == LOW sind.

  if (millis() - timestore > 600000 && millis() - timestore < 1800000 ) {                   // Wenn 10 Minuten vergangen sind (in denen der Kompressor Druck aufgebaut hat (5 Minuten) und das Ventil geöffnet war (5 Minuten), dann...
    lcd.setCursor(1, 0);                                                                    // Startposition der Darstellung auf dem LCD festlegen. lcd.setCursor(0,0) bedeutet: Zweites Zeichen in der ersten Zeile.
    lcd.print(" next game in :");                                                           // Dort soll der Text „time to next game: “ erscheinen.
    Serial.println(" next game in :");
    lcd.setCursor(5, 1);                                                                    // Startposition der Darstellung auf dem LCD festlegen. Sechstes Zeichen in der zweiten Zeile.

    if (m < 10) {                                                                           // wenn m kleiner als 10, dann...
      lcd.print('0');                                                                       // schreibe erst eine Null
      lcd.print(m);                                                                         // und dann die Minuten
    } else {                                                                                // ansonsten
      lcd.print(m);                                                                         // schreibe die Minuten normal
    }

    lcd.print (":");                                                                        // dann der Text ":"

    if (s < 10) {                                                                           // wenn s < 10 dann...
      lcd.print('0');                                                                       // schreibe erst eine Null
      lcd.print(s);                                                                         // und dann die Sekunden
    } else {                                                                                // ansonsten
      lcd.print(s);                                                                         // schreibe die Sekunden normal
    }

  }


  // Und am Ende wird alles wieder zurückgesetzt

  if (millis() - timestore == 1800000) {                  // Wenn 30 Minuten abgelaufen sind, dann...
    timestore = millis();                                 // werden wieder 30 Minuten runtergezählt
    s = 60;                                               // Der Variablen s wird wieder der Wet 60 zugeordnet
    m = 29;                                               // Der Variablen m wird wieder der Wert 29 zugeordnet
    lcd.clear();                                          // Wenn genau 30 Minuten vergangen sind, LCD löschen
  }
}

Jetzt erscheint auf dem LCD immer das was ich will. Zumindest wenn die millis(), also die Anzahl der Millisekunden seit dem Programmstart, nicht den Wert von 1800000 überschritten haben. Ich lasse den Sketch jetzt mal bis heute Abend laufen. Dann sollte sich zeigen, ob es irgendwo noch einen Fehler gibt. Wenn jemandem davor schon irgendeine Unstimmigkeit auffällt, lasst es mich wissen.

Lieber postmaster-ino und lieber Tommy56, danke für Eure Geduld!:slight_smile:

Herzliche Grüße Leonardo

Ich habe eben einen Schmarrn erzählt. Das Programm funktioniert leider doch nicht mal richtig bis 1800000 ms vergangen sind.

Das hier bleibt auf dem LCD stehen: "next game in : 00:04."

Es muss auf jeden Fall an dieser if Bedingung hier liegen. Ich kann mir das aber leider nicht so richtig erklären:D.

  // Und am Ende wird alles wieder zurückgesetzt

  if (millis() - timestore == 1800000) {                  // Wenn 30 Minuten abgelaufen sind, dann...
    timestore = millis();                                 // werden wieder 30 Minuten runtergezählt
    s = 60;                                               // Der Variablen s wird wieder der Wet 60 zugeordnet
    m = 29;                                               // Der Variablen m wird wieder der Wert 29 zugeordnet
    lcd.clear();                                          // Wenn genau 30 Minuten vergangen sind, LCD löschen
  }

So hat es davor glaube ich noch funktioniert:

 // Und am Ende wird alles wieder zurückgesetzt

  if (millis() - timestore > 1800000) {                  // Wenn 30 Minuten abgelaufen sind, dann...
    timestore = millis();                                 // werden wieder 30 Minuten runtergezählt
    s = 60;                                               // Der Variablen s wird wieder der Wet 60 zugeordnet
    m = 29;                                               // Der Variablen m wird wieder der Wert 29 zugeordnet
    lcd.clear();                                          // Wenn genau 30 Minuten vergangen sind, LCD löschen
  }

Was mich auch noch sehr wundert ist, dass bei einer abgelaufenen Programmzeit von 1800000 ms, der Countdown erst bei 00:04 angekommen ist. Kann mir jemand sagen, wie ich meinen Countdown mit der abgelaufenen Programmzeit so synchronisiert kriege, dass millis() - timestore und abgelaufene 1800000 ms einander genau dann entsprechen, wenn der Countdown bei 00:00 angekommen ist?

Vielen Dank und herzliche Grüße Leonardo