A Ton (Timer On) is used to provide an \'on delay\' system so as to avoid using wait()

Dependents:   NEWlcd_menu_v2 Garage_Control

Files at this revision

API Documentation at this revision

Comitter:
AjK
Date:
Thu Mar 03 15:30:13 2011 +0000
Child:
1:55c67a056031
Commit message:
1.0 See ChangeLog.h

Changed in this revision

ChangeLog.h Show annotated file Show diff for this revision Revisions of this file
Ton.h Show annotated file Show diff for this revision Revisions of this file
example1.h Show annotated file Show diff for this revision Revisions of this file
example2.h Show annotated file Show diff for this revision Revisions of this file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ChangeLog.h	Thu Mar 03 15:30:13 2011 +0000
@@ -0,0 +1,5 @@
+/* $Id:$
+
+1.0     03/Mar/2011
+        Initial release.
+        
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Ton.h	Thu Mar 03 15:30:13 2011 +0000
@@ -0,0 +1,165 @@
+/*
+    Copyright (c) 2011 Andy Kirkham
+ 
+    Permission is hereby granted, free of charge, to any person obtaining a copy
+    of this software and associated documentation files (the "Software"), to deal
+    in the Software without restriction, including without limitation the rights
+    to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+    copies of the Software, and to permit persons to whom the Software is
+    furnished to do so, subject to the following conditions:
+ 
+    The above copyright notice and this permission notice shall be included in
+    all copies or substantial portions of the Software.
+ 
+    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+    IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+    AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+    LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+    OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+    THE SOFTWARE.
+*/
+
+#ifndef AJK_TON_H
+#define AJK_TON_H
+
+#include "mbed.h"
+
+namespace AjK {
+
+/** @defgroup API The Ton API */
+
+/** Ton module
+ *
+ * @author Andy Kirkham
+ * @see API
+ * @see example1.h
+ * @see example2.h
+ *
+ */
+class Ton {
+
+protected:
+    bool    _lastInput;
+    int     _counter;
+    int     _reload;
+    int     _mode;
+    Ticker  _tick;
+    
+    /** init
+     * Used to init the properties.
+     */
+    void init(void) {
+        _lastInput = false;
+        _mode      = InputResets;
+        _tick.attach_us(this, &Ton::ticktock, 1000);
+    }
+    
+public:
+    friend class Ticker;
+    
+    /** Mode
+     */
+    enum Mode {
+        InputResets = 0,    /*!< Loss of input resets the timer. */
+        InputPauses         /*!< Loss of input pauses the timer. */
+    };
+    
+    /** ticktock
+     * Used by the Ticker object to call to once per millisecond.
+     */
+    void ticktock(void) {
+        switch (_mode) {
+        case InputResets:
+            if (_lastInput) {
+                if (_counter > 0) _counter--;
+            }
+            else {
+                _counter = _reload;
+            }
+            break;
+        case InputPauses:
+            if (_lastInput) {
+                if (_counter > 0) _counter--;
+            }
+            break;
+        }
+    }
+    
+    /** setTime
+     * Used to set the timer value, in milliseconds.
+     * @ingroup API
+     * @param int i The value to time.     
+     */
+    void setTime(int i) { _counter = _reload = i; }
+    
+    /** getTime
+     * Used to get the timer value, in milliseconds.
+     * @ingroup API
+     * @return int The value to time.     
+     */
+    int getTime(void) { return _reload; }
+    
+    /** getTimeLeft
+     * Used to get the timer value remaining, in milliseconds.
+     * @ingroup API
+     * @return int The time remaining to zero (timeout). 
+     */
+    int getTimeLeft(void) { return _reload - _counter; }
+    
+    /** setMode
+     * Set the Ton operational mode.
+     * Valid values are Ton::InputResets or Ton::InputPauses.
+     * The default mode is Ton::InputPauses
+     * @ingroup API
+     * @see Mode
+     * @param enum Mode
+     */
+    void setMode(Mode i) { _mode = i; }
+    
+    /** reset
+     * Resets the timer to the default value.
+     * @ingroup API
+     */
+    void reset(void) { _counter = _reload; }
+    
+    /** reset
+     * Overloaded method, reset the timer to the value supplied.
+     * @ingroup API
+     * @param int i The time to count.
+     */
+    void reset(int i) { _counter = _reload = i; }
+    
+    /** Constructor
+     */
+    Ton(int to, int mode = InputResets) { init(); _counter = _reload = to; _mode = mode; }
+    
+    /** Destructor
+     */
+    ~Ton() { _tick.detach(); }
+    
+    /** operator=
+     * Controls the starting of the timer.
+     * @ingroup API
+     */
+    Ton& operator= (int value) {
+        _lastInput = value ? true : false;
+        if (_mode == InputResets && !_lastInput) _counter = _reload; 
+        return *this;
+    }
+    
+    /** operator int()
+     * @ingroup API
+     * @return zero if not timed out yet, non-zero otherwise.
+     */
+    operator int() {
+        return (_counter == 0) ? 1 : 0;
+    }
+        
+};
+
+}; // namespace AjK ends.
+
+using namespace AjK;
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/example1.h	Thu Mar 03 15:30:13 2011 +0000
@@ -0,0 +1,50 @@
+/* 
+ * This example DOES NOT use a Ton timer. It shows how
+ * beginners often "abuse" wait() to wait for a period
+ * of time before actioning something. As shown here we
+ * delay the switching on an LED after an input is asserted.
+ *
+ * The problem is that they "interfer" with each other. Using
+ * wait() to wait around causes the entire system to hold up
+ * waiting some period of time. As you can see, this holds up
+ * the main() systems while(1) loop preventing any other task
+ * or process from being performed.
+ *
+ * THIS IS AN EXAMPLE OF HOW NOT TO DO IT!
+ *
+ * To see how the Ton object can fix this issue see example2.h
+ */
+#include "mbed.h"
+
+DigitalIn ip1(p19);
+DigitalIn ip2(p20);
+
+DigitalOut led1(LED1);
+DigitalOut led2(LED2);
+
+void f1(void) {
+    if (ip1) {
+        wait(2);
+        led1 = 1;
+    }
+    else {
+        led1 = 0;
+    }
+}
+
+void f2(void) {
+    if (ip2) {
+        wait(2);
+        led2 = 1;
+    }
+    else {
+        led2 = 0;
+    }
+}
+
+int main() {
+    while(1) {
+        f1(); // Do process f1()
+        f2(); // Do process f2()
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/example2.h	Thu Mar 03 15:30:13 2011 +0000
@@ -0,0 +1,61 @@
+/*
+ * This example shows how to "delay" an action yet still
+ * have the system response to other tasks or processes.
+ *
+ * Note, f1() and f2() do the same thing. They are just 
+ * coded in different ways to show how versitile the Ton
+ * object is.
+ *
+ * Note how setting a Ton to non-zero starts the timer.
+ * Reading the value of a Ton object will return zero if
+ * the timer has not yet been reached. It will return a
+ * non-zero value (1) if the timeout value is reached.
+ *
+ * Tons can operate in one of two modes. The default mode
+ * is Ton::InputResets and what this means is setting a Ton
+ * to zero will reset the interval timer back to it's default
+ * value thus forcing a complete retime next time a Ton is 
+ * asserted.
+ * 
+ * The other mode, Ton::InputPauses doesn't reset the internal
+ * counter, it just halts it. So when a future event starts the
+ * timer again it doesn't time the entire timer value but the
+ * remaining value left since it's last assertion.
+ * 
+ * The mode is set when created, eg:-
+ * Ton t1(2000, Ton::InputResets); // (default)
+ * Ton t1(2000, Ton::InputPauses); // (pause mode)
+ */
+#include "mbed.h"
+#include "Ton.h"
+
+DigitalIn ip1(p19);
+DigitalIn ip2(p20);
+
+DigitalOut led1(LED1);
+DigitalOut led2(LED2);
+
+Ton t1(2000);
+Ton t2(2000);
+
+void f1(void) {
+    t1 = ip1;
+    led1 = t1;
+}
+
+void f2(void) {
+    t2 = ip2;
+    if (t2) {
+        led2 = 1;
+    }
+    else {
+        led2 = 0;
+    }
+}
+
+int main() {
+    while(1) {
+        f1();
+        f2();
+    }
+}