Es geht darum, dass wenn man auf einen Button drückt, dann soll eine LED
dreimal blinken.
Wenn man während dem Blinken erneut auf den Button drückt, dann muss die
LED wieder 3x blinken.
Das ganze soll ohne blocking Code implementiert werden.
Wie man eine LED ohne blocking Code zum blinken bringt, habe ich bereits
gefunden.
https://www.arduino.cc/en/Tutorial/BuiltInExamples/BlinkWithoutDelay
Die LED soll aber dreimal blinken. Jetzt könnte man eine Schleife
verwenden, damit die LED 3x blinkt, aber dann hätte ich wieder implizit
blocking Code drin.
Wie kann man das ohne blocking Code implementieren?
Die einfachste Lösung ist eine Zustandsmaschine (state machine). Also
sich einfach global merken, ob die LED gerade nicht blinkt, das erste
Mal blinkt, das zweite Mal blinkt oder das dritte Mal blinkt. Und dann
bei Ablauf der Wartezeit (millis() überprüfen wie in deinem Beispiel)
die LED bedienen und den Zustand weiterschalten.
LG, Sebastian
Vielen Dank für eure bisherigen Antworten. Das hat mir weiter geholfen.
Eine Frage hätte ich noch. Wie realisiere ich den untenstehenden Punkt?
Wenn man während dem Blinken erneut auf den Button drückt, dann muss die
LED wieder von vorne 3x blinken.
Wie sagt der Meister: "Du sollst doch deinen Kopf benutzen".
Schau dir das Prinzip an, versuch es zu verstehen, dann kannst du es
selbst optimal umsetzen. Nicht einfach abschreiben....
Zur Frage:
Ist dir überlassen, wo du den Event "Button Pressed" verarbeitest.
Entweder du sagst, nur in einem bestimmten Zustand (z.B. LEDONSTATE)
wird der Button berücksichtigt, oder du machst es außerhalb des Switch,
dann setzt du einfach den Zustand/State zurück.
Du kannst auch sehr schön mehrere Switch-Blöcke ineinander verschachteln
um Sub-Statemachines zu machen.
(Das ist alles super-primitiv-Variante ich weiß)
Das Tolle an so einer Statemachine: Sie hat immer einen definierten
Zustand. Kommt ein externer Stimulus, der zu einer Zustandsänderung
führen soll, dann kann man einfach in einen anderen Zusatnd springen.
Im Fall von "auf Knopfdruck von vorne blinken" halt in den Zustand, mit
dem das Blinken beginnt.
Optimal ist es übrigens, wenn man so eine Statemachine im
Systick-Interrupt laufen lässt, dann hat man immer eine Zeitreferenz und
das Ding nimmt kaum Rechenzeit in Anspruch.
Nick schrieb:> Wenn man während dem Blinken erneut auf den Button drückt, dann muss die> LED wieder von vorne 3x blinken.
Das ist schlecht definiert.
Was genau soll passieren?
Das aktuelle blinken abbrechen?
Das aktuelle erst beenden?
Sagen wir Mal, du blinkt 1s an, 1s aus. Kurz vor Ende der ersten Sekunde
erkennst Du einen Tastendruck. Soll dann insgesamt
A) 6x geblinkt werden
B) 4x geblinkt werden
C) 3x geblinkt werden mit 2s an beim ersten mal
Thomas W. schrieb:> Voll der overkill:
Wieso overkill? Ich würde es vielleicht in mehre Prozeduren aufteilen,
aber ansonsten gefällt mir der Code so. Er ist übersichtlich,
nachvollziehbar und vor allem ausbaufähig.
{Add_Delayed_Event(100,tBlink);// Event nach 100 ms auslösen
22
Blink=5;
23
}
24
25
if(Event_avail())
26
{E=Get_Event();
27
if(E==tBlink)
28
{LED_einaus(E&1);// Bit 0 = Blinkbit
29
E--;
30
if(E)Add_Delayed_Event(300,tBlink);
31
}
32
33
...hierggf.anderweitigeEventsauswerten
34
}
35
...hierggf.anderesZeugserledigen
36
gotoelleweil;
So, jetzt brauchst du bloß noch eine Systemuhr in deiner Firmware und
eine kleine Event-Verwaltung. Sowas habe ich schon vor ewig hier mal
gepostet.
W.S.