Ich habe mir einen Countdown mit Starttaster, zwei Status-LEDs (grün => Countdown läuft; rot => Countdown läuft nicht) und einer LCD-Anzeige (Restzeit und Fortschrittsbalken) gebaut. Während der Countdown läuft ist der Taster blockiert.
Direkt nach dem Hochladen des Sketches funktioniert der Code noch wunderbar. Ein paar Minuten später startet der Countdown nur noch nach mehrmaligem Betätigen des Tasters. Außerdem stoppt der Countdown nicht mehr bei Null, sondern läuft ins Minus und der Fortschrittsbalken wird unberechenbar.
Aber für die if-Anweisung brauche ich ja Vergleichswerte wie die Start- und Endzeit.
Nein, die Endzeit brauchst du nicht.
Die ergibt sich automatisch, wenn sie erreicht wird, und dann ist früh genug.
Denn, die Endzeit würde eine Addition erfordern, und damit nagelst du dir eine Frikadelle ans Knie.
Der Countdown hat jetzt die unschöne Angewohnheit, dass der Startzeitpunkt verschieden ist. Je nach Wartezeit zum vorherigen Durchgang startet der Countdown nun bei weniger als 10 Sekunden.
Wie meinen?
Deine Fehlerbeschreibung sagt mir nicht viel.
Auch sehe ich in Deinen Sketch keine State-Maschine - Du benutzt zwar millis(), Das war's aber auch schon.
Z.B. wird, wenn 'button_pressed' true ist, tausend Mal die Sekunde das LCD aktualisiert - soll Das so?
Viel mehr als 10 Werte die Sekunde kannst Du eh nicht sehen - das Geflimmer der letzten Ziffern kann man dabei genauso gut simulieren und man spart sich 90% Zeit.
DAS wäre z.B. was für 'Blink_without'delay' - nur alle 97ms das Display zu aktualisieren.
Dein Haupt-Problem ist gerade, daß Du 'previous_millis' nicht beim Tastendruck auf millis() setzt - sofern der Countdown immer 'countdown' Millisekunden dauern soll, wäre Das schon Mal ein Schritt in die richtige Richtung - die Start-Bedingung beim Start richtig setzen.
Auch wird Dir der Countdown direkt durchstarten, wenn der Button betätigt bleibt - also einen Countdown von nur wenigen Millisekunden wirst Du so nicht hinbekommen - zumindest nicht als Einzeldurchlauf.
Ich meinte, dass der Countdown z.B. bei 8 und nicht bei 10 Sekunden gestartet ist, wenn man 2 Sekunden nach dem Ende des vorherigen Countdowns auf den Taster gedrückt hat. Dieses Problem besteht mittlerweile nicht mehr.
Ich habe den Code jetzt entsprechend überarbeitet:
Schlammcatcher:
Was ist der Vorteil einer State-Maschine?
Ein Vorteil ist, dass das ein Strickmuster ist, das dabei helfen kann, mehrere Sachen gleichzeitig zu erledigen. Für einen kurzen Blick genügt vielleicht mein Geschreibsel dazu.
Für meine 2 Zustände (Countdown läuft, Countdown läuft nicht) kommt mir das Strickmuster State-Maschine ziemlich überdimensioniert und unnötig kompliziert vor.
Bietet eine State-Maschine in meinem Fall tatsächlich einen Vorteil?
Schlammcatcher:
Bietet eine State-Maschine in meinem Fall tatsächlich einen Vorteil?
Dazu müsste ich mich mal in das reinlesen, was „Dein Fall“ denn überhaupt ist. Ich bin neu in diesem Thread.
Gruß
Gregor
PS: Auf die Schnelle: Du hast ja mit deutlich mehr als nur zwei Dingen zu tun. Teil der „State-Machine-Strategie“ ist, jeden Teil als Ding zu betrachten, das Zustände annehmen kann. Also z. B. Taster, LEDs, LC-Display (das D in LCD steht schon für Display - LCD-Display ist bissl viel) usw. Jedes dieser Dinger kannst Du als Klasse formulieren, d. h. eben als Ding, das Zustände annehmen und auf „Anforderung“ Informationen herausrücken kann. Was das Wesen objektorientierter Denke angeht, kann man sich ordentliche Knoten ins Hirn denken. Bist Du denn irgendwie Programmier-Erfahren?
Schlammcatcher:
Für meine 2 Zustände (Countdown läuft, Countdown läuft nicht) kommt mir das Strickmuster State-Maschine ziemlich überdimensioniert und unnötig kompliziert vor.
Bietet eine State-Maschine in meinem Fall tatsächlich einen Vorteil?
Eine gut programmierte State-Maschine läuft in deinem Fall geschmeidiger. Die Delay(100) sorgen dafür, dass dein Countdown eine 1/10tel Sekunde zu lang zählen kann. Auch solltest du die doppelten Tastendrücke anders als mit einer Delay(500) verhindern. Hier bietet sich eine Flankenerkennung an. Wenn die Taste im letzten Durchlauf gedrückt war und jetzt nicht mehr, wurde die Taste losgelassen und der Contdown kann starten. Zum Entprellen finde ich ein Delay(20) bei nicht zeitkritischen Anwendungen OK, aber nicht Delay(500). Eine State-Maschine kann man leichter erweitern. Z.B. mit einem kurzen Tastendruck wird der Countdown angehalten und mit langem abgebrochen.
Nicht zu Letzt kann man bei so einem kleinen Beispiel wunderbar das Programmieren einer State-Maschine üben. Man muss das Prinzip verinnerlichen. In umfangreichen Projekten kommt man ohne sie schnell in Sackgassen, wo man den ganzen Sketch nochmal komplett neu schreiben muss.