Since this library sets timer2 interrupt using microseconds and not letting you counting in seconds, i've written a wrapper to allow this.
static unsigned int _msecs = 0;
static void (*_func)() = 0;
void _overFlow();
void Timer2Init();
void Timer2Func(void (*f)());
void Timer2Ms(unsigned int msecs);
void _overFlow() {
static unsigned int _counter = 0;
_counter += 1;
if ((_counter % (_msecs*2)) == 0) {
_counter = 0;
(*_func)();
}
}
void Timer2Init() {
FrequencyTimer2::setPeriod(1000);
FrequencyTimer2::setOnOverflow(_overFlow);
}
void Timer2Func(void (*f)()) {
_func = f;
}
void Timer2Ms(unsigned int msecs) {
_msecs = msecs;
}
How to use? it's very easy:
void flashLed() {
static boolean value = HIGH;
digitalWrite(13, value);
value = !value;
}
void setup() {
pinMode(13, OUTPUT);
Timer2Init();
Timer2Ms(1000); // overflow each second
Timer2Func(flashLed);
}
void loop() {
}
Do you like it?
woot, 2nd version, now with multiple triggers for the same timer!
// up to 5 "virtual" overflows with the same timer
#define _TIMERS 5
static unsigned int _msecs[_TIMERS];
static unsigned int _counters[_TIMERS];
static void (*_funcs[_TIMERS])();
void _overFlow();
void Timer2Init();
void Timer2Func(byte num, void (*f)());
void Timer2Ms(byte num, unsigned int msecs); // msecs = 0 for disabling
void _overFlow() {
byte tmp;
for(tmp = 0; tmp < _TIMERS; tmp++) {
if (_msecs[tmp] > 0) {
_counters[tmp] += 1;
if ((_counters[tmp] % (_msecs[tmp]*2)) == 0) {
_counters[tmp] = 0;
(*(_funcs[tmp]))();
}
}
}
}
void Timer2Init() {
byte tmp;
for(tmp = 0; tmp < _TIMERS; tmp++) {
_msecs[tmp] = 0;
_funcs[tmp] = 0;
_counters[tmp] = 0;
}
FrequencyTimer2::setPeriod(1000);
FrequencyTimer2::setOnOverflow(_overFlow);
}
void Timer2Func(byte num, void (*f)()) {
_funcs[num] = f;
}
void Timer2Ms(byte num, unsigned int msecs) {
_msecs[num] = msecs;
}
And a simple example:
void flash() {
static boolean output = HIGH;
digitalWrite(13, output);
output = !output;
}
void flash2() {
static boolean output = HIGH;
digitalWrite(12, output);
output = !output;
}
void setup() {
pinMode(12, OUTPUT);
pinMode(13, OUTPUT);
Timer2Init();
Timer2Ms(0, 1000); // flash a led each second
Timer2Func(0, flash);
Timer2Ms(1, 3000);
Timer2Func(1, flash2); // flash a led each 3 seconds
}
void loop() {
}
Now that v2 looks really nice.
thanks, i only hope future versions of arduino compiler support something similar since it's more user-friendly IMO
thanks, i only hope future versions of arduino compiler support something similar since it's more user-friendly IMO
It's absolutely must have for any sort of real-time programming. When I first got started with Arduino, that was the first functionality I needed, luckily someone here pointed me to FrequencyTimer2 very quickly.
That bug in the library of calling the handler twice as often as it should really threw me for a while though.
tigrezno,
I’m interested in what you’re doing here. Thanks! So I wanted to try it.
I think I’m being a little naive here, I just took your wrapper and the example and put them together into one sketch. (example first) I also added “#include <FrequencyTimer2.h>”
I get the following compile error:
In function ‘void setup()’:
error: ‘Timer2Func’ was not declared in this scope
. . . which is weird since there is a “Timer2Func” in the wrapper.
(Not that I understand it yet :))
(I even got a “fresh copy” of FrequencyTimer2)
Any help is appreciated
BroHogan, i've already done a stand-alone version (and better) that i'll post in an hour or so.
tigrezno,
Nice timer!
Great way to earn your second star! 8-)
I am running it (at 1Ms) in a pretty demanding application with lots of stuff going on.
When I was using FrequencyTimer2 in the same ap, I had to be careful with some things or I would cause a reboot.
I no longer have this issue with this timer.
Thanks!