Unsigned long subtrahieren für Timer

Hallo zusammen und Fohe Weihnachten gehabt zu haben!

Ich habe mich an einem Punkt fest gerannt und sehe vermutlich den Wald vor Bäumen nicht.

Für ein Projekt brauche ich einen Timer über mehrere Minuten. Weil ein Durchlauf der Loop jenachdem was der Yun alles zu tun hat immer unterschiedlich lang ist, hatte ich mir folgenden Ansatz überlegt:

Int timerInSekunden = 240; // Beispiel zum Testen, wird später dynamisch festgelegt
Unsigned Long timerEnde = millis() + (240*1000);

Um nun die Länge des verbleibenden Timers anzeigen zu lassen müsste ich doch eigentlich nur alles genau einmal umdrehen:

Int restZeit = (timerEnde - millis()) / 1000;

Das müsste mir doch in Sekunden die übrige Zeit rauswerfen (bei negativen Werten wäre der Timer abgelaufen) oder? Leider bekomme ich alle möglichen Werte ohne erkennbaren zusammenhang da raus (500, 90, 376 etc)

Wo habe ich den Denkfehler drin?

Danke schon mal für alle Zaupfahl auf den Kopf zum Erwachen Schläge,

Grüße

Steve

unsigned long timerEnde = millis() + (240*1000L);
nicht dass es sowas triviales ist

Unsigned Long timerEnde = millis() + (240*1000);

Das ist aus 2 Gründen böse:

  • Die Multiplikaton dürfte eine int Multiplikation sein, mit (unbemerktem) Überlauf
  • Die Addition kann auch einen Überlauf erzeugen, welchen du nicht mehr korrigieren kannst.
Int restZeit = (timerEnde - millis()) / 1000;

Ein drohnder Unterlauf

Der zweite "böse" Effekt tritt erst knapp 50 Tage nach Reset auf, wird also nicht so auffällig sein.

Werde ich nachher mal ausprobieren mit dem L am Ende, aber könnte gut der Grund sein.

Welche anderen Möglichkeiten gäbe es denn einen Teimer in Minutengröße zu machen. Die Internen mit Overflow interrupt denke ich mal sind im Minuten Bereich eher nicht geeignet.

Ansonsten muß ich bei meiner Lösung natürlich die Beiden Möglichkeiten abfangen, sowas hatte ich schon im Hinterkopf.

Danke schon mal für die Infos

Hallo,

eigentlich ganz einfach.

void zeitgesteuert ()
{
  static unsigned long last_ms = 0;
  const unsigned long intervall = 600000;   // 10min
      
  if (millis() - last_ms > intervall) {
    last_ms = millis();
    
    ...
    mach was sinnvolles aller x [ms]
    ...
  }
}

oder

void zeitgesteuert ()
{
  static unsigned long last_ms = 0;
  const unsigned long intervall = 600000;   // 10min
		
  if (millis() - last_ms < intervall) return;
	
  last_ms += intervall;
    
  ...
  mach was sinnvolles aller x [ms]
  ...

}

mit der 2. Variante gibts keinen Drift. 10min bleiben 10min.
Bei der ersten Variante addiert sich immer die restliche Code Laufzeit dazu.

Es war sowas simples wie das kleine unscheinbare "L" :frowning:

Die anderen Lösungen sind auch interessant. Schaue ich mir auf jedenfall auch genauer an.

Danke für die Hilfe und Allen einen guten Rutsch ins Neue Jahr!!!

Steve