Unterschiede
Hier werden die Unterschiede zwischen zwei Versionen angezeigt.
decoder:code:programmieren-ohne-delay [08.12.2024 21:53] – angelegt Martin Fitzel | decoder:code:programmieren-ohne-delay [Unbekanntes Datum] (aktuell) – Externe Bearbeitung (Unbekanntes Datum) 127.0.0.1 | ||
---|---|---|---|
Zeile 1: | Zeile 1: | ||
+ | ====== Programmieren ohne ‚delay‘ ====== | ||
+ | Eines der einfachsten Programme für einen Mikroprozessor ist der „Blink“-Sketch, | ||
+ | |||
+ | // the setup function runs once when you press reset or power the board | ||
+ | void setup() { | ||
+ | // initialize digital pin LED_BUILTIN as an output. | ||
+ | pinMode(LED_BUILTIN, | ||
+ | } | ||
+ | // the loop function runs over and over again forever | ||
+ | void loop() { | ||
+ | digitalWrite(LED_BUILTIN, | ||
+ | delay(1000); | ||
+ | digitalWrite(LED_BUILTIN, | ||
+ | delay(1000); | ||
+ | } | ||
+ | |||
+ | |||
+ | Eine LED wird im Sekunden-Takt ein- und ausgeschaltet, | ||
+ | |||
+ | LED einschalten | ||
+ | 1000 Millisekunden warten | ||
+ | LED ausschalten | ||
+ | 1000 Millisekunden warten … | ||
+ | |||
+ | | ||
+ | |||
+ | Versucht der Programmier-Einsteiger nun, dieses Programm z.B. um weitere LEDs zu erweitern, so stößt er schnell auf die Problematik der Abhängigkeit und erhält auf seine Fragen die lapidare Antwort „schau´ Dir ‚BlinkWithoutDelay an‘ – da ist das Prinzip erklärt“. | ||
+ | |||
+ | Zwar ist m.E. im zugehörigen Tutorial https:// | ||
+ | |||
+ | Anstelle der Befehlskette | ||
+ | |||
+ | Pizza in die Mikrowelle | ||
+ | 10 Minuten warten | ||
+ | Pizza aus der Mikrowelle holen | ||
+ | eMail prüfen | ||
+ | |||
+ | prüft man z.B. alle 2 Minuten die eMails und kommt zu der Befehlskette | ||
+ | |||
+ | Pizza in die Mikrowelle | ||
+ | eMail prüfen | ||
+ | 2 Minuten warten | ||
+ | eMail prüfen | ||
+ | 2 Minuten warten | ||
+ | eMail prüfen | ||
+ | 2 Minuten warten | ||
+ | eMail prüfen | ||
+ | 2 Minuten warten | ||
+ | eMail prüfen | ||
+ | 2 Minuten warten | ||
+ | Pizza aus der Mikrowelle holen | ||
+ | |||
+ | Wenn man sich das bildlich vorstellt, wird schnell klar, dass so niemand arbeitet und dass das spätestens dann nicht mehr funktioniert, | ||
+ | |||
+ | Schon in dem einfachen ‚Blink‘-Programm steht als Kommentar „the loop function runs over and over again forever” – und genau darum geht es: Die Ausführung des Programms nicht anzuhalten, sondern ganz gezielt Befehle auszuführen, | ||
+ | |||
+ | Genau das macht ‚BlinkWithoutDelay‘ nun für die LED – es prüft endlos, ob die Zeit bis zum nächsten Umschalten abgelaufen ist und wenn das Ergebnis „ja“ lautet, wird es ausgeführt: | ||
+ | |||
+ | void loop() { | ||
+ | unsigned long currentMillis = millis(); | ||
+ | if (currentMillis - previousMillis >= interval) { // Zeitintervall abgelaufen ? | ||
+ | previousMillis = currentMillis; | ||
+ | if (ledState == LOW) { // LED umschalten | ||
+ | ledState = HIGH; | ||
+ | } | ||
+ | else{ | ||
+ | ledState = LOW; | ||
+ | } | ||
+ | digitalWrite(ledPin, | ||
+ | } | ||
+ | } | ||
+ | |||
+ | Beim Blinken einer LED sieht man nun leider tatsächlich keinerlei Vorteil – das Programm erscheint dem Einsteiger nur viel unübersichtlicher. Ich habe es daher mal für 5 LEDs an einem ATtiny85 erweitert. Für den Einsatz auf einem Arduino sind natürlich auch mehr als 5 LEDs möglich und die Portnummern anzupassen. Das Programm ist nur unwesentlich größer, kann aber nun 5 LEDs unabhängig mit verschiedenen Frequenzen und unsymmetrisch (High-Low-Verhältnis) blinken lassen, weil pausenlos nacheinander für alle LEDs geprüft wird, ob sie geschaltet werden müssen – das ist mit Verwendung von ‚delay‘ so nicht mehr zu realisieren. | ||
+ | |||
+ | int ledZahl = 5; // Anzahl der LEDs | ||
+ | int ledPin[] = {0, 1, 2, 3, 4}; // Pins der LEDs | ||
+ | unsigned long currentMillis = 0; | ||
+ | unsigned long previousMillis[] = {0, 0, 0, 0, 0}; | ||
+ | int interval[] = {750, 800, 850, 950, 1000}; | ||
+ | int highlowq[] = {5, 5, 5, 2, 2}; | ||
+ | void setup() { | ||
+ | for (int i = 0; i < ledZahl; i++) { | ||
+ | pinMode(ledPin[i], | ||
+ | } | ||
+ | } | ||
+ | void loop() { | ||
+ | currentMillis = millis(); | ||
+ | for (int i = 0; i < ledZahl; i++) { | ||
+ | previousMillis[i] = currentMillis; | ||
+ | digitalWrite(ledPin[i], | ||
+ | } | ||
+ | else if(currentMillis - previousMillis[i] > interval[i]/ | ||
+ | digitalWrite(ledPin[i], | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | |||
+ | Der prinzipielle Aufbau eines Programms ohne ‚delay‘ unterscheidet sich also grundlegend von Befehlsketten mit ‚delay‘ – und deshalb kann man ein Programm auch kaum „mal eben umschreiben“. Bei der Erstellung eines Programms ist es also sinnvoll, schon von Anfang an möglichst ohne ‚delay‘ zu arbeiten – sowohl um das Prinzip zu lernen, als auch um später bei Erweiterungswünschen nicht wieder komplett von vorne beginnen zu müssen. |