Go Down

Topic: millis() überlauf umgehen? (Read 2988 times) previous topic - next topic

mpl1337

Hallo,

da der ja bekannterweiße millis iwann voll ist dachte ich mir ich setze einfach auf second(); von der time lib welche per DCF77 gefüttert wird?

ich müsste das dann etwas anders gestalten aber sind aufgaben welche ca nur alle 30 sekunden mal ausgeführt werden sollen.

oder läuft in der time lib auch iwann mal was über?

im grunde so aufgebaut

Code: [Select]

#include <DCF77.h>
#include <Time.h>

#define DCF_PIN 23
#define DCF_INTERRUPT 23

time_t time;

  DCF.Start();
  setSyncInterval(30);
  setSyncProvider(DCF.getTime);

time_t DCFtime = DCF.getTime(); // Check if new DCF77 time is available
  if (DCFtime!=0)
  {
    Serial.println("Time is updated");
    setTime(DCFtime);
  } 



combie

Quote
sind aufgaben welche ca nur alle 30 sekunden mal ausgeführt werden sollen.
Dann spielt der millis() Überlauf doch gar keine Rolle....
Man sollte keine Dummheit zweimal begehen, die Auswahl ist schließlich groß genug.
Quelle: Jean-Paul Sartre

mpl1337

Bleibt da der Controller nicht hängen? Dann tut der Doch Garnichts mehr...

agmue

Nee, der fängt einfach bei Null von vorne an.  :)
Die Vorstellungskraft ist wichtiger als Wissen, denn Wissen ist begrenzt. (Albert Einstein)

sschultewolter

Nö, der Wert fängt wieder bei 0 an.
Orginal Atmel AVRISP mkII zu verkaufen. Anfrage per PN ;)

mpl1337

Achso :D verbinde overflow immer noch mit sicherheitslücken und exploits und da startet das Betriebssystem oder das Programm in der Regel nicht einfach mal neu ohne etwas ungewolltes noch zu tun

combie

#6
Oct 25, 2015, 09:43 pm Last Edit: Oct 25, 2015, 09:44 pm by combie
Counter Overflows sind ganz normal. Sie stellen kein Problem dar, wenn man sie kennt und korrekt abhandelt.

Man sollte keine Dummheit zweimal begehen, die Auswahl ist schließlich groß genug.
Quelle: Jean-Paul Sartre

mpl1337

Also wird das Programm im schlimmsten Fall einen Durchlauf auslassen.

sschultewolter

Nein! Besorge dir mal Lektüre, oder google im Internet.

Die Thematik wird 1000fach angesprochen.

Wenn ich von einem Wert x (hier ausgehend von einem Byte) einen Wert y abziehe, der größer x ist, geschieht folgendes

x = 10;
y = 11;

x = x - y;
x hat nun den Wert 255. Eigentlich würde man jetzt sagen, das Ergebnis müsste -1 sein. Da es sich aber bei einem byte oder unsigned long um einen Wertebereich aus positiven Zahlen (ohne Vorzeichen handelt), stellt der Wert -1 den höchst möglichen Wert von dem Werteberech da. (2^8)-1 ergbit 255. Somit kümmert dich der Werteüberlauf nicht, solange beim unsigned long du keine Wartezeiten von irgendwas um die 40 Tage hast.
Orginal Atmel AVRISP mkII zu verkaufen. Anfrage per PN ;)

combie

#9
Oct 26, 2015, 10:23 am Last Edit: Oct 26, 2015, 10:24 am by combie
Also wird das Programm im schlimmsten Fall einen Durchlauf auslassen.
Nein!
Bei korrekter Abhandlung nicht.....


Hier mal ein Beispiel aus meiner Wühlkiste, ein Blinker welcher ohne Unterlass blinkt.
Wird ein exakter Zeitpunkt verpasst, wird dieses aufgeholt.
Code: [Select]

class TimerTick
{
  private:
  unsigned long lastHit;
  unsigned long interval;
 
  public:
  TimerTick(unsigned long interval):interval(interval){}
 
  bool abgelaufen()
  {
    if(millis() - lastHit >= interval)
    {
        lastHit += interval; // mit aufholjagt
        return true; 
    }
    return false;
  } 
};

const byte led = 13;
TimerTick timer(500); // alle 0,5 sec


void tuwas()
{
    digitalWrite(led,!digitalRead(led)); // toggle LED
}

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

void loop()
{
  if(timer.abgelaufen()) tuwas();   
}
Man sollte keine Dummheit zweimal begehen, die Auswahl ist schließlich groß genug.
Quelle: Jean-Paul Sartre

Chris72622

#10
Oct 26, 2015, 01:15 pm Last Edit: Oct 26, 2015, 07:58 pm by uwefed
Ich mach auch immer:

Code: [Select]
if (millis() - letzterZeitpunkt >= zeitdauer)

Funktioniert astrein.

Gruß Chris
Bilnk wtiohut daley.

uxomm

Genau!

Eine kleine Zusammenfassung:  :)
millis() zählt die Millisekunden seit Prozessorstart. Es ist eine Variable vom Typ unsigned long und kann deshalb von 0 bis 4294967295 zählen. Das bedeutet dass sie nach "fast 50 Tagen" (wie es im Arduino-Manual heißt) überläuft, um genau zu sein nach 49,71 Tagen (49 Tage, 17 Stunden, ...).

Häufig wird millis() zum messen von Zeitintervallen verwendet (dafür ist es ja auch gedacht). Wenn man also Rechenoperationen mit millis() durchführt kann der Überlauf ein Problem sein, aber nur wenn man es falsch macht.

Richtig macht man es so:

 - unsigned long für Zeitvariable verwenden (und nicht long oder int)
 - einen Startzeitpunkt festhalten
 - den Startzeitpunkt von der aktuellen Zeit subtrahieren um auf die Differenz zu kommen
 - überprüfen ob diese Differenz größer ist als das gewünschte Intervall

z.B.: Intervall ist 5 Sekunden (5000 millis)

Code: [Select]
unsigned long startTime = millis();
unsigned long interval  = 5000;

...

if ( millis() - startTime >= interval )
{
    // mach was
}


So wird selbst bei einem Überlauf von millis richtig gezählt.
Always decouple electronic circuitry.

mpl1337

Super, vielen Dank. Habt mir echt geholfen :) dann kann ich mich jetzt dran machen alle Waits raus zu hauen :)

Chris72622

#13
Oct 26, 2015, 07:29 pm Last Edit: Oct 26, 2015, 07:31 pm by Chris72622
Code: [Select]
unsigned long interval  = 5000;
Hätte man das nicht per Integer lösen können?

Gruß Chris
Bilnk wtiohut daley.

agmue

Wenn Du an const int interval  = 5000; denkst, dann sicherlich. Bei einer Variablen kommt es aber darauf an, was Du im Programm so vorhast ;)
Die Vorstellungskraft ist wichtiger als Wissen, denn Wissen ist begrenzt. (Albert Einstein)

Go Up