Skip to content

Commit d705a10

Browse files
author
JChristensen
committed
Changed the stop() method to return TIMER_NOT_AN_EVENT when it is given a valid timer event ID. Given an invalid (out of bounds) ID, it simply returns the same ID that it was given.
Converted the ReadMe file to Markdown, added examples, reference, etc. from Dr. Monk's site. Minor cosmetic editing, tabs to spaces. Closes JChristensen#5.
1 parent daf15b9 commit d705a10

File tree

4 files changed

+338
-114
lines changed

4 files changed

+338
-114
lines changed

Event.cpp

Lines changed: 21 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -31,30 +31,30 @@
3131

3232
Event::Event(void)
3333
{
34-
eventType = EVENT_NONE;
34+
eventType = EVENT_NONE;
3535
}
3636

3737
void Event::update(void)
3838
{
39-
unsigned long now = millis();
40-
if (now - lastEventTime >= period)
41-
{
42-
switch (eventType)
43-
{
44-
case EVENT_EVERY:
45-
(*callback)(context);
46-
break;
39+
unsigned long now = millis();
40+
if (now - lastEventTime >= period)
41+
{
42+
switch (eventType)
43+
{
44+
case EVENT_EVERY:
45+
(*callback)(context);
46+
break;
4747

48-
case EVENT_OSCILLATE:
49-
pinState = ! pinState;
50-
digitalWrite(pin, pinState);
51-
break;
52-
}
53-
lastEventTime = now;
54-
count++;
55-
}
56-
if (repeatCount > -1 && count >= repeatCount)
57-
{
58-
eventType = EVENT_NONE;
59-
}
48+
case EVENT_OSCILLATE:
49+
pinState = ! pinState;
50+
digitalWrite(pin, pinState);
51+
break;
52+
}
53+
lastEventTime = now;
54+
count++;
55+
}
56+
if (repeatCount > -1 && count >= repeatCount)
57+
{
58+
eventType = EVENT_NONE;
59+
}
6060
}

ReadMe.md

