Timer-Scheduler Library Examples Using Three Different Methods

Submitted by Ed_B on Wed, 06/30/2010 - 12:47

Printer-friendly versionPrinter-friendly version

I've been working on a  timer/scheduler library for fairly accurate, low speed timing of function calls on the Arduino. Using timers to schedule simple function calls, you can have multiple repeating events happening at the same time. As you know, this is very hard to do using delay().  The timer-scheduler library can give the appearance of multiple channels of independent activity. It looks kind of like multitasking. Maybe it is. Maybe it isn't. 

The timer-scheduler library provides eight (8) software timers. There are three methods for using a timer to make something happen. The first method is polling a flag. A flag is read from or written to by hardware and your code. A flag has two states: set (high) or clear (low). Flags tell you when something has changed in hardware. The second method uses callbacks. These are small functions you write. They fire off when a timer event happens.  The third method, pin-direct, attaches a software timer directly to a pin. The pin will go high and low based on the timer settings.  The videos are of the actual code samples running. The video for the flag-polling method and the callback methods is the same footage(!?) for both methods, because they look the same when they're running. The video for the pin-direct sketch has asymmetrical blink patterns because it was more fun to write it that way.

  READ MORE =====>

 Video for the flag-polling method and the callback method:


The timer-scheduler library for Arduino has a home at google code. The library and the examples are in the trunk, which can be downloaded from the source page. The contents of the timer-scheduler folder (the trunk) should be copied into an Arduino library folder called TimerScheduler. The code has only been tested on an ATMega168 chip. The examples below are bare-bones just to show how to set up the timers. All three sketches have the same purpose: make multiple blinkies happen together in a simple piece of code. More complex examples will come soon.

Video for the pin-direct method:


 

// TimerWithFlag_1.pde Ed Bennett 6-28-10 // // Using flags in loop() --first example with fixed speeds
//
// Three LED's blinking together at different rates.
// Three timer channels are used. The channels are 
// numbered 0, 1, and 2. 
//
// Timer commands usually take a channel number and/or a 
// time-value. 
//
// The unit of time is is called a blink. The duration 
// of a blink is related to an AVR jiffy. See
// http://en.wikipedia.org/wiki/Jiffy_%28time%29

#include <TimerScheduler.h>

// hardware pins
int LED0 = 11;
int LED1 = 10;
int LED2 = 9;

int outval0 = 0;
int outval1 = 0;
int outval2 = 0;


void setup()
{   
  pinMode(LED0, OUTPUT); 
  pinMode(LED1, OUTPUT); 
  pinMode(LED2, OUTPUT);

  Timer.begin();        // start the hardware timer

  Timer.repeat(0,1501); // (channel, time)
  Timer.repeat(1,700); 
  Timer.repeat(2,22);

  Timer.start(0);       // (channel)
  Timer.start(1); 
  Timer.start(2); 
}

  // this is how to poll a timer flag
void loop()
{
  // for LED0
  if(Timer.flagIsSet(0)){  // channel 0 flag
    outval0 ^= 1;          // toggle the pin
    digitalWrite(LED0, outval0);
  }

  // for LED1   
  if(Timer.flagIsSet(1)){  // channel 1 flag
    outval1 ^= 1;
    digitalWrite(LED1, outval1);
  }

  //for LED2  
  if(Timer.flagIsSet(2)){  // channel 2 flag
    outval2 ^= 1;
    digitalWrite(LED2, outval2);
  }

//TimerCallback_1.pde Ed Bennett 6-28-10  
//
// using user-written functions outside of loop() --first example with fixed speeds
//
// Three LED's blinking together at different rates.
// Three timer channels are used. The channels are 
// numbered 0, 1, and 2. 
//
// Timer commands usually take a channel number and/or a 
// time-value. 
//
// The unit of time is is called a blink. The duration 
// of a blink is related to an AVR jiffy. See
// http://en.wikipedia.org/wiki/Jiffy_%28time%29
//
// This example uses a callback functions that you write. Your
// function is registered with a timer. When the timer fires off,
// it runs your function.
//
// Your callback functions should be very short and very fast. Don't
// use delay() or anything else that eats a lot of time. Serial.print()
// is very slow, for example. While your callback is running, the chip is 
// stuck on a very low level that affects other things. It's a good
// idea to add a blinking LED to your program just so that you can see
// whether it locks up due to a callback that runs too slowly.

#include <TimerScheduler.h>

// hardware pins
int LED0 = 11;
int LED1 = 10;
int LED2 = 9;

int outval0 = 0;
int outval1 = 0;
int outval2 = 0;


void setup()
{   
  pinMode(LED0, OUTPUT); 
  pinMode(LED1, OUTPUT); 
  pinMode(LED2, OUTPUT);

  Timer.begin();        // start the hardware timer
  
  // Register user's callback function name with a timer channel.
  // blinkLED0 is a function I wrote further down this page.
 
  Timer.onTick(0, blinkLED0); //(channelNumber, functionName)
  Timer.onTick(1, blinkLED1); 
  Timer.onTick(2, blinkLED2);

  // time interval
  Timer.repeat(0,1501); // (channel, time)
  Timer.repeat(1,700); 
  Timer.repeat(2,22);
  
  Timer.start(0);       // (channel)
  Timer.start(1); 
  Timer.start(2); 
}


// You can put things in loop(), if you like,
// but it's not required for the callbacks.

void loop()
{
}

// here are the user's callbacks

void blinkLED0(void){
    outval0 ^= 1;          // toggle the pin
    digitalWrite(LED0, outval0);
}

void blinkLED1(void){
    outval1 ^= 1;
    digitalWrite(LED1, outval1);
}

void blinkLED2(void){
    outval2 ^= 1;
    digitalWrite(LED2, outval2);
}


// TimerPinDirect_1.pde  Ed Bennett 6-28-10
// timers act directly on pins --first example with fixed speeds
//
// Three LED's blinking together at different rates.
// Three timer channels are used. The channels are 
// numbered 0, 1, and 2. 
//
// Timer commands usually take a channel number and/or a 
// time-value. 
//
// The unit of time is is called a blink. The duration 
// of a blink is related to an AVR jiffy. See
// http://en.wikipedia.org/wiki/Jiffy_%28time%29
//
// This example uses direct control of the pins from the timer channels.
// This method uses less processor power than callbacks or flag polling.
// (see the other examples)


#include <TimerScheduler.h>

// hardware pins
int LED0 = 11;
int LED1 = 10;
int LED2 = 9;

int outval0 = 0;
int outval1 = 0;
int outval2 = 0;


void setup()
{   
  pinMode(LED0, OUTPUT); 
  pinMode(LED1, OUTPUT); 
  pinMode(LED2, OUTPUT);

  Timer.begin();        // start the hardware timer
  
  // attach LED pins to timer channels
  Timer.attachPin(0, LED0); // (channel, value)
  Timer.attachPin(1, LED1);
  Timer.attachPin(2, LED2); 

  // using pin-direct mode, you need to set the pin-high
  // and pin-low times seperately
  Timer.setHighTime(0, 500); // (channel, value)
  Timer.setLowTime(0, 200); 
  
  Timer.setHighTime(1,50);
  Timer.setLowTime(1, 700);
  
  Timer.setHighTime(2, 20);
  Timer.setLowTime(2, 100);
  
  Timer.start(0);       // (channel)
  Timer.start(1); 
  Timer.start(2); 
}


// You can put things in loop(), if you like,
// but it's not required.

void loop()
{
}