Here is the first cut of the timerAlarm library. I will post it here for people to play with and comments while I finish testing and writing up.
The library is the suggested subset of scheduling functionality mentioned in this thread http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1217833080
The library provides for co-operative scheduling of time based tasks with periods from one second to many years. Alarms can be created that repeat at a given interval or that trigger only once. Alarms once created can be enabled, disabled or rescheduled as required.
The number of Alarms concurrent alarms is fixed at library compile time, the default is 6 alarms. The number can be changed by altering a define in the header file, each alarm takes 12 bytes of RAM.
Alarms are created by calling one of the following two methods:
AlarmId1 = dtAlarms.createRepeating( PeriodInSeconds ); // fires periodically
AlarmId2 = dtAlarms.createOneshot( PeriodInSeconds ); // fires once
There are convenience macros to set periods of minutes, hours, days and weeks
The scheduling algorithm is a simple round robin, priority is given to alarms based on the order the create methods are called, first created alarms have the highest priority. Any timers that mature while a callback is executing while wait for the callback to finish.
The library requires the timing mechanism from the DateTime library which is available here:
http://www.arduino.cc/playground/Code/DateTime
I intend to post the finished code for the Alarm library in the playground along with a write-up but welcome a discussion on the functionality here.
example sketch
#include <DateTime.h>
#include <TimerAlarms.h>
AlarmID_t AlarmA, AlarmB, AlarmC, AlarmD;
void onAlarm(AlarmID_t Sender){
// alarm callback function
Serial.print("cume time ");
Serial.print(DateTime.now()); // print elapsed seconds since sketch started runnin
Serial.print(": ");
if( Sender == AlarmA) {
Serial.println("15 seconds Alarm");
}
else if( Sender == AlarmB){
Serial.println("90 second Alarm");
}
else if( Sender == AlarmC){
Serial.print("One Shot alarm, elapsed period was ");
time_t alarmValue = dtAlarms.getValue(Sender);
Serial.println(alarmValue,DEC);
}
else if( Sender == AlarmD){
Serial.print("re-trigged One Shot alarm, elapsed period was ");
time_t alarmValue = dtAlarms.getValue(Sender);
Serial.println(alarmValue,DEC);
dtAlarms.setValue(Sender, alarmValue + 2); //re-enable with a new value two seconds longer
}
}
void setup(){
pinMode(13,OUTPUT);
Serial.begin(19200);
AlarmA = dtAlarms.createRepeating( 15 ); // alarm every 15 seconds
AlarmB = dtAlarms.createRepeating( AlarmHMS(0,1,30) ); // alarm every 1 minute 30 seconds
AlarmC = dtAlarms.createOneshot( 10 ); // one shot alarm in 10 seconds
AlarmD = dtAlarms.createOneshot( 12 ); // one shot alarm that will be manually retriggered
Serial.println("started");
}
void loop(){
dtAlarms.waitUntilThisSecond(0); // this code blocks waiting for start of the next minute, background alarms are still serviced
Serial.println("turning LED on");
digitalWrite(13, HIGH);
dtAlarms.delay(2000); // note we call the alarm delay to service the background alarms
Serial.println("turning LED off");
digitalWrite(13,LOW);
}