Lines changed: 262 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,262 @@
1+
#Arduino Timer Library
2+
ReadMe file for version 2.0
3+
https://github.com/JChristensen/Timer
4+
5+
This library was originally developed by Dr. Simon Monk to avoid problems that arise when you start trying to do much inside the `loop()` function. It can change pin values or run a callback function. See Dr. Monk's original page [here](http://www.doctormonk.com/2012/01/arduino-timer-library.html)).
6+
7+
The library does not interfere with the built-in timers, it just uses `millis()` in a basic type of scheduler to decide when something needs doing.
8+
9+
##Examples
10+
11+
The Arduino `delay()` function is both a blessing and a curse. It's great for showing beginners how to make an LED flash. But as soon as you get more complex and start slowing down your `loop()` function you will run into problems.
12+
13+
A classic example is turning a relay on for 10 minutes. The `delay()` way looks like this:
14+
15+
```c++
16+
int pin = 13;
17+
18+
void setup()
19+
{
20+
pinMode(13, OUTPUT);
21+
digitalWrite(pin, HIGH);
22+
delay(10 * 60 * 1000);
23+
digitalWrite(pin, LOW);
24+
}
25+
26+
void loop()
27+
{
28+
}
29+
```
30+
31+
The disadvantage of the `delay()` approach is that nothing else can go on while the `delay()` is happening. You cannot update a display, or check for key presses for example.
32+
33+
The **Timer** library version looks like this:
34+
35+
```c++
36+
#include "Timer.h"
37+
38+
Timer t;
39+
int pin = 13;
40+
41+
void setup()
42+
{
43+
pinMode(pin, OUTPUT);
44+
t.pulse(pin, 10 * 60 * 1000, HIGH); // 10 minutes
45+
}
46+
47+
void loop()
48+
{
49+
t.update();
50+
}
51+
```
52+
53+
The `pulse()` method takes arguments of a pin to change, the period to change it for and its initial state.
54+
55+
The call to `t.update()` takes a matter of microseconds to run, and when the appropriate period of time has passed, it will change the state of the pin.
56+
57+
Let's look at another example that uses two timer events. One to flash an LED and another that reads analog input 0 and displays its value on the Serial Monitor.
58+
59+
```c++
60+
#include "Timer.h"
61+
62+
Timer t;
63+
int pin = 13;
64+
65+
void setup()
66+
{
67+
Serial.begin(9600);
68+
pinMode(pin, OUTPUT);
69+
t.oscillate(pin, 100, LOW);
70+
t.every(1000, takeReading, (void*)0);
71+
}
72+
73+
void loop()
74+
{
75+
t.update();
76+
}
77+
78+
void takeReading(void *context)
79+
{
80+
Serial.println(analogRead(0));
81+
}
82+
```
83+
84+
The first thing to notice is that we are using a callback function called `takeReading()`. We connect it to the Timer using the `every()` method, which in this case, will call the function every second.
85+
86+
We have also attached another event to the timer using the method `oscillate()`. This will cause the LED to toggle state every 100 milliseconds.
87+
88+
Each of the events has an integer ID associated with it, so that you can stop an event, as we do in the example below, which will write to the serial monitor every 2 seconds, flash the LED and after 5 seconds, stop the LED flashing fast, and flash it 5 times slowly.
89+
90+
```c++
91+
#include "Timer.h"
92+
93+
Timer t;
94+
int ledEvent;
95+
96+
void setup()
97+
{
98+
Serial.begin(9600);
99+
int tickEvent = t.every(2000, doSomething, (void*)0);
100+
Serial.print("2 second tick started id=");
101+
Serial.println(tickEvent);
102+
103+
pinMode(13, OUTPUT);
104+
ledEvent = t.oscillate(13, 50, HIGH);
105+
Serial.print("LED event started id=");
106+
Serial.println(ledEvent);
107+
108+
int afterEvent = t.after(10000, doAfter, (void*)0);
109+
Serial.print("After event started id=");
110+
Serial.println(afterEvent);
111+
}
112+
113+
void loop()
114+
{
115+
t.update();
116+
}
117+
118+
void doSomething(void *context)
119+
{
120+
Serial.print("2 second tick: millis()=");
121+
Serial.println(millis());
122+
}
123+
124+
void doAfter(void *context)
125+
{
126+
Serial.println("stop the led event");
127+
t.stop(ledEvent);
128+
t.oscillate(13, 500, HIGH, 5);
129+
}
130+
```
131+
132+
You can attach up to 10 events to a timer.
133+
134+
Note that the callback functions have a "context" parameter. The context value is specified when the event is created and it will be sent to callback function when the timer fires. The context is a void pointer, so it can be cast to any other data type. Its use is optional, if you don't need it, just code `(void*)0` as in the above examples, but be sure that the callback function definitions have it in their argument list, i.e. `(void *context)`.
135+
136+
##Installation
137+
138+
As with all libraries, unzip the file into the *libraries* folder in your Arduino sketchbook directory, which will be something like *My Documents\Arduino\sketchbook* on Windows, *Documents/Arduino/sketchbook* on Mac etc. If this is the first library you have installed, you will need to create a directory there called *libraries*.
139+
140+
The Timer library is compatible with both Arduino 1.0+ and earlier versions.
141+
142+
##Reference
143+
144+
###every();
145+
#####Description
146+
Runs the *callback* function every *period* milliseconds. Optionally stops after *repeatCount* times.
147+
#####Syntax
148+
`t.every(period, callback, context);`
149+
`t.every(period, callback, repeatCount, context);`
150+
#####Parameters
151+
***period:*** How often to run the callback function, in milliseconds *(unsigned long)*
152+
***callback:*** The name of the callback function which is called when the timer event fires *(function pointer)*
153+
***repeatCount:*** The number of times to run the callback function *(int, optional)*
154+
***context:*** Context value to be passed to the callback function *(void pointer)*
155+
#####Returns
156+
The ID of the Timer event *(int8_t or char)*
157+
158+
###after();
159+
#####Description
160+
Run the *callback* function once, after *period* milliseconds.
161+
#####Syntax
162+
`t.after(period, callback, context);`
163+
#####Parameters
164+
***period:*** How long to wait before running the callback function, in milliseconds *(unsigned long)*
165+
***callback:*** The name of the callback function which is called when the timer event fires *(function pointer)*
166+
***context:*** Context value to be passed to the callback function *(void pointer)*
167+
#####Returns
168+
The ID of the Timer event *(int8_t or char)*
169+
170+
###oscillate();
171+
#####Description
172+
Toggle the state of the digital output *pin* every *period* milliseconds. The pin's starting value is specified by *startingValue*, which should be HIGH or LOW. Optionally stops after *repeatCount* times.
173+
#####Syntax
174+
`t.oscillate(pin, period, startingValue);`
175+
`t.oscillate(pin, period, startingValue, repeatCount);`
176+
#####Parameters
177+
***pin:*** The number of the pin to oscillate *(uint8_t or byte)*
178+
***period:*** How often to toggle the pin, in milliseconds *(unsigned long)*
179+
***startingValue:*** HIGH or LOW, the state at which the pin will start *(uint8_t or byte)*
180+
***repeatCount:*** Optional number of toggles to stop after *(int)*
181+
#####Returns
182+
The ID of the Timer event *(int8_t or char)*
183+
184+
###pulse();
185+
#####Description
186+
Generates a pulse of *!startingValue*, occuring *period* after the call to this method and lasting for *period*. The *pin* will be left in *!startingValue* state.
187+
#####Syntax
188+
`t.pulse(pin, period, startingValue);`
189+
#####Parameters
190+
***pin:*** The number of the pin to pulse *(uint8_t or byte)*
191+
***period:*** The pulse period in milliseconds *(unsigned long)*
192+
***startingValue:*** HIGH or LOW, the state at which the pin will start *(uint8_t or byte)*
193+
#####Returns
194+
The ID of the Timer event *(int8_t or char)*
195+
196+
###pulseImmediate();
197+
#####Description
198+
Generates a pulse of *startingValue*, which begins immediately and lasts for *period*. The *pin* will be left in the *!startingValue* state.
199+
#####Syntax
200+
`t.pulseImmediate(pin, period, pulseValue);`
201+
#####Parameters
202+
***pin:*** The number of the pin to pulse *(uint8_t or byte)*
203+
***period:*** The pulse period in milliseconds *(unsigned long)*
204+
***startingValue:*** HIGH or LOW, the state at which the pulse will start *(uint8_t or byte)*
205+
#####Returns
206+
The ID of the Timer event *(int8_t or char)*
207+
208+
###stop();
209+
#####Description
210+
Stops the given timer event.
211+
#####Syntax
212+
`t.stop(timerID);`
213+
#####Parameters
214+
***timerID:*** The number of the timer event to be stopped, as returned previously by one of the other functions, e.g. `every()`, `after()`, `oscillate()`, etc.
215+
#####Returns
216+
If a valid *timerID* is given, returns TIMER_NOT_AN_EVENT to indicate that the timer was successfully stopped. By default, the library supports up to 10 events per timer; the valid range is therefore 0-9. If a value outside this range is given, that same value is returned.
217+
218+
###update();
219+
#####Description
220+
Must be called from `loop()`. This will service all the events associated with the timer.
221+
#####Syntax
222+
`t.update();`
223+
#####Parameters
224+
None.
225+
#####Returns
226+
None.
227+
228+
##Revision History
229+
230+
####1.0 by Simon Monk
231+
- Library as downloaded 02Feb2012 22:55 UTC from http://srmonk.blogspot.com/2012/01/arduino-timer-library.html
232+
233+
####1.1 by Jack Christensen
234+
Changed data types of variables and functions:
235+
- event types and indexes changed from int to int8_t.
236+
- periods and durations changed from long to unsigned long.
237+
- update() and stop() functions typed as void, since they return nothing.
238+
- pin numbers and pin values changed from int to uint8_t, this agrees with digitalWrite().
239+
- added return values to Timer::pulse() and Timer::oscillate(uint8_t, unsigned long, uint8_t).
240+
- changed test in Event::update() to use subtraction to avoid rollover issues.
241+
- Updated keywords.txt file to include all functions.
242+
243+
####1.2 by Damian Philipp
244+
- Added a range check to Timer::stop() to avoid memory corruption.
245+
- Added constants to <Timer.h>:
246+
- NO_TIMER_AVAILABLE: Signals that while an event was to be queued, no free timer could be found.
247+
- TIMER_NOT_AN_EVENT: Can be used to flag a variable that *might* contain a timer ID as *not* containing a timer ID
248+
- Replaced a bunch of magic numbers in Timer.cpp with the above constants
249+
- Added several comments
250+
- Added Timer::pulseImmediate(). pulseImmediate sets the pin to the specified value for the given duration. After the duration, the pin is set to !value.
251+
252+
####1.3 by Jack Christensen
253+
- Added "blink2" example illustrating flashing two LEDs at different rates.
254+
- 19Oct2013: This is the last v1.x release. It will continue to be available on GitHub as a branch named v1.3. Future development will continue with Sandy Walsh's v2.0 which can pass context (timer ID, etc.) to the callback functions.
255+
256+
####2.0 by Sandy Walsh
257+
- Added a "context" parameter to callbacks. You can pass in the context when the event is created and it will be sent back to callback when called. If you don't have any context data you want to pass in (let's say you're using separate callbacks for each timer), you can just pass in 0 and ignore it in the callback.
258+
259+
####2.1 by ThoMo
260+
- Changed the stop() method to return TIMER_NOT_AN_EVENT when it is given a valid timer event ID. Given an invalid (out of bounds) ID, it simply returns the same ID that it was given.
261+
- Converted the ReadMe file to Markdown, added examples, reference, etc. from Dr. Monk's site. *[jc]*.
262+
- Minor cosmetic editing, tabs to spaces *[jc]*.

ReadMe.txt

Lines changed: 0 additions & 36 deletions
This file was deleted.

0 commit comments

Comments
 (0)