Recent changes
Order
tag order
RTOS
Help
mbed NXP LPC1768
Firmware
Homepage
From the mbed microcontroller Handbook.  

Ticker

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.

Hello World!

A simple program to setup a Ticker to invert an LED repeatedly...

Example attaching a static function to a ticker

#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 flip
    while(1) {
        led1 = !led1;
        wait(0.2);
    }
}

API

API summary

TickerA Ticker is used to call a function at a recurring interval
Functions
attachAttach a function to be called by the Ticker, specifiying the interval in seconds
attachAttach a member function to be called by the Ticker, specifiying the interval in seconds
attach_usAttach a function to be called by the Ticker, specifiying the interval in micro-seconds
attach_usAttach a member function to be called by the Ticker, specifiying the interval in micro-seconds
detachDetach the function
class Ticker : public TimerEvent
A Ticker is used to call a function at a recurring interval
void attach(void (*fptr)(void),
float t)
Attach a function to be called by the Ticker, specifiying the interval in seconds
void attach_us(void (*fptr)(void),
unsigned int t)
Attach a function to be called by the Ticker, specifiying the interval in micro-seconds
void detach()
Detach the function

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.

Examples

Example attaching a member function to a ticker

#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 flip
    while(1) {
        led1 = !led1;
        wait(0.2);
    }
}



calendar Page history
Last modified 04 Mar 2012, by   user Simon Ford   tag No tags | 27 comments  

27 comments on Ticker:

06 Dec 2010

Has anyone used Ticker() to develop a thread scheduler or some other type of preemptive multiprocessor OS?

07 Dec 2010

the function says attach_us where the description says micro-seconds

07 Dec 2010

Hi Stephan,

Yes, that is correct. In general:

  • milli-seconds is shortened to ms
  • micro-seconds is shortened to us

Simon

19 Dec 2010

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?

28 Dec 2010

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)

28 Dec 2010

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

11 Jan 2011

how small can I make the wait time?

11 Jan 2011

user shang wang wrote:

how small can I make the wait time?

AFAIK one microsecond (when you use the attach_us methods). But then your callbacks would need to be really fast...

29 Jan 2011

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 ;)

20 Mar 2011

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???

09 Apr 2011

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.

09 Apr 2011

Make a small wrapper and attach that.

Code

void ledon()
{
  ledpwmonoff(1);
}
[...]
ticker.attach(ledon, 24.0);
15 Apr 2011

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
}

which should create a very simple lightshow ;) The wrapper does solve the error, but not the problem I was having ;)

Regards,

Melchior

15 Apr 2011

Simple solution is probably to make 4 seperate functions :)

15 Apr 2011

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);
}

Simon

20 Apr 2011

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);
}

now all 4 LEDs dance!

Graeme

21 Apr 2011

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

17 Nov 2011

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);

21 Nov 2011

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

class1.cpp
#include "class1.h"

class1::class1() {
  ticker.attach(&class1::func, 2.0);
}

class1::func() {
  //Do something
}

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);

everything works fine. Can someone help me with the correct syntax?? Thank You.

21 Nov 2011

The member-function version of attach() also needs an instance pointer. Try:

Code

class1::class1() {
  ticker.attach(this, &class1::func, 2.0);
}
21 Nov 2011

user Igor Skochinsky wrote:

The member-function version of attach() also needs an instance pointer. Try:

Code

class1::class1() {
  ticker.attach(this, &class1::func, 2.0);
}

thank you, you saved my day!

27 Nov 2011

Warning!

The mbed compiler will aggressively optimise use of global variables, which may result in changes to a variable in a Ticker attach function not being seen by the base level code. Compiler optimisation is variable, and can be prevented by API calls etc, so this is a difficult bug to diagnose.

Such variables must be declared volatile.

Here is an example which will (likely but not certainly) fail without the use of volatile.

Code

volatile int running = 1;

Ticker tick;

void isr(void)
{
  running = 0;
}

int main(void)
{
   tick.attach(&isr, 10.0); // set up interrupt every 10s
   while (1) {
     printf("Starting test...\n");
     running = 1;
     while (running); // inner while loop is broken by interrupt
     printf("OK.\n");
   }
   return 0;
}



04 Mar 2012

user John Anon wrote:

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 ;)

I've had a similar problem (1 sec, 1 min and 1 hr). It took over an hour (I didn't sit with a stopwatch, but went away and came back again) before they all appeared to be running properly. But they all seemed to work if I did 1sec, 1sec and 1min respectively (whilst testing). In the end I scrapped the 1hr ticker and combined it with the 1min but only executing the appropriate code every 60 mins.

04 Mar 2012

Hi Mark,

Just added the note to this page about length of time - it was on Timeout but not Ticker.

Summary is 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, or the ticker firing at more regular intervals manipulating a counter etc.

Hope that helps!

Simon

12 Apr 2012

If I attach a function name and time to a ticker object. To change the time, do I just attach again with the same function but different time, or do I need to detach first and then attach.

Thank you.

4 weeks, 1 day ago

Hello,

Is there any way to programmatically specify the ticker delay argument? Every way I try gives me "no instance of this overloaded function allows this" error. Without this, it seems impossible to have the mbed react automatically to a given set of scenarios using either this or the timeout function.

Thank you, Attila

4 weeks, 1 day ago

It's my understanding that Ticker is more for sampling at a constant rate. If you wanted something to respond to external stimulus, you could use a counter and a mod function inside of a Ticker to make the code snippet execute at more dynamic time intervals.

Please login to post comments.