Timer ohne Überlauf

Arduino-Bastelprojekt: Lange Laufzeiten mit millis() ohne Überlauf-Probleme.

TURBINE NIEDERNDORFER MUEHLE
TURBINE NIEDERNDORFER MUEHLE

Bei Arduino-Projekten wird oft millis() für zeitgesteuerte Aktionen genutzt. Nach etwa 49 Tagen läuft der 32-Bit-Zähler über – eine naive Abfrage wie if (millis() - lastTime > interval) kann dann fehlschlagen. Diese Timer-Klasse umgeht das Problem, indem sie die vergangene Zeit kumuliert statt mit dem aktuellen millis()-Wert zu vergleichen.

Materialien

Verwendung

Timer updateLCD(1 * TIMER_SECONDS);   // alle 1 Sekunde
Timer storeValue(15 * TIMER_SECONDS); // alle 15 Sekunden

void loop() {
  if (updateLCD.check()) {
    // wird jede Sekunde ausgeführt
  }
  if (storeValue.check()) {
    // wird alle 15 Sekunden ausgeführt
  }
}

Der Trick: Statt ul_PreviousMillis = millis() wird ul_PreviousMillis += ul_Interval gesetzt. So bleibt die Zeitlogik auch nach einem Überlauf von millis() korrekt. Optional kann der Timer aus dem EEPROM geladen und gespeichert werden – nützlich für Geräte, die über lange Zeit laufen.

#include "./Timer.h"

// initiate

Timer::Timer(){ // just create object
  setInterval(0);
}

Timer::Timer(void* ee){ // load value from eeprom (4 bytes)
  int ee_int = (int)ee;
  ee_addr = (ee_int>=0 && ee_int<EEPROM.length()) ? ee_int : -1;
  unsigned long value = 0;
  if(ee_addr>=0) EEPROM_readAnything(ee_addr, value);
  setInterval(value);
}

Timer::Timer(unsigned long value){ // set value
  setInterval(value);
}


void Timer::setInterval(unsigned long value){
  ul_Interval = value;
  if(ee_addr>=0) EEPROM_writeAnything(ee_addr, ul_Interval);
}

unsigned long Timer::getInterval(void){
  return ul_Interval;
}

boolean Timer::check(){
  if(millis()-ul_PreviousMillis <= ul_Interval)
    return false;
  ul_PreviousMillis += ul_Interval;
  return true;
}
#ifndef TIMER_H
#define TIMER_H

#include "Arduino.h"
#include <EEPROM.h> // required for EEPROMAnything.h
#include "./EEPROMAnything.h"

#define TIMER_SECONDS 1000
#define TIMER_MINUTES TIMER_SECONDS*60
#define TIMER_HOURS   TIMER_MINUTES*60

class Timer{
  public:
    Timer(void); // just create object
    Timer(void* ee); // load timer from eeprom addr.
    Timer(unsigned long value); // initiate and set value (without eeprom)
    void setInterval(unsigned long value); // in Milliseconds
    unsigned long getInterval(void); // in Milliseconds
    boolean check(void);
	// TODO: void restart(void);
	// TODO: void pause(void);
	// TODO: void continue(void);
    // TODO: unsigned long remaining(void); // in Milliseconds
  private:
    unsigned long ul_PreviousMillis;
    unsigned long ul_Interval;
    int ee_addr = -1;
};

#endif
TURBINE NIEDERNDORFER MUEHLE
TURBINE NIEDERNDORFER MUEHLE
STEUERUNG TURBINE
STEUERUNG TURBINE
STELLMOTOR WASSEREINLASS
STELLMOTOR WASSEREINLASS
AUSSENBEREICH MUEHLE
AUSSENBEREICH MUEHLE
TURBINENRAUM
TURBINENRAUM

Kommentare

→

Zum Absenden den Slider nach rechts ziehen


Weitere Artikel

Gefällt dir die Webseite? Unterstütz die werbefreie Seite mit einer Spende.

© Veit Götz 2012 - 2026
Impressum
Datenschutz
Statistiken