ESP8266ESP8266 - Einführung

Delay() vs. millis() – Warum ich lieber millis() einsetze

In diesem Artikel erkläre ich Dir die Unterschiede der delay() und millis() Funktion.  In Deinem ersten Arduino Programm hast Du bestimmt auch genauso wie ich eine oder zwei LEDs blinken lassen. Dabei wurde das Intervall der Blinkgeschwindigkeit bestimmt über die delay() Funktion gesteuert. Für einfache Programme und Anwendungsfälle ist die Funktion sehr praktisch und einfach zu verwenden. Für größere Projekte würde ich sie Dir nicht empfehlen. Warum? Das erfährst Du jetzt im Artikel.

Die Funktionsweise der delay() Funktion ist relativ einfach. Der Funktion wird die Zahl der Millisekunden übergeben. Wenn wir also der Funktion 1000 übergeben, wird das Programm eine Sekunde verzögert. Im folgenden Code-Beispiel wird die Verwendung der delay() Funktion verdeutlicht:

// Pins definieren
const int ledPin = LED_BUILTIN;

void setup()
{
  pinMode(ledPin, OUTPUT);
}

void loop()
{
  digitalWrite(ledPin,HIGH);
  delay(1000);
  digitalWrite(ledPin,LOW);
  delay(1000);
}

In der Loop-Funktion wird zunächst der ledPin auf HIGH gesetzt. Im Anschluss wird das gesamte Programm angehalten und dann wieder der ledPin auf LOW gesetzt. Über die delay() Funktion wird also die Blink-Frequenz gesteuert. Dabei wird das gesamte Programm angehalten, und somit auch andere Funktionalitäten geblockt. Wenn nun also mehrere Funktionen parallel ausgeführt werden sollen, haben wir hier ein Problem. Gerade beim Zusammenspiel von mehreren Komponenten ist die Nutzung von Delays so nicht machbar.

Aus diesem Grund würde ich für komplexere Aufgaben die millis() Funktion einsetzen. Die Funktion gibt die Anzahl Millisekunden zurück, die seit dem ersten Start des Programms vergangen sind. Im folgenden Beispiel zeige ich Dir, wie eine Wechselblinker-Schaltung mit 2 LEDs funktioniert.

// Pins definieren 
const int ledPin1 =  D7;
const int ledPin2 =  D8;
 
// Initialstates definieren
int ledState1 = LOW;
int ledState2 = HIGH;
 
// Timer-Variablen
long myTimer = 0;
long myTimeout = 100;
 
void setup() { 
  pinMode(ledPin1, OUTPUT); 
  pinMode(ledPin2, OUTPUT); 
} 
 
void loop() { 
 if (millis() > myTimeout + myTimer ) {
    myTimer = millis();
 
    if (ledState1 == LOW) {
      ledState1 = HIGH;
    } else {
      ledState1 = LOW;
    }
     
    if (ledState2 == LOW) {
      ledState2 = HIGH;
    } else {
      ledState2 = LOW;
    }    
 
    digitalWrite(ledPin1, ledState1);
    digitalWrite(ledPin2, ledState2);
  }  
}

Zugegeben, auf der ersten Blick doch komplexer als das Beispiel über die delay() Funktion, aber eigentlich einfach und mittels dieser Vorgehensweise flexibler für Erweiterungen. Ich setze die millis() Funktion für größere Projekte bereits ein.

Matthias Korte

Hauptberuflich Software-Entwickler und seit einigen Jahren Smart-Home Fan. Angefangen hat alles mit einem RaspberryMatic und einer schaltbaren Steckdose. Mittlerweile habe ich einige Steckdosen, Sensoren, und Thermostate sowie ioBroker zur Visualisierung im Einsatz.

