Delay() mal schneller…
Delay() mal schneller...
Problem
Oft möchten wir in einem Programm einen Sensor auslesen und gleichzeitig einen Aktuator aktivieren/deaktivieren. Dies kann zu Problemen führen, wenn wir in der loop() Schleife ein delay() verwenden um z.B. eine LED blinken zu lassen. Während einem delay() macht das Arduino Board gar nichts, es bleibt einfach an der gleichen Stelle stehen und liesst auch keinen neuen Sensor-Input ein. Dies kann zu ungewünschten Verzögerungen führen. Um die Geschwindigkeit des folgenden Sketches zu visualiseren, ladet den Code auf euer Board und öffnet den Serial Monitor. Ihr werdet bemerken, dass jeder loop() ca. 2 Sekunden benötigt – genau die zwei Sekunden, welche durch das delay() hervorgerufen werden.#define LED_PIN 13 #define POTI_PIN 0 int counter = 0; // for visualizing the speed int potiDelay = 0; void setup() { pinMode(13, OUTPUT); // set LED_PIN as output Serial.begin(9600); // enable Serial communication } void loop() { potiDelay = analogRead(POTI_PIN); digitalWrite(13, HIGH); // set the LED on delay(potiDelay); // wait for a second digitalWrite(13, LOW); // set the LED off delay(potiDelay); // wait for a second Serial.println(counter++); // only for demonstration }Sketch Grösse = 2596 bytes
Lösung
Um diese Problem zu umgehen gibt es eine sehr effiziente Methode: millis(). Für eine Übersicht über die Funktion millis() bitte in der Arduino Reference nachsehen. Wir benutzen diese Funktion um uns in einer Variablen (timeStamp) die aktuelle Systemzeit zu speichern. Mit dieser Systemzeit und zwei if() Abfragen ist es möglich genau das gleiche Programm wie vorher zu erstellen; mit dem grossen Unterschied, dass dieses Programm nicht an einem delay() hängenbleibt und sehr viel schneller durchlaufen wird. Um den Effekt zu sehen kopiert unten stehenden Code und alteriert den Serial Monitor. Vergleicht die ausgegebenen Werte mit dem vorherigen Sketch. Schneller? Richtig!#define LED_PIN 13 #define POTI_PIN 0 long timeStamp = 0; // to store the system time int ledDelay = 1000; // the actual delay boolean onOff = false; // indocates if the LED is on or off int counter = 0; // for visualizing the speed void setup() { pinMode(LED_PIN, OUTPUT); // set LED_PIN as output Serial.begin(9600); // enable Serial communication } void loop() { ledDelay = analogRead(POTI_PIN); if(millis() - timeStamp > ledDelay && onOff == false) // if time elapsed during last swich > delay and led is off { digitalWrite(LED_PIN, HIGH); // set the LED on timeStamp = millis(); // set timeStamp to actual system time onOff = true; // set onOff to true (LED is on) } if(millis() - timeStamp > ledDelay && onOff == true) // if time elapsed during last swich > delay and led is on { digitalWrite(LED_PIN, LOW); // set the LED off timeStamp = millis(); // set timeStamp to actual system time onOff = false; // set onOff to false (LED is off) } Serial.println(counter++); // only for demonstration (compare with code above) }Sketch Grösse = 2578 bytes