millis()-Überlauf- wie damit umgehen?

Hallo,

wenn ich ein Programm geschrieben habe, welches zu großen Teilen mit millis() arbeitet, wie kann ich dann gewährleisten, dass dieses Programm auch in mehreren Wochen oder Monaten noch stabil läuft, wenn der Prozessor permanent an sein soll?

Gruß Chris

Vielleicht so: http://playground.arduino.cc/Code/TimingRollover ?

Wenn man die Kontrolle der vergangenen Zeit richtig schreibt (so wie in den Beispielen) dann ist die Zeitdauer auch bei einem Überlauf exakt. Die einzige Problem ist, wenn Zeitintervalle größer als 49,5 Tage lang sein sollen. Das geht mit millis() alleine nicht da nicht erkannt werden kann wieviele Überläufe bereits vorbei sind. Abhilfe mit http://www.faludi.com/2007/12/18/arduino-millis-rollover-handling/

Grüße Uwe

uwefed: Abhilfe mit http://www.faludi.com/2007/12/18/arduino-millis-rollover-handling/

Hallo Uwe,

das Beispiel bei dem Link führt leider in die Leere (sprich: der weiterführende Link zu dem Download-Source existiert nicht mehr). Die Diskussion darunter zeigt wohl aber andere Lösungen auf. Danach suche ich auch gerade, da delay(x) ja keine Lösung ist, sondern ich alle x-Millisekungen etwas machen möchte und dafür eine stabile Berechnung suche.

...immer auf der Suche... Thomas

Wenn man es so macht spielt der Überlauf keine Rolle:

if(millis() - previousMillis > interval)

Wenn man da unsigned rechnet und millis() z.B. auf 10 überlauft ist das Ergebnis der Subtraktion i.d.R. nahe am oberen Ende des Wertebereiches und sollte damit größer als gebräuchliche Werte von interval sein.

twyly: Hallo Uwe,

das Beispiel bei dem Link führt leider in die Leere (sprich: der weiterführende Link zu dem Download-Source existiert nicht mehr).

Ich hatte leider nicht kontrolliert. Der Sketch befindet sich auf http://www.faludi.com/itp/arduino/millis_rollover.pde

Grüße Uwe

uwefed: Der Sketch befindet sich auf http://www.faludi.com/itp/arduino/millis_rollover.pde

Danke!

if(millis() - previousMillis > interval)

Serenifly: Wenn man da unsigned rechnet..

Was meinst Du damit genau?

Meinst Du damit das previousMillis und interval unsigned deklariert sein müssen, oder reicht es, wenn lediglich previousMillis unsigned deklariert wurde?

Gruß Chris

previousMillis() als unsigned reicht. Wenn es signed int geht es auch, da das dann für die Berechnung auf unsigned geändert wird. Wobei da dann wahrscheinlich Probleme bekommt wenn previousMillis() größer als der Werterbereich eines signed int wird.

Es geht gar nicht wenn man mit einer currentMillis Variable arbeitet und sowohl diese als auch previousMillis signed sind.

Das größte Problem ist, dass "int" so schnell zu tippen ist und man verleitet wird einen falschen Datentyp zu nehmen.

Wenn das Intervall unter 32 sec ist, kann man fälschlich ein int nehmen und es geht doch. millis() und Kopien davon ( wie previousmillis o.ä. ) müssen immer [b]unsigned long[/b] sein. Sauber wäre sowas

const unsigned long INTERVALL = 120*1000UL; // 120 sec
...

  static unsigned long lastmillis; 
  if ( millis() - lastmillis > INTERVALL )
  {
     // dies kommt einmal alle zwei Minuten dran
     // ...
    lastmillis += INTERVALL;   
  }

Überlauf ist hier kein Thema, und INTERVALL kann bis zu 49 Tage groß werden.