7 Gedanken zu „Delay() vs. millis() – Warum ich lieber millis() einsetze

  • Pingback: LED ein- und ausschalten – smarthome-tricks.de

  • Pingback: ESP8266 – LED Wechselblinker – smarthome-tricks.de

  • posti

    Kleine Korrektur: MILLI-Sekunden.
    Davon ergeben 1000 genau eine Sekunde.
    Bei den erwähnten MIKRO-Sekunden sind’s 1000000 – schon ein kleiner Unterschied und das delay() wartet dann plötzlich doch schon ‚etwas‘ länger.

    Wie ich mehreren Beiträgen entnehmen durfte, wird hier auf Kommentare wohl eher stiefmütterlich reagiert … nun denn.

    @Mathias Korte
    Ihre Beiträge erscheinen mir etwas arg knapp gehalten, erinnert irgendwie an die Arduino-Beispiele – Die gehen auch am ‚Sinn des Lebens‘ vorbei, zeigen aber eben genau diese eine Funktionalität, Die dem Titel zu entnehmen ist.
    Ok – man kann mit dem Beispiel halt als normaler Mensch dann zum Programmieren NICHTS anfangen, aber Das hat ja auch zuvor Niemand behauptet, daß Das damit auch nur gewollt gewesen wäre.
    Ich wünschte mir:
    – etwas mehr ausholen
    – so Zeugs wie Wiederstände ausmerzen (das heißt Widerstand – ohne E vorne)
    – den Sinn hinter dem Beispiel erläutern – warum macht man den ganzen Käse überhaupt??

    Und, was mir schon ungesund aufstößt:
    – 1.tens:
    Wenn man schon IP-Adressen fest im Sketch vergibt – warum nicht Diese als const byte an EINER Stelle zum Einstellen anlegen und im Sketch bei IP, DNS, Gateway, Subnetmask genau diese Variablen benutzen? (zugegeben: war ein anderes Beispiel)
    – 1.tens:
    SSID und Passwort lagere ich in einen 2.ten Tab aus und includiere Diesen ( #include „tabname.h“ )
    Somit ist sichergestellt, daß MEIN Passwort nicht versehentlich in der Öffentlichkeit gezeigt wird, weil ich eben meinen Haupt-Sketch helfenden Augen zur Verfügung stelle, weil ich irgendwo selber nicht mehr zurecht komme.

    War schon zu Zeiten von PHP so, daß man die Zugangsdaten zum mySQL-Server NICHT im Klartext in der PHP durch die Welt schickt – warum also hier … wir sollten mittlerweile ein paar Jahre Erfahrung mehr haben und den Mist von Damals müssen wir doch nicht mit wesentlich gefährlicheren Komponenten wiederholen, woll?

    Antwort
    • Matthias Korte

      Moin,

      danke für den Hinweis mit denn Millisekunden, den Fehler habe ich gleich berichtigt. Ja, zum Thema Beantwortung von Kommentaren gelobe ich Besserung, hier muss ich definitiv noch mehr Zeit investieren.
      Zu den ungesunden Punkten 😉

      1.) Das ist korrekt, habe ich evtl. im nicht benannten Beispiel vergessen, sollte so aber natürlich immer umgesetzt werden. Ich werde dazu zeitnah einen separaten Artikel verfassen.
      2.) Rechtschreibfehler sind immer unnötig, hier bin ich aktuell am verbessern, sodass sowas nicht mehr vorkommt. Vor allem so peinliche 😉
      3.) Ich versuche die Beispiele immer so einfach wie möglich aufzubauen, daher kommen bei mir die WLAN-Zugangsdaten in der Regel immer den Header des Sketches.

      Nochmals Danke für Deine konstruktive Kritik 🙂

      LG Matthias

      Antwort
  • Andreas

    Wo ist der Code für Millis()?

    Antwort
    • Me and the boys

      In der Tat 😀 Er zeugt den „schlechten“ Code, aber gibt kein Beispiel, wie man es besser macht xD

      Antwort
    • Matthias Korte

      Sorry für den fehlenden Code, ich habe den Code für einen Wechselblinker gerade ergänzt. Den Code kann man nun natürlich so auch auf eine LED anpassen 🙂

      Antwort

Schreibe einen Kommentar zu posti Antworten abbrechen

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