millis()-Overflow

Beim Arduino trifft man häufig auf das Problem, dass man zeitlich verzögerte Aktionen ohne die Verwendung von delay() lösen will/muss. Wenn man als Lösungsansatz die Differenz der vergangenen Millisekunden misst, dann stößt man unweigerlich auf das Überlaufproblem. Folgender Code sei gegeben:

#define CUSTOM_DELAY 100

unsigned int lastAction = 0;

void setup() {}

void loop()
{
    if (millis() - lastAction >= CUSTOM_DELAY) {
        lastAction += CUSTOM_DELAY;
        // do something...
    }
}

Sobald millis() das Maximum von lastAction, d.h. von unsigned int erreicht hat, wird diese Variable wieder von 0 an beschrieben. Damit ist die obige if-Abfrage für lange Zeit falsch.
Eine einfache und praktikable Lösung ist, lastAction als signed long zu deklarieren, damit würde sich das Problem auch nach einem Überlauf der Variablen nicht mehr stellen:

#define CUSTOM_DELAY 100
#define lmillis() ((long)millis())

long lastAction;

void setup()
{
    lastAction = lmillis() + CUSTOM_DELAY;
}

void loop()
{
    if (lmillis() - lastAction >= 0) {
        lastAction = lmillis() + CUSTOM_DELAY;
        // do something...
    }
}
zurück