A Ton (Timer On) is used to provide an \'on delay\' system so as to avoid using wait()
Dependents: NEWlcd_menu_v2 Garage_Control
Revision 0:748acff4e3c8, committed 2011-03-03
- 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
--- /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(); + } +}