Willkommen auf unserem Seminar-Blog

Immer auf dem aktuellen Stand bleiben

Dieser Seminar-Blog befindet sich noch im Aufbau und wird in den kommenden Tagen entsprechend verfeinert.

Member Login

Lost your password?

Registration is closed

Sorry, you are not allowed to register by yourself on this site!

You must either be invited by one of our team member or request an invitation by email at viad.info {at} zhdk {dot} ch.

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