Arduino Delay [Tutorial]

In diesem Tutorial erfahren Sie, wie Sie die delay() -Funktion richtig verwenden, um eine Verzögerung zwischen 2 Aktionen in Ihren Arduino-Programmen hinzuzufügen. Dann werden Sie herausfinden, warum die Verwendung von delay() oft keine gute Idee ist, wenn Sie Ihre Programme skalieren möchten und wie Sie das beheben können.

In Ordnung, lass uns anfangen!

Inhaltsverzeichnis

Warum brauchen Sie Verzögerungen in Ihren Arduino-Programmen?

Nun, ein Arduino-Programm ist sehr auf externe Ein- / Ausgänge angewiesen, um zu funktionieren.

Ein einfaches Beispiel: Sie können den Zustand eines Druckknopfes 100 Mal pro Sekunde überwachen oder eine LED alle 0,5 Sekunden blinken lassen.

Wie können Sie das erreichen? Ein Arduino-Programm funktioniert so:

  • Zuerst wird die Funktion setup() einmal ausgeführt.
  • Dann wird die loop() -Funktion immer wieder ausgeführt, bis Sie Ihren Arduino ausschalten.

Jedes Programm, das Sie schreiben, wird mit voller Geschwindigkeit ausgeführt. Wenn Sie also eine LED in Ihrem Code blinken lassen, wird die LED mit einer sehr hohen Rate blinken (mindestens mehrere tausend Mal pro Sekunde).

Sie lernen, wie Sie mit Arduino Ihre eigenen Projekte erstellen können?

Schauen Sie sich Arduino für Anfänger an und lernen Sie Schritt für Schritt.

Wenn Sie die Zeit steuern möchten– dh sicherstellen möchten, dass die LED nur alle 0,5 Sekunden und nicht mit voller Geschwindigkeit blinkt, müssen Sie Ihrem Code eine Verzögerung hinzufügen.

Implementieren der Arduino-Verzögerung in Ihrem Code

Die Arduino delay() -Funktion

Hier ist ein Code, mit dem eine LED alle 0,5 Sekunden blinkt (hier wählen wir die eingebaute LED, keine externe LED muss hinzugefügt werden) – dies ist eines der häufigsten Beispiele, die Sie sehen werden, wenn Sie mit Arduino beginnen.

#define LED_PIN 13void setup() { pinMode(LED_PIN, OUTPUT);}void loop() { digitalWrite(LED_PIN, HIGH); delay(500); digitalWrite(LED_PIN, LOW); delay(500);}

Wie funktioniert dieser Code?

Zuerst verwenden Sie ein „define“, damit Sie die Zahl „13“ nicht mehrmals in Ihrem Code fest codieren müssen und Ihr Programm lesbarer wird.

Mit der Funktion pinMode() legen Sie den Modus des auszugebenden Pins fest.

Dann können Sie in der Funktion loop():

  1. Schalten Sie die LED ein
  2. Verwenden Sie delay(500), um das Programm für 500 Millisekunden oder 0,5 Sekunden in den Ruhezustand zu versetzen
  3. Schalten Sie die LED aus
  4. Verwenden Sie delay(500), um das Programm für 0,5 Sekunden in den Ruhezustand zu versetzen
  5. Und fahren Sie mit Schritt 1 fort, da die Funktion loop() immer wieder ausgeführt wird.

Die Funktion delay() erwartet, dass Sie eine Anzahl von Millisekunden – nicht Sekunden – für den Ruhezustand angeben. Wenn Sie also in Sekunden denken, multiplizieren Sie die Zahl mit 1000 und Sie haben den Wert, den Sie benötigen.

Machen Sie eine Arduino-Verzögerung für 1 Minute

Wenn Sie Ihren Arduino 1 Minute oder mehrere Minuten lang schlafen lassen möchten, ist dies ganz einfach.

Nehmen Sie die Anzahl der Minuten, multiplizieren Sie sie mit 60, um die Anzahl der Sekunden zu erhalten, und multiplizieren Sie sie dann mit 1000, um die Anzahl der Millisekunden zu erhalten.

Ex: delay(3 * 60 * 1000); wird machen die programm schlaf für 3 minuten.

Die Arduino delayMicroseconds() -Funktion

Wenn Sie genauer sein müssen, müssen Sie möglicherweise die delayMicroseconds() -Funktion verwenden. Mit delayMicroseconds() können Sie eine Anzahl von Mikrosekunden zum Schlafen bereitstellen. Die Mindestdauer für delay() beträgt 1 Millisekunde, wenn Sie also nur 400 Mikrosekunden schlafen müssen, haben Sie hier eine neue Lösung.

Diese Funktion kann bei der Kommunikation mit einigen Hardwarekomponenten sehr nützlich sein. Zum Beispiel muss der Arduino einige Daten an die Komponente senden und dann eine Antwort lesen. Angenommen, die Komponente benötigt 6 Mikrosekunden, um die Anforderung zu verarbeiten und genaue Daten zu liefern.

Dann haben Sie in Ihrem Programm möglicherweise Folgendes:

...void loop() { // send data to component delayMicroseconds(6); // reach out to component again to read data}

Nicht blockierende Verzögerung – warum Sie delay() vermeiden sollten

Nachdem Sie nun verstanden haben, was eine Verzögerung in Arduino ist und wie Sie sie mit delay() und delayMicroseconds() implementieren, sehen wir uns an, wie Sie die Verzögerungsfunktion verwenden – jedoch ohne diese Funktionen.

Warum?

Wenn Sie delay()verwenden, wird die Ausführung Ihres Programms gestoppt und erst nach Beendigung der Verzögerung fortgesetzt.

Dies ist in Ordnung, wenn Sie nur eine Aktion ausführen müssen – Beispiel: blinken Sie eine einzelne LED – aber was ist, wenn Sie sich um mehrere Hardwarekomponenten kümmern oder mit anderen Geräten wie Arduino-Boards oder Ihrem eigenen Computer kommunizieren müssen?

Wie können Sie im vorherigen Beispiel eine LED alle 0,5 Sekunden und eine andere alle 0,8 Sekunden blinken lassen?

In diesem Fall werden Sie ziemlich schnell stecken bleiben. Wenn Sie immer noch delay() verwenden möchten, finden Sie möglicherweise eine Lösung, bei der Sie kürzere Verzögerungen zwischen mehreren Aktionen verwenden.

Die Lösung dafür besteht einfach darin, die Zeit zu überwachen, ohne die Funktion delay() zu verwenden, um im Grunde einen Weg zu finden, das Verhalten von delay() zu reproduzieren, ohne es zu verwenden.

Codebeispiel – Arduino delay without delay()

Schreiben wir unser Blink-LED-Beispiel neu, ohne delay() zu verwenden.

#define LED_PIN 13unsigned int lastTimeLedBlinked = millis();unsigned int delayBetweenBlink = 500;byte ledState = LOW;void setup() { pinMode(LED_PIN, OUTPUT);}void loop() { unsigned int timeNow = millis(); if (timeNow - lastTimeLedBlinked > delayBetweenBlink) { if (ledState == LOW) { ledState = HIGH; } else { ledState = LOW; } digitalWrite(LED_PIN, ledState); lastTimeLedBlinked = timeNow; }}

Lassen Sie uns diesen Code Zeile für Zeile analysieren.

Initialisierung

#define LED_PIN 13unsigned int lastTimeLedBlinked = millis();unsigned int delayBetweenBlink = 500;byte ledState = LOW;

Zuerst initialisieren Sie 3 Variablen im globalen Bereich:

  • lastTimeLedBlinked: Diese Variable wird verwendet, um das letzte Blinken der LED zu speichern. Grundsätzlich aktualisieren wir diese Variable jedes Mal, wenn die LED blinkt, mit der aktuellen Zeit – mithilfe der Funktion millis ().
  • delayBetweenBlink: Dies ist die Zeit, die Sie zwischen 2 Aktionen warten möchten – hier besteht die Aktion darin, die LED zu blinken.
  • ledState: Wir müssen den Status der aktuellen LED (HOCH oder NIEDRIG) speichern, damit wir wissen, was der vorherige Status war, und entsprechend Maßnahmen ergreifen können.

Warum im globalen Bereich? Nun, wir planen, diese Variablen in der Funktion loop() zu aktualisieren und beim nächsten Aufruf von loop() erneut darauf zuzugreifen. Wenn wir die Variablen innerhalb von loop() erstellen, sind die Variablen lokale Variablen und werden daher zerstört, wenn Sie die Funktion loop() beenden. Wenn also das nächste Mal loop() erneut aufgerufen wird, gehen alle Werte verloren und Sie erstellen erneut Variablen ohne vorherigen Wert. Indem wir die Variablen außerhalb der Funktion erstellen, können wir sie hier „überleben“ lassen und ihren Wert bei jeder Eingabe von loop() beibehalten.

Implementieren der Arduino-Verzögerungsfunktion in der Schleifenfunktion

Nun wollen wir sehen, was in der Funktion loop() passiert.

void loop() { unsigned int timeNow = millis();

Zuerst lesen Sie die aktuelle Uhrzeit mit der Funktion millis() ab.

 if (timeNow - lastTimeLedBlinked > delayBetweenBlink) {

Und jetzt vergleichen Sie die aktuelle Zeit, die Sie gerade gelesen haben, mit der vorherigen Zeit, als die LED blinkte. Wenn genügend Zeit vergangen ist (mehr als der in delayBetweenBlink gespeicherte Wert), können Sie if() eingeben.

Diese Codestruktur – Lesen der Zeit und Vergleichen mit der vorherigen Zeit, in der Sie eine Aktion ausgeführt haben – ersetzt die Funktion delay() . Im Grunde berechnen Sie hier nur eine Dauer. Und wie Sie sehen können, bedeutet dies, dass Ihr Programm mehr Zeilen für eine einfache Anwendung enthält, aber es gibt Ihnen viel mehr Kontrolle und es ist viel skalierbarer.

Also, was wird passieren? Nun, der loop() wird weiterhin mit voller Geschwindigkeit ausgeführt. Jedes Mal überprüft Ihr Programm, ob genügend Zeit vergangen ist. Wenn nicht, endet loop() hier, da es nicht in die if-Struktur aufgenommen wird.

Und wenn gerade genug Zeit vergangen ist, geben wir die if() ein.

Ausführen der Aktion

 if (ledState == LOW) { ledState = HIGH; } else { ledState = LOW; } digitalWrite(LED_PIN, ledState);

OK, Sie haben gerade die if() eingegeben, und hier werden Sie die Aktion ausführen, die Sie ausführen müssen.

Hier lassen wir die LED blinken. Und weil wir nicht direkt wissen können, wie der vorherige Status für die LED war (da wir die loop() viele Male eingegeben und alle darin erstellten lokalen Variablen verloren haben), erhalten wir diesen Status von einer globalen Variablen.

Was wir mit dieser globalen Variablen machen, ist einfach: Wenn sie NIEDRIG war, setzen wir sie auf HOCH, und wenn sie HOCH war, setzen wir sie auf NIEDRIG. Und dann aktualisieren wir natürlich den physischen LED-Status entsprechend mit digitalWrite().

 lastTimeLedBlinked = timeNow; }}

Schließlich, und das ist super wichtig, speichern wir die aktuelle Zeit als das letzte Mal, als wir die LED blinzelten. Wenn wir das nicht tun, blinkt das Programm die LED mit voller Geschwindigkeit, da die Bedingung innerhalb von if() immer wahr ist.

Indem wir die vorherige Zeit auf die aktuelle Zeit einstellen, „setzen wir den Timer zurück“.

In diesem Beispiel wird also if() nur alle 500 Millisekunden oder 0,5 Sekunden eingegeben.

Und jetzt ist das großartig, weil Ihr Programm nicht stoppt, so dass Sie weiterhin verschiedene unabhängige Aktionen ausführen können, während Sie immer noch „warten“, um die LED zu blinken.

2 Aktionen „gleichzeitig“

Angenommen, Sie möchten beispielsweise alle 0 eine LED blinken lassen.5 zweite, und eine andere jeden 0,8 zweite.

#define LED_1_PIN 13#define LED_2_PIN 10unsigned int lastTimeLed1Blinked = millis();unsigned int delayBetweenBlink1 = 500;byte led1State = LOW;unsigned int lastTimeLed2Blinked = millis();unsigned int delayBetweenBlink2 = 800;byte led2State = LOW;void setup() { pinMode(LED_1_PIN, OUTPUT); pinMode(LED_2_PIN, OUTPUT);}void loop() { unsigned int timeNow = millis(); // Action 1 - Blink LED 1 if (timeNow - lastTimeLed1Blinked > delayBetweenBlink1) { if (led1State == LOW) { led1State = HIGH; } else { led1State = LOW; } digitalWrite(LED_1_PIN, led1State); lastTimeLed1Blinked = timeNow; } // Action 2 - Blink LED 2 if (timeNow - lastTimeLed2Blinked > delayBetweenBlink2) { if (led2State == LOW) { led2State = HIGH; } else { led2State = LOW; } digitalWrite(LED_2_PIN, led2State); lastTimeLed2Blinked = timeNow; }}

Wie Sie sehen, wiederholen wir die Codestruktur für die zweite Aktion, die wir hinzugefügt haben. Und beide Aktionen werden sich nicht stören!

Rekapitulieren

Wenn Sie eine Arduino-Verzögerung ohne Verwendung von delay():

  1. Erstellen Sie eine globale Variable, um zu speichern, wann Sie das letzte Mal eine bestimmte Aktion ausgeführt haben.
  2. Erstellen Sie eine weitere globale Variable, um die gewünschte Dauer zwischen 2 Aktionen zu speichern.
  3. Lesen Sie in der Funktion loop()die aktuelle Uhrzeit mit millis() ab.
  4. Verwenden Sie danach eine if Struktur und verwenden Sie die Bedingung (timeNow - lastTimeActionWasExecuted > delayBetweenActions) .
  5. Sobald Sie if() eingegeben haben, führen Sie die Aktion aus.
  6. Und immer noch in der if(), speichern Sie die aktuelle Zeit als die vorherige Zeit.

Sie können diese Schritte für jede Aktion wiederholen, für die Sie eine Arduino-Verzögerung benötigen.

Wenn es in Ordnung ist, delay() und delayMicroseconds()

Es gibt bestimmte Fälle, in denen die Verwendung von delay() in Ihrem Code immer noch in Ordnung ist.

Hier sind 2 davon:

  • Sie müssen eine Komponente während der Einrichtung Ihres Programms initialisieren, und diese Komponente benötigt einige Zeit, um initialisiert zu werden – zum Beispiel 1,5 Sekunden. In diesem Fall ist die Verwendung von delay(1500) in Ihrer setup() -Funktion vollkommen in Ordnung. Grundsätzlich ist jede delay() in der setup() -Funktion Ihres Arduino-Programms kein Problem.
  • Wie im delayMicroseconds() -Teil erläutert, müssen Sie einige Mikrosekunden warten (keine Millisekunden!) bei der Kommunikation mit einer externen Komponente. Wenn Sie feststellen, dass die Verwendung von delayMicroseconds() mit einer kleinen Zahl (z. B. 10) den Rest Ihres Programms nicht stört, können Sie es trotzdem verwenden, ohne sich zu viele Sorgen machen zu müssen. Betrachten Sie es jedoch als Ausnahme, nicht als allgemeine Regel.

Fazit – Verwenden Sie Arduino delay() mit Sorgfalt

Aufgrund der Natur von Arduino-Programmen müssen Sie Ihrem Code häufig Verzögerungen hinzufügen, damit Sie auswählen können, wann und wie oft Sie einige Aktionen ausführen möchten.

Die Funktionen delay() und delayMicroseconds() sind sehr einfach zu bedienen und wurden der Arduino-Sprache hinzugefügt, damit Anfänger mit etwas Einfachem beginnen können.

Wie Sie jedoch in diesem Tutorial gesehen haben, kann die Verwendung von delay() dazu führen, dass Sie sehr schnell stecken bleiben. Daher ist es am besten, zuerst zu verstehen, warum Sie es benötigen, wie Sie es verwenden und wie Sie dann dasselbe Verhalten erzielen, ohne die Arduino delay() -Funktion direkt zu verwenden.

Sobald Sie die Codestruktur verstanden haben, um delay() loszuwerden, können Sie Ihre Arduino-Programme erheblich verbessern, und Multitasking wird ganz einfach.

Schreibe einen Kommentar

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