/* Basic timer converted to polymorphic/inherited form. Utilizes virtual function to effect timer reset. reference Arduino.cc thread http://forum.arduino.cc/index.php?topic=567010.new#new */ // debounce disabled for users without the library //#include <Bounce2.h> #define BUTTON_PIN 6 // to enable the timer DIO6 #define RESET_PIN 8 // to reset a timer DIO8 #define externalLED1 7 // +5--/\/\/-->|--DIO7 byte LED_PIN = 13; // on board LED // Instantiate a Bounce object //Bounce debouncer = Bounce(); // create a class called 'PLCtimer' class PLCtimer { /* This is the base class - All types: > produce a positive-going one-scan pulse 'os' upon reaching preset value. > respond to a reset command by setting accumulated value to zero and resetting done and tt. > set the done bit upon reaching preset. */ public: unsigned long _Accumulator = 0; bool _Reset: 1; bool _Enable: 1; bool _Done: 1; bool _OSRise: 1; bool _Control: 1; private: unsigned long _Preset; unsigned long _CurrentMillis; unsigned long _LastMillis = 0; bool _TimerRunning: 1; bool _OSFall: 1; bool _OSRSetup: 1; bool _OSFSetup: 1; public: // constructor - permits setting of variables upon instantiation // Timers are instantiated with enable false by default @PLCtimer::PLCtimer(unsigned long pre, boolean en = 0) { _Preset = pre; negativePresetWarning(pre); // preset validation }; // end constructor /* User-added error handler from pert @ Arduino.cc, post #13 thread http://forum.arduino.cc/index.php?topic=559655.new#new Timers may not have a negative preset value. */ void negativeError( void ) __attribute__((error("Negative PLCtimer preset! Check instantiations!"))); void negativePresetWarning(unsigned long number) { if (number < 0) { negativeError(); } } /* ===== Access functions for timer status/controls */ // Allows to start/stop a timer void setEN(bool en) { _Enable = en; } // Allows to reset a timer void setres(bool res) { _Reset = res; } // Returns enable state of timer byte getEN() { return _Enable; } // Returns reset state of timer bool getres() { return _Reset; } // Returns done status of timer bool getDn() { return _Done; } // Returns timer timing state of timer bool getTt() { return _TimerRunning; } // Returns timer timing state of timer bool getIntv() { return _TimerRunning; } // Returns state of timer done rising one-shot bool getOSRise() { return _OSRise; } // Returns state of timer done falling one-shot bool getOSFall() { return _OSFall; } private: /* Virtual timer Reset function Reset conditions to be determined by descendants */ virtual bool Reset(); public: // Function to operate timers created under PLCtimer // ---------------------------------------- // Update timer accumulated value & condition // flags 'tt' (timer timing) and 'dn' (done) based // on timer type. // Function returns boolean status of done, 'dn' // =========================== boolean update() { _CurrentMillis = millis(); // Get system clock ticks if (_Enable or _Control) { // timer is enabled to run _Accumulator = _Accumulator + _CurrentMillis - _LastMillis; if (_Accumulator >= _Preset) { // timer done? _Accumulator = _Preset; // Don't let accumulator run away _Done = true; } } _LastMillis = _CurrentMillis; // 9/25/18 - Modified the virtual function Reset() to return // a boolean. The derived classes now only return a yes/no // to the base class to handle resetting of done and clearing // of accumulator. // This saves 50+ bytes versus resetting in the derived classes. if ( Reset()) { // Find out if reset needed based on derived class' criteria. _Done = false; _Accumulator = 0; } /* ----- Generate a positive going one-shot pulse on timer done f-t transition */ _OSRise = (_Done and _OSRSetup); _OSRSetup = !_Done; /* ----- and another positive going one-shot pulse on timer done t-f transition */ _OSFall = (!_Done and _OSFSetup); _OSFSetup = _Done; /* ----- condition the timer timing status */ if ((_Enable or _Control) and !_Done and !_Reset) { _TimerRunning = true; } else _TimerRunning = false; return _Done; }; // end of base class update Timer operation } ; // end of class PLCtimer void setup() { } void loop() { } //end of loop
var
This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)