The Ticker interface is used to setup a recurring interrupt to repeatedly call a function at a specified rate.
Any number of Ticker objects can be created, allowing multiple outstanding interrupts at the same time. The function can be a static function, or a member function of a particular object.
#include "mbed.h"
Ticker flipper;
DigitalOut led1(LED1);
DigitalOut led2(LED2);
void flip() {
led2 = !led2;
}
int main() {
led2 = 1;
flipper.attach(&flip, 2.0); // the address of the function to be attached (flip) and the interval (2 seconds)// spin in a main loop. flipper will interrupt it to call flipwhile(1) {
led1 = !led1;
wait(0.2);
}
}
The handler registered with the underlying timer interrupt.
Warning
Note that timers are based on 32-bit int microsecond counters, so can only time up to a maximum of 2^31-1 microseconds i.e. 30 minutes. They are designed for times between microseconds and seconds. For longer times, you should consider the time()/Real time clock.
No blocking code in ISR
In ISR you should avoid any call to wait, infinitive while loop, or blocking calls in general.
No printf, malloc, or new in ISR
In ISR you should avoid any call to bulky library functions. In particular, certain library functions (like printf, malloc and new) are non re-entrant and their behaviour could be corrupted when called from an ISR.
RTOS Timer
Consider using the mbed RTOS Timer instead of a Ticker. In this way your periodic function will not be executed in a ISR, giving you more freedom and safety in your code.
#include "mbed.h"// A class for flip()-ing a DigitalOut class Flipper {
public:
Flipper(PinName pin) : _pin(pin) {
_pin = 0;
}
void flip() {
_pin = !_pin;
}
private:
DigitalOut _pin;
};
DigitalOut led1(LED1);
Flipper f(LED2);
Ticker t;
int main() {
t.attach(&f, &Flipper::flip, 2.0); // the address of the object, member function, and interval// spin in a main loop. flipper will interrupt it to call flipwhile(1) {
led1 = !led1;
wait(0.2);
}
}
When I create multiple Ticker objects, are the attached functions executed in parallel? E.g. When I have one ticker updating the first line of a LCD every second, and other ticker updating the second line of the same LCD every 5 second, do I need some form of synchronization (a semaphore) or are these calls executed after each other?
When I create multiple Ticker objects, are the attached functions executed in parallel? E.g. When I have one ticker updating the first line of a LCD every second, and other ticker updating the second line of the same LCD every 5 second, do I need some form of synchronization (a semaphore) or are these calls executed after each other?
The example code for Ticker in the "mbed" library browser declares the ticker object using the identifier "timer". Would "ticker" be a more appropriate identifier? There's nothing wrong with the code, but this caused me a little confusion between the Timer and Ticker classes for about half an hour. All sorted now :) (P.S. mbed is a superb product)
Just a suggestion...
The example code for Ticker in the "mbed" library browser declares the ticker object using the identifier "timer". Would "ticker" be a more appropriate identifier? There's nothing wrong with the code, but this caused me a little confusion between the Timer and Ticker classes for about half an hour. All sorted now :) (P.S. mbed is a superb product)
Hendrick; they don't execute in parallel, as one will get there first and they both have the same priority. So you should be fine
John; thanks for the pointer. I'll note that to be updated at the next natural point.
Simon
Hendrick; they don't execute in parallel, as one will get there first and they both have the same priority. So you should be fine
John; thanks for the pointer. I'll note that to be updated at the next natural point.
Simon
AFAIK one microsecond (when you use the attach_us methods). But then your callbacks would need to be really fast...
<<quote 81144825>>
how small can I make the wait time?
<</quote>>
AFAIK one microsecond (when you use the attach_us methods). But then your callbacks would need to be really fast...
My question is the opposite...how LONG can I make the wait time?
I have two tickers set up, one that goes off every 0.25 seconds, and another that goes off...well, if I set it to every minute, they both work, if I set it to every hour (60.0*60.0) then the shorter one never goes off. And I haven't waited around long enough to see if the longer one does ;)
My question is the opposite...how LONG can I make the wait time?
I have two tickers set up, one that goes off every 0.25 seconds, and another that goes off...well, if I set it to every minute, they both work, if I set it to every hour (60.0*60.0) then the shorter one never goes off. And I haven't waited around long enough to see if the longer one does ;)
How do I pass arguments to a function that is to be attached using the Ticker function.
for e.g using the above example if the function flip was something like
void flip (int x)
{
x= x+1;
}
How do I attacn this function with Ticker???
How do I pass arguments to a function that is to be attached using the Ticker function.
for e.g using the above example if the function flip was something like
void flip (int x)
{
x= x+1;
}
How do I attacn this function with Ticker???
I have the function: void ledpwmonoff(int lednr) {
And the ticker attach attempt: ticker.attach(&ledpwmonoff(1),24.0);
Which gives the error: expression must be an lvalue or a function designator (E158)
tried some (()()())))()()'s around ledpwnonoff in the attach, but didn't work.
I have the same question as Kunai.
I have the function: void ledpwmonoff(int lednr) {
And the ticker attach attempt: ticker.attach(&ledpwmonoff(1),24.0);
Which gives the error: expression must be an lvalue or a function designator (E158)
tried some (()()())))()()'s around ledpwnonoff in the attach, but didn't work.
void ledpwmonoff(int lednr) {
switch(lednr) {
case 1: led1=!led1;
case 2: led2=!led2;
case 3: led3=!led3;
case 4: led4=!led4;
}
}
int main() {
ticker.attach(&ledpwmonoff(int variable),2.0); //variable = the lednr; 1,2,3 or 4
wait(0.5);
ticker.attach(&ledpwmonoff(int variable),2.0); //variable = the lednr; 1,2,3 or 4
wait(0.5);
ticker.attach(&ledpwmonoff(int variable),2.0); //variable = the lednr; 1,2,3 or 4
wait(0.5);
ticker.attach(&ledpwmonoff(int variable),2.0); //variable = the lednr; 1,2,3 or 4
}
which should create a very simple lightshow ;)
The wrapper does solve the error, but not the problem I was having ;)
Regards,
Melchior
What I mean to accomplish is something like
<<code>>
void ledpwmonoff(int lednr) {
switch(lednr) {
case 1: led1=!led1;
case 2: led2=!led2;
case 3: led3=!led3;
case 4: led4=!led4;
}
}
int main() {
ticker.attach(&ledpwmonoff(int variable),2.0); //variable = the lednr; 1,2,3 or 4
wait(0.5);
ticker.attach(&ledpwmonoff(int variable),2.0); //variable = the lednr; 1,2,3 or 4
wait(0.5);
ticker.attach(&ledpwmonoff(int variable),2.0); //variable = the lednr; 1,2,3 or 4
wait(0.5);
ticker.attach(&ledpwmonoff(int variable),2.0); //variable = the lednr; 1,2,3 or 4
}
<</code>>
which should create a very simple lightshow ;)
The wrapper does solve the error, but not the problem I was having ;)
Regards,
Melchior
You could always use templates to do the work for you if you did want to go down this closure-style route:
#include "mbed.h"
DigitalOut led1(LED1);
DigitalOut led2(LED2);
DigitalOut led3(LED3);
DigitalOut led4(LED4);
void ledpwmonoff(int lednr) {
switch(lednr) {
case 1: led1=!led1;
case 2: led2=!led2;
case 3: led3=!led3;
case 4: led4=!led4;
}
}
template<void (*fptr)(int), int value>
void caller() {
fptr(value);
}
Ticker ticker;
int main() {
ticker.attach(caller<&ledpwmonoff,1>, 2.0);
wait(0.5);
ticker.attach(caller<&ledpwmonoff,2>, 2.0);
wait(0.5);
ticker.attach(caller<&ledpwmonoff,3>, 2.0);
wait(0.5);
ticker.attach(caller<&ledpwmonoff,4>, 2.0);
wait(0.5);
}
Simon
You could always use templates to do the work for you if you did want to go down this closure-style route:
<<code>>
#include "mbed.h"
DigitalOut led1(LED1);
DigitalOut led2(LED2);
DigitalOut led3(LED3);
DigitalOut led4(LED4);
void ledpwmonoff(int lednr) {
switch(lednr) {
case 1: led1=!led1;
case 2: led2=!led2;
case 3: led3=!led3;
case 4: led4=!led4;
}
}
template<void (*fptr)(int), int value>
void caller() {
fptr(value);
}
Ticker ticker;
int main() {
ticker.attach(caller<&ledpwmonoff,1>, 2.0);
wait(0.5);
ticker.attach(caller<&ledpwmonoff,2>, 2.0);
wait(0.5);
ticker.attach(caller<&ledpwmonoff,3>, 2.0);
wait(0.5);
ticker.attach(caller<&ledpwmonoff,4>, 2.0);
wait(0.5);
}
<</code>>
Simon
I'm a novice C++ programmer and I've been playing with the examples above, even though I don't fully understand what I'm doing! That said, it looks like the above example should be using 4 different tickers rather than just 1. When I tried it, only LED4 does anything.
I modded the code:
I'm a novice C++ programmer and I've been playing with the examples above, even though I don't fully understand what I'm doing! That said, it looks like the above example should be using 4 different tickers rather than just 1. When I tried it, only LED4 does anything.
I modded the code:
<<code>>
Ticker ticker1;
Ticker ticker2;
Ticker ticker3;
Ticker ticker4;
int main() {
ticker1.attach(caller<&ledpwmonoff,1>, 2.0);
wait(0.5);
ticker2.attach(caller<&ledpwmonoff,2>, 2.0);
wait(0.5);
ticker3.attach(caller<&ledpwmonoff,3>, 2.0);
wait(0.5);
ticker4.attach(caller<&ledpwmonoff,4>, 2.0);
// wait(0.5);
}
<</code>>
now all 4 LEDs dance!
Graeme
I wrote the example just to explain what I wanted to achieve but I see that it would just overwrite the ticker 4 times, leaving only the last one with LED4. Your solution solves that!
And cheers Simon, I will have a go with the template when I'm at home. Graeme's response is cause for optimism ^^
Thanks,
Melchior
Ah right, that makes sense Graeme : )
I wrote the example just to explain what I wanted to achieve but I see that it would just overwrite the ticker 4 times, leaving only the last one with LED4. Your solution solves that!
And cheers Simon, I will have a go with the template when I'm at home. Graeme's response is cause for optimism ^^
Thanks,
Melchior
All mbed tickers use the TIMER3 object, so you can create a critical section in your main code to access a buffer being written to by a Ticker handler:
From the [[http://mbed.org/forum/mbed/topic/1189/?page=1#comment-14619]] post:
<<quote>>
All mbed tickers use the TIMER3 object, so you can create a critical section in your main code to access a buffer being written to by a Ticker handler:
<<code>>
NVIC_DisableIRQ(TIMER3_IRQn);
// critical section
NVIC_EnableIRQ(TIMER3_IRQn);
<</code>>
<</quote>>
i always get the error: "no instance of overloaded function "mbed::Serial::attach" matches the argument list"
if i put the function func() in a separate .h-file not as a memberfunction and then call:
ticker.attach(func,2.0);
everything works fine. Can someone help me with the correct syntax?? Thank You.
Hello guys,
i am new to programming and try to set up a ticker. my code looks like this:
<<code>>
class1.h
#include "mbed.h"
class class1 {
private:
Ticker ticker;
public
class1();
void func();
};
<</code>>
<<code>>
class1.cpp
#include "class1.h"
class1::class1() {
ticker.attach(&class1::func, 2.0);
}
class1::func() {
//Do something
}
<</code>>
i always get the error: "no instance of overloaded function "mbed::Serial::attach" matches the argument list"
if i put the function func() in a separate .h-file not as a memberfunction and then call:
<<code>>
ticker.attach(func,2.0);
<</code>>
everything works fine. Can someone help me with the correct syntax?? Thank You.
The member-function version of attach() also needs an instance pointer. Try:
<<code>>
class1::class1() {
ticker.attach(this, &class1::func, 2.0);
}
<</code>>
Please login to post comments.