#pragma once namespace Combie { namespace Timer { class TriggerableBool // Interface { protected: bool state = false; virtual bool doTrigger(const bool trigger) = 0; virtual ~TriggerableBool() {} bool operator() (const bool trigger) { return doTrigger(trigger); } bool operator() () { return state; } bool operator= (const bool trigger) { return doTrigger(trigger); } operator bool() const { return state; } }; class SimpleTimer { private: uint32_t timeStamp; // Zeitmerker bool reached; // default Status: timer abgelaufen public: SimpleTimer():timeStamp(0),reached(true){} void start() { timeStamp = millis(); reached = false; } void reset() { reached = true; } bool operator()(const uint32_t interval) { if(!reached) reached = millis() - timeStamp >= interval; return reached; } }; class Pulsator // liefert alle X ms einen HIGH Impuls { protected: SimpleTimer timer; uint32_t interval; public: Pulsator(uint32_t interval):interval(interval){} void setInterval(const uint32_t interval) { this->interval = interval; } void start() { timer.start(); } operator bool() { bool result = false; if(timer(interval)) { result = true; timer.start(); } return result; } }; class EdgeTimer // EdgeTimer: Die Mutter der Flankenverzoegerer { protected: SimpleTimer timer; uint32_t interval; public: EdgeTimer(const uint32_t interval):interval(interval){} void setInterval(const uint32_t _interval) { interval = _interval; } }; class FallingEdgeTimer: protected EdgeTimer, protected TriggerableBool // abfallende Flanke wird verzoegert { public: using EdgeTimer::EdgeTimer; using EdgeTimer::setInterval; using TriggerableBool::operator(); using TriggerableBool::operator=; using TriggerableBool::operator bool; virtual bool doTrigger(const bool trigger) override { if(trigger) timer.start(); state = !timer(interval); return state; } void reset() { timer.reset(); state = false; } }; class RisingEdgeTimer: protected EdgeTimer, protected TriggerableBool // steigende Flanke wird verzoegert { public: using EdgeTimer::EdgeTimer; using EdgeTimer::setInterval; using TriggerableBool::operator(); using TriggerableBool::operator=; using TriggerableBool::operator bool; virtual bool doTrigger(const bool trigger) override { if(!trigger) timer.start(); state = timer(interval); return state; } void reset() { timer.reset(); state = false; } }; class Debounce: protected TriggerableBool { private: SimpleTimer timer; const uint32_t interval; public: Debounce(const uint32_t interval = 20) : interval(interval) {} using TriggerableBool::operator(); using TriggerableBool::operator=; using TriggerableBool::operator bool; virtual bool doTrigger(const bool trigger) override { if(state == trigger) timer.start(); if(timer(interval)) state = !state; return state; } }; class PpmGenerator // Puls Pausen Modulation { private: bool state; // zustandsmerker Puls oder Pause uint32_t onInterval; uint32_t offInterval; SimpleTimer timer; public: PpmGenerator():state(false),onInterval(500),offInterval(500){} PpmGenerator(const uint32_t onInterval,const uint32_t offInterval):state(false),onInterval(onInterval),offInterval(offInterval){} inline void setOnInterval(const uint32_t value) { onInterval = value; } inline void setOffInterval(const uint32_t value) { offInterval = value; } operator bool() { if(timer(state?onInterval:offInterval)) { state = !state; timer.start(); } return state; } }; class TimeRelay: protected TriggerableBool { protected: RisingEdgeTimer ton ; FallingEdgeTimer toff; public: explicit TimeRelay(const unsigned long roseDelay, const unsigned long fellDelay): ton{roseDelay}, toff{fellDelay}{} using TriggerableBool::operator(); using TriggerableBool::operator=; using TriggerableBool::operator bool; virtual bool doTrigger(const bool trigger) override { return state = toff = ton = trigger; } }; // compatibility aliases using ZeitRelaisErsatzstoff = TimeRelay; using EntprellTimer = Debounce; } }