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