In diesem Beitrag dreht sich alles um die effiziente Programmierung von Timern für Arduino. Timergesteuerte Funktionen spielen eine wichtige Rolle in vielen Arduino-Projekten, sei es für präzise Zeitsteuerung oder wiederkehrende Aufgaben. Ich werde Dir zeigen, wie Du die externe „Timer“-Bibliothek nutzen kannst, um diese Herausforderungen elegant zu bewältigen. Entdecke eine verbesserte Lösung im Vergleich zu herkömmlichen Ansätzen und erfahre, wie Du Deine Arduino-Projekte mit den richtigen Zeitintervallen bereichern kannst. Als zusätzliche Unterstützung findest Du auch ein Schritt-für-Schritt-Erklärungsvideo, das Dir den Einstieg erleichtert.
Im Beitrag Arduino: Ein Sketch ohne delay(ms) schreiben hatte ich Dir bereits eine Lösung aufgezeigt, wie Du ohne den Funktionsaufruf „delay“ einen Programmabschnitt ausführen kannst. Hier möchte ich diese Ideen aufgreifen und Dir eine weitere Lösung zeigen.
Inhaltsverzeichnis
Einlegen einer Pause mit Boardmitteln
Zunächst möchte ich Dir nochmal zeigen, wie Du eine kleine Pause in Deinem Programm mit den Boardmitteln der Arduino IDE bzw. der Sprache einlegen kannst.
delay
Die wohl einfachste Form ist der Aufruf der Funktion delay. Hier legt der gesamte Mikrocontroller eine Pause ein. Wenn die Pause abgelaufen ist, dann wird das Programm weiter ausgeführt. Jedoch kann während dieser Pause keine weitere Aktion ausgeführt werden.
void setup() { //beginn der seriellen Kommunikation von 9600 baud Serial.begin(9600); } void loop() { //ausgeben der bisher vergangenen Millisekunden Serial.println(millis()); //einlegen einer Pause von 500 Millisekunden delay(500); }
Wenn wir dieses kleine Programm einmal ausführen, dann sehen wir, dass die Pause meist etwas länger als die angestrebten 500 Millisekunden ist.
millis()
Eine weitere Möglichkeit ist es, die vergangenen Millisekunden (Funktion millis()) zu nehmen und diese für eine kleine Berechnung heranzuziehen. Hier wird geprüft, ob die vergangenen Millisekunden + einer Pause fortlaufend geprüft werden, ob dieses kleiner als die aktuellen Millisekunden ist. Wenn dem so ist, dann soll die Funktion ausgeführt werden.
//Konstante mit dem ganzzahligen Wert der Pause const int PAUSE = 500; //Feld zum Speichern des Zeitstempels der letzten Ausführung long lastAction = 0; void setup() { //beginn der seriellen Kommunikation von 9600 baud Serial.begin(9600); } void loop() { //Wenn der Zeitpunkt der letzten Ausführung + der Pause //kleiner ist als der aktuelle Rückgabewert der Funktion //millis(), dann... if ((lastAction + PAUSE) < millis()) { //abspeichern des aktuellen Wertes der Funktion millis() lastAction = millis(); //ausgeben der bisher vergangenen Millisekunden Serial.println(millis()); } }
Die Werte im seriellen Monitor sind hier nun deutlich genauer als mit dem Funktionsaufruf von delay:
Modulo
Einen dritten Ansatz habe ich auf der Seite https://starthardware.org/timer-mit-arduino-alternative-zu-delays/ gefunden. Dort wird ein dritter ebenso sehr interessanter Ansatz gezeigt, und zwar mit der Berechnung mit Modulo.
Modulo ist eine mathematische Rechenoperation, ähnlich der Addition oder Multiplikation. Diese Operation spielt eine bedeutende Rolle in verschiedenen Verschlüsselungsverfahren sowie Schlüsselaustausch-Verfahren. Das Ergebnis des Modulo, oft als „mod“ abgekürzt, bezeichnet den Rest einer ganzzahligen Division.
//Konstante mit dem ganzzahligen Wert der Pause const int PAUSE = 500; void setup() { //beginn der seriellen Kommunikation von 9600 baud Serial.begin(9600); } void loop() { //den aktuellen Wert der vergangenen Millisekunden, seit dem //der Mikrocontroller gestartet ist durch 1000 teilen und davon //den ganzzahligen Rest nehmen long calcMod = millis() % 1000; //Wenn dieser Wert größer als die gewünschte Pause ist, dann... if (calcMod > PAUSE) { //ausgeben der bisher vergangenen Millisekunden Serial.print(millis()); //ausgeben des berechneten Wertes Serial.print(" ["); Serial.print(calcMod); Serial.println("]"); } }
Wenn wir uns die Ausgabe genau anschauen, dann wird immer, wenn der Rest größer als 500 ist, die Ausgabe auf der seriellen Schnittstelle ausgeführt.
Somit haben wir eine Pause von 500 Millisekunden, dieses ist für LEDs etc. ausreichend, jedoch, wenn wir wie hier eine serielle Ausgabe ausführen, dann erhalten wir zu viele Werte.
Schlanker mit der Timer Bibliothek von Arduino
Es geht aber auch noch schlanker und vor allem genauer, hier kommt die Timer Bibliothek von Arduino zum Einsatz. Diese kannst Du Dir derzeit in der Version 3.0.0 von der Seite https://www.arduino.cc/reference/en/libraries/arduino-timer/ als ZIP-Datei herunterladen.
Wie Du eine Bibliothek als ZIP-Datei in die Arduino IDE integrierst, habe ich bereits im gleichnamigen Beitrag Arduino IDE, Einbinden einer Bibliothek ausführlich erläutert.
//Arduino Timer Bibliothek #include <arduino-timer.h> //Timer Objekt initialisieren Timer timer = timer_create_default(); //Funktion zur ausgabe der Millisekunden //Parameter ist unbestimmt bool printMillis(void *){ Serial.println(millis()); //Rückgabewert true wenn der Timer fortgeführt werden soll, //andernfalls false. return true; } void setup() { //beginn der seriellen Kommunikation mit 9600 baud Serial.begin(9600); //Konfigurieren des Timers, //die Funktion "printMillis" soll alle 500 Millisekunden //ausgeführt werden. timer.every(500, printMillis); } void loop() { //Lässt den Timer vorwärts laufen timer.tick(); }
Wenn wir uns nun die Ausgabe anschauen, dann sehen, wir, dass hier die Pause genau 500 Millisekunden beträgt.
Solltest Du also auf eine explizite Pause angewiesen sein, so würde ich Dir empfehlen die Bibliothek Time zu verwenden.
Download
Hier nun alle Beispiele als ZIP-Datei zum download.
Fazit
Abschließend lässt sich festhalten, dass die Verwendung der „Timer“-Bibliothek für Arduino deutliche Vorteile bietet. Die präzise Intervall-Ausführung ermöglicht eine genauere Zeitsteuerung, während die Effizienz des Codes erhalten bleibt. Mit dieser schlanken Lösung können wir uns von den herkömmlichen Ansätzen, wie der Verwendung von delay
, verabschieden und unsere Projekte auf ein neues Level heben. Entdecke die Faszination der Arduino-Timer-Programmierung und erlebe die Genauigkeit, die deine Projekte verdient haben.
Eine tolle Sache mit dem Timer. Ich suche die Möglichkeit den Timer mit einer Variable flexibel zu halten. Die Eingabe wird als Analogwert eingelesen werden. Vielleicht kann mich jemand dabei Unterstützen.
Beispiel wäre über ein Poti Analogwert einzulesen, passend mit map zu machen und den Timer mit der neuen Variable zu füttern.