Arduino Tutorial: Verwenden von millis() anstelle von delay()

Eine bekannte Arduino-Funktion ist delay(), die das Programm für eine als Parameter angegebene Anzahl von Millisekunden pausiert.

millis(), andererseits ist eine Funktion, die die Anzahl der Millisekunden zurückgibt, die seit dem Programmstart vergangen sind.

Auf den ersten Blick mag man an der Nützlichkeit dieser Funktion zweifeln. Tatsache ist, dass es in vielen Szenarien äußerst nützlich ist und delay() häufig vollständig „ersetzt“. Schauen wir uns zunächst an, wie wir millis() fast genau wie delay() verwenden können.

Timing-Probleme sind oft in der Programmierung vorhanden.

Mit millis() wie Verzögerung()

int period = 1000;unsigned long time_now = 0;void setup() {Serial.begin(115200);}void loop() {time_now = millis(); Serial.println("Hello"); while(millis() < time_now + period){//wait approx. ms}}

Wenn Sie möchten, dass Ihr Code am Ende jeder Schleifeniteration nur 1000 ms pausiert, ist der obige Code etwas albern. Sie können stattdessen einfach delay(1000) . Der einzige Unterschied zwischen dem obigen Code und einem Code mit delay(1000) am Ende besteht darin, dass die Schleife im obigen Code einmal pro Sekunde ziemlich genau ausgeführt wird. Die Schleife in einem Code mit delay(1000) wird etwas seltener ausgeführt, da die Ausführung von Serial.println("Hello") ebenfalls einige Zeit dauert.

Warum millis() anstelle von delay() ?

Wir betrachten nun zwei Vorteile mit millis() im Vergleich zu delay().

Genaues Timing

Der erste Vorteil, den wir besprechen werden, ist das genaue Timing. In Bezug auf den Code haben wir dies im letzten Kapitel behandelt. Mit millis() können wir sicherstellen, dass die Schleife unabhängig von der Ausführungszeit so oft ausgeführt wird, wie wir möchten (natürlich, solange die Ausführungszeit kürzer ist als der gewünschte Zeitraum). Mit delay() ist dies nicht möglich, da wir nicht wissen, wie lange die Schleifenausführungszeit ist.

Ein genaues Timing wie dieses ist sehr nützlich, wenn Sie unter anderem mit einer bestimmten Frequenz abtasten oder Filter ausführen.

Nicht blockierend

Der andere Vorteil von millis() ist, dass es uns nicht daran hindert, Code auszuführen, während wir „warten“.

Nehmen wir an, wir möchten einmal pro Sekunde „Hallo“ über seriell drucken, während wir in der Zwischenzeit andere Dinge tun. Dies ist mit delay() nicht möglich, da der gesamte Code angehalten wird. Hier ist eine Möglichkeit, dies zu tun:

int period = 1000;unsigned long time_now = 0;void setup() {Serial.begin(115200);}void loop() {if(millis() >= time_now + period){time_now += period;Serial.println("Hello");} //Run other code}

Dieser Codeblock ist dem ersten ziemlich ähnlich, außer dass er den Rest des Programms nicht blockiert, wenn er nicht über seriell druckt.

Beispiel: ein einfacher Scheduler

Lassen Sie uns ein einfaches Beispiel schreiben, in dem wir einen Scheduler erstellen, der bestimmte Textbits in unterschiedlichen Intervallen druckt.

#define INTERVAL_MESSAGE1 5000#define INTERVAL_MESSAGE2 7000#define INTERVAL_MESSAGE3 11000#define INTERVAL_MESSAGE4 13000unsigned long time_1 = 0;unsigned long time_2 = 0;unsigned long time_3 = 0;unsigned long time_4 = 0;void print_time(unsigned long time_millis);void setup() {Serial.begin(115200);}void loop() {if(millis() >= time_1 + INTERVAL_MESSAGE1){time_1 +=INTERVAL_MESSAGE1;print_time(time_1);Serial.println("I'm message number one!");} if(millis() >= time_2 + INTERVAL_MESSAGE2){time_2 +=INTERVAL_MESSAGE2;print_time(time_2);Serial.println("Hello, I'm the second message.");} if(millis() >= time_3 + INTERVAL_MESSAGE3){time_3 +=INTERVAL_MESSAGE3;print_time(time_3);Serial.println("My name is Message the third.");} if(millis() >= time_4 + INTERVAL_MESSAGE4){time_4 += INTERVAL_MESSAGE4;print_time(time_4);Serial.println("Message four is in the house!");}}void print_time(unsigned long time_millis){Serial.print("Time: ");Serial.print(time_millis/1000);Serial.print("s - ");}

So sehen die ersten 60 Sekunden im seriellen Monitor aus:

Dies ist eine schöne und einfache Möglichkeit, Ausführungen in Ihrem Code zu synchronisieren. Sie können auch anderen Code gleichzeitig ausführen.

micros() und Overflowing

Genau wie delay() hat eine Mikrosekunden-Version namens delayMicroseconds(), millis() hat micros(). Wenn Sie eine bessere Auflösung benötigen, kann micros() der richtige Weg sein.

Beachten Sie jedoch, dass micros() nach ungefähr 70 Minuten überläuft, verglichen mit den 50 Tagen von millis(). Dies bedeutet, dass die Rückgabewerte der Funktionen bei Null beginnen.

Noch wichtiger: Um zu erfahren, wie Sie das Überlaufproblem insgesamt vermeiden können, lesen Sie diesen Blogbeitrag.

Zusammenfassung

millis() und micros() sind wirklich praktische Funktionen für Timing-Aufgaben. Wenn Sie sich dessen nicht bewusst sind, verwenden Sie möglicherweise stattdessen delay() , was (wenn überhaupt) nicht immer so gut funktioniert.

Weitere Arduino-Tipps & Tricks finden Sie in unserer Blog-Kategorie Arduino-Tutorials. Bleiben Sie dran für weitere Arduino-bezogene Inhalte auch in Zukunft!

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht.