Arduino Mikrocontroller Tutorials - Softwaretechnik

Multitasking mit millis() statt delay()

Die delay()-Funktion wird in einem einfachen Programm ohne Verzweigungen verwendet um den Ablauf zeitweise zu pausieren. (Bsp. LED an, Pause, LED aus, Pause, …) . Um den delay(500)- Befehl umzusetzen wird der µC veranlasst wiederholt eine for-Schleife ohne zusätzliche Befehle zu durchlaufen. Solange bis die Anzahl der Durchläufe multipliziert mit dem Prozessortakt dann 500ms ergibt. Der Prozessor ist die ganze Zeit über (sinnlos) beschäftigt und kann dabei keine weiteren Aufgaben übernehmen (wie zum Beispiel einen Taster abfragen).
Abhilfe schafft ein Zeitstempel, welcher dann in einer if-Abfrage in jedem Loop überprüft wird ob dieser schon erreicht wurde. Erst wenn die Zeit erreicht ist, werden die Befehle in der if-Verzweigung ausgeführt. millis() ist übrigens ein Zähler, der ab dem Start oder Reset des Arduinos zu zählen beginnt.

Programmcode Möglichkeit 1 (nextTime)

Gleich innerhalb der if-Verzweigung wird die Zeit für die nächste Ausführung berechnet und in der Variablen 'nextTime' gespeichert. Dann wird bei jedem anschließenden 'Loop' Durchlauf geprüft ob die if-Bedingung mit der neuen Zeit bereits wieder erreicht wurde.

// Multitasking mit Timer (Bsp. LED toggeln) int interval = 500; // Interval vorgeben (hier 500ms) unsigned long nextTime; bool ledStatus = LOW; void setup() { pinMode(LED_BUILTIN, OUTPUT); } void loop() { if (millis() >= nextTime) { nextTime = millis() + interval; if (ledStatus == HIGH) { ledStatus = LOW; } else ledStatus = HIGH; digitalWrite(LED_BUILTIN, ledStatus); } // Weiterer Code... }

Programmcode Möglichkeit 2 (timeStamp)

Vom Prinzip handelt es sich hier um die gleiche Codeidee wie bei Möglichkeit 1. Nur wird hier ein Zeitstempel der letztmaligen Ausführung gesetzt. In der Bedingung für die if-Verzweigung ist dann die Berechnung für die neue Zeit.

// Multitasking mit Timer (Bsp. LED toggeln mit einem Zeitstempel) int interval = 500; // Interval vorgeben (hier 500ms) unsigned long timeStamp; // Zeitstempel bool ledStatus = LOW; void setup() { pinMode(LED_BUILTIN, OUTPUT); } void loop() { if (millis() >= timeStamp + interval) { // Speichert die Ausführungszeit timeStamp = millis(); // Toggeln in kurzer Schreibweise ohne Variablen digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN)); } // Weiterer Code.... }

Programmcode Möglichkeit 3 (Modulo)

Bei dieser Methode nutzt man den Modulo Operator, der bei einer Division immer den Rest angibt. Wenn man zum Beispiel eine Zahl durch 1000 teilt kann der Modulo Operator nur Werte zwischen 0 und sich selbst minus 1 (hier 999) zurück geben.

// Multitasking mit Timer (Bsp. LED toggeln mit dem Modulo Operator %) int interval = 500; // Interval vorgeben (hier 500ms) void setup() { pinMode(LED_BUILTIN, OUTPUT); } void loop() { // % liefert Werte zwischen 0 und 2x interval zurück (0-999) if (millis() % (2*interval) < interval) { // von 0 - 499 wird die LED angeschaltet digitalWrite(LED_BUILTIN, HIGH); } else digitalWrite(LED_BUILTIN, LOW); // von 500 - 999 wird die LED ausgeschaltet }