A small timing utility: can be a non blocking replacement for delay(). The need: execute a function on a timed basis, without blocking the processor with delay(). Independant of the time taken by other running processes. Example of use: flash a led at 3 hertz rate while flashing a second led at 11 hertz, a third at 0,75 Hz, etc. The two main functions: startTimer() and checkTimer.
Have fun!
void setup() {
Serial.begin(9600);
}
//--------------------------------------------------
int tickPeriod = 100; //Défines the duration of one tick in milliSeconds. All timers are incremented at this tick rate.
// Also defines timers resolution. The tickPeriod should be longer than the void-loop duration.
unsigned long int tickCounter = 0; //counts millis divided by tickPeriod.
unsigned int mainTimer = 0; //mainTimer increases every tickPeriod. All declared timers rely on mainTimer to maesure time.
unsigned int timer1[4] = {0, 0, 0, 0 }; //declare 2 timers
unsigned int timer2[4] = {0, 0, 0, 0 };
//--------------------------------------------------
void loop() {
//EXAMPLE OF USE:
tickTimers(); //Increase all declared timers by one at each tickPeriod milliSeconds.
flashLed1(5); //flash LED 1, period of 1 sec.
flashLed2(7); //flash LED 2, period of 1.4 sec.
}
//--------------------------------------------------
// Note: only for demonstration purpose: flashLed could be more efficient...
void flashLed1(int period) {
static unsigned int timer1[4] = {0, 0, 0, 0 };
static byte toggle = 0;
startTimer(timer1, period);
if (checkTimer(timer1)) {
if (toggle == 0) {
Serial.println(" LED 1 is ON");
toggle = 1;
}
else {
Serial.println(" LED 1 is OFF");
toggle = 0;
}
}
}
//-----------------------------
void flashLed2(int period) {
static unsigned int timer1[4] = {0, 0, 0, 0 };
static byte toggle = 0;
startTimer(timer2, period);
if (checkTimer(timer1)) {
if (toggle == 0) {
Serial.println(" LED 2 is ON");
toggle = 1;
}
else {
Serial.println(" LED 2 is OFF");
toggle = 0;
}
}
}
//------------------------------------- TIMERS UTILITY -------------------------------------
void tickTimers() { //Must be called at least once in a void ... loop
//Increments tickCounter up to tickPeriod, and then increments mainTimer.
if ((unsigned long)(millis() - tickCounter) >= tickPeriod) {
tickCounter += tickPeriod;
Serial.print("time = "); Serial.println(mainTimer); mainTimer ++;
}
}
//-----------------------------
//A timer is an array of 4 unsigned integers.
// array[0] is the timerPeriod: the timer increments up to this Period before checkTimer returns true.
// A null (0) timerPeriod is iterpreted as an infinite Period: the timer is counting but will never end.
// array[1] is the StartedTime: a copy of mainTimer taken when the timer was initially started with startTimer.
// array[2]is the time when timer was paused: a copy of mainTimer when pauseTimer was called.Used to resumeTimer.
// array[3] is the timer status: 0: the timer is running, !=0: the timer is paused.
// PRINCIPLE: To measure time, one takes note of mainTimer when startTimer is called.
// Elapsed time = actual (running) mainTimer minus the originally noted mainCounter.
const byte timerPeriod = 0;
const byte startedTime = 1;
const byte pausedTime = 2;
const byte timerStatus = 3;
const byte timerRunning = 0;
const byte timerPaused = 1;
//-----------------------------ok
void startTimer (unsigned int aTimer[], unsigned int aTimerPeriod) {
//NOTE: **** startTimer has no effect on an already running timer, allowing to call startTimer in a loop; ****
if (aTimer[timerPeriod] != 0) {
return;
}
else {
aTimer[timerPeriod] = aTimerPeriod; //the timer becomes active:
aTimer[startedTime] = mainTimer; //note the startTime.
}
}
//-----------------------------ok
void runTimer(unsigned int aTimer[]) {
aTimer[timerStatus] = timerRunning; //let the timer run.
}
//-----------------------------ok
void rewindTimer(unsigned int aTimer[]) { //rewinds the timer to zero and let it run.
aTimer[startedTime] = mainTimer;
aTimer[timerStatus] = timerRunning; //let the timer run
}
//-----------------------------ok
void pauseTimer(unsigned int aTimer[]) { // Pause timer
aTimer[pausedTime] = mainTimer; //write a copy of actual time; used by resumeTimer.
aTimer[timerStatus] = timerPaused;
}
//-----------------------------ok
void resumeTimer(unsigned int aTimer[]) { //make a timer run again after beeing paused.
if (aTimer[timerPeriod] == 0) {
return;
}
aTimer[startedTime] = mainTimer - aTimer[pausedTime] + aTimer[startedTime]; //puts the timer where it was when paused.
aTimer[timerStatus] = timerRunning; //remove pause = run timer
}
//-----------------------------ok
bool checkTimer (unsigned int aTimer[]) { //Checks if the timer arrived at its end.
if (aTimer[timerPeriod] == 0 || aTimer[timerStatus] != timerRunning) { //If timer is not active or paused.
return false;
}
if (mainTimer - aTimer[startedTime] >= aTimer[timerPeriod]) { // if time elapsed...
aTimer[startedTime] += aTimer[timerPeriod]; //advance the start time.Optionnally: aTimer[startedTime] = mainTimer;Texte préformaté
return true; //return true if time elapsed.
}
else {
return false;
}
}
//-----------------------------
void setTimerPeriod (unsigned int aTimer[], unsigned int aTimerPeriod) {
aTimer[timerPeriod] = aTimerPeriod; //set new period
aTimer[startedTime] = mainTimer; //rewind timer
}
//------------------------------------- END OF TIMERS UTILITY -------------------------------------Texte préformaté