Happy Pins 7 -- video demo and Arduino code example

Submitted by Ed_B on Thu, 07/22/2010 - 23:10

Printer-friendly versionPrinter-friendly version

I'm discovering that there was an unknown-unknown challenge in writing the timer-scheduler demo examples. It really shouldn't have been a surprise at all, but giving aesthetic structure to time with C code is an odd thing to do. It must be a little like composing music in code. That's something to ask around about. The previous posting had a demo video, but the code behind it was awful. I didn't understand what the mindset should be to use the timer-scheduler library. The right way to think about it in the context of rhythmic composition is pretty much limited to timer events controlling other timer events and generating outputs. Here's a video, and the Arduino sketch is below. Code is at http://code.google.com/p/timer-scheduler/


  // HappyFlags_7.pde Ed Bennett 7-19-10
// 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_(time)#Use_in_computing

#include <TimerScheduler.h>

// hardware pins
int HF0 = 13;
int HF1 = 12;
int HF2 = 11;
int HF3 = 10;
int HF4 = 9;
int HF5 = 8;
int HF6 = 7;
int HF7 = 6;

int rate = 7;
int whichChannel = 0;
int randomize = 0;

int outval[8]={

int currentChannel;

void setup()

  pinMode(HF0, OUTPUT); 
  pinMode(HF1, OUTPUT); 
  pinMode(HF2, OUTPUT);
  pinMode(HF3, OUTPUT); 
  pinMode(HF4, OUTPUT);
  pinMode(HF5, OUTPUT); 
  pinMode(HF6, OUTPUT);
  pinMode(HF7, OUTPUT); 

  Timer.attachPin(0, HF0);    // (channel, Ard. pin number)
  Timer.attachPin(1, HF1); 
  Timer.attachPin(2, HF2); 
  Timer.attachPin(3, HF3); 
  Timer.attachPin(4, HF4);

  // Register user's callback function names with their timer channels.
  Timer.onTick(5, setLowTime);   // (channelNumber, functionName)
  Timer.repeat(5, 1000);         // (channel, time)
  Timer.onTick(6, updatePinTimers); 
  Timer.repeat(6, 100); 
  Timer.onTick(7, randomMode);
  Timer.repeat(7, 3000);

  // Allow timers to be serviced in the timer interrupt
  Timer.start(0);    // happy flag 0
  Timer.start(1);    // happy flag 1
  Timer.start(2);    // happy flag 2
  Timer.start(3);    // happy flag 3
  Timer.start(4);    // happy flag 4
  Timer.start(5);    // ramps value of timer 6
  Timer.start(6);    // loads pin timer values -- master rate control
  Timer.start(7);    // randomizer-controller & print timer

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

 Timer 7 is being used with a callback, AND with its user flag. 
 The callback is fast, and the user-flag code in loop() uses
 Serial.print() which is slow. It's the best of both worlds running
 on Timer 7. The two pieces of code execute indepenant of each other.

void loop()
    Serial.print("How! High are you? ");

// callback on timer 7
void randomMode(void){
  randomize ^=1; // toggle between sequential and random blink patterns
  digitalWrite(HF7, randomize); // random/sequential indicator lamp

// callback on timer 6
// updates one pin per call
void updatePinTimers(void){
  // HIGH TIME ramp factor- each new cycle is 90% of the previous
  // until the value is below 5
  outval[currentChannel]= outval[currentChannel] * 90/100;
  if(outval[currentChannel]< 5){
    outval[currentChannel]= 1000;

  // in a sequential blink pattern, currentChannel is the one 
  // we're doing now
  if(currentChannel >= 5){
  whichChannel = currentChannel; // which channel to write

  // if randomize == 1, overwrite whichChannel with a random value 0-4
  if(randomize == 1){ 
    whichChannel = random(0,5);

  // write the control value to fire the pin
  Timer.mono(whichChannel, outval[currentChannel]); 

// callback on timer 5
// This function ramps the repeat rate of Timer 6.
// (An example of one timer controlling another timer.)
// In this program, all timers have variable high times 
// but share the same value of low time. Timer 6 sets the 
// low time. Timer 5 modifies Timer 6 to ramp the blink 
// sequencing rate.
void setLowTime(void){  
  if(rate >300)rate=7;
  rate = rate * 100/85;