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/

READ MORE ==>

  // 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]={
  0,0,0,0,0,0,0,0};

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
  Serial.begin(1200);
}

/* 
 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()
{  
  if(Timer.flagIsSet(7)){ 
    Serial.print("How! High are you? ");
    Serial.println(whichChannel);
  }
}

// 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
  currentChannel++; 
  if(currentChannel >= 5){
    currentChannel=0;
  }
  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;
  Timer.repeat(6,rate);
}