One option would be to use the EventFuse library I recently posted to the Playground, or one of the similar task scheduling libraries that can also be found there. Or to use the idea of a countdown 'fuse' to schedule events in the way that EventFuse illustrates.
Here is an example that uses the MsTimer2 library to generate an interrupt every mS, similar to your master timer, though I'm not keeping track of the number of counts (since millis() also updates every mS and keeps a count, that would be redundant).
The tick() routine is called by the interrupt handler. It calls burn(1) which subtracts 1 from the length of each defined 'fuse'. This is essentially a simple countdown timer that executes a callback when it is finished.
After adjusting the port output the callback reloads the fuse with a new fuse length pulled from the 'delays' array. It could also simply do nothing and the fuse would automatically reset to the original value.
/*
*
* Description:
* Fade an LED by combining the output of two
* fuses with similar intervals. The combined
* output exhibits a beat pattern that varies
* the output pulse width.
*
* Use the interrupt based MsTimer2 library as
* a source for a 1mS event for the burn function.
*
*/
#include <EventFuse.h>
#include <MsTimer2.h>
int ledPin = 13; // LED output pin
boolean output = LOW;
// Delay values control both on and off time and could be
// any sequence, not just the simple linear progression here.
int delays[20] = {100,100,150,150,200,200,250,250,300,300,
350,350,400,400,450,450,500,500,550,550};
int delayIdx = 0;
int getNextDelay()
{
if(delayIdx > 19)
delayIdx=0;
return delays[delayIdx++];
}
// Fuse event, toggles the ledPin output
void ToggleOutput(eventFuse_h fuse){
output = !output;
digitalWrite( ledPin, output );
// The fuse settings can be updated at any time.
// Here we'll adjust the length so that it doesn't
// reset to the 500mS specified when the fuse was set up.
Fuses.fuses[fuse].fuseLen = getNextDelay();
}
void tick(){
Fuses.burn(1);
}
void setup() {
pinMode(ledPin, OUTPUT);
// Schedule the ToggleOutput() function to
// execute after 500 calls to Fuses.burn(1).
Fuses.setFuse( 500, INF_REPEAT, ToggleOutput );
// Set up the tick() function to be called
// every millisecond.
MsTimer2::set( 1, tick );
MsTimer2::start();
}
void loop(){
}