I would suggest a slightly different view of the sample code. The term Alarm would be replaced by Task. Rather than one loop with testing there would be separate loops.
The setup should allow for delta time, absolute time as well as one time and repeating schedules.
I would default the maximum number of tasks at 6 and wait for user feedback.
#include <DateTime.h>
#include <DateTimeStrings.h>
#include <TaskScheduler.h>
void onTask1(){
Serial.println("15 seconds Alarm");
}
void onTask2(){
Serial.println("90 second Alarm");
}
void onTask3(){
Serial.print("One Shot alarm, elapsed period was ");
time_t alarmValue = dtAlarms.getValue(Sender);
Serial.println(alarmValue,DEC);
}
void onTask4(){
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);
Task1 = dtAlarms.createRepeating( 15 ); // alarm every 15 seconds
Task2 = dtAlarms.createRepeating( AlarmHMS(0,1,30) ); // alarm every 1 minute 30 seconds
Task3 = dtAlarms.createOneshot( 10 ); // one shot alarm in 10 seconds
Task4 = 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);
}
Well, I know that you seemed to think that inclusion in the core was not an important question, but a non user-definable method to allocate space for these Alarms/event seems unreasonable if this library is ever going to be a part of the core. Mem has done a good job of keeping resource usage (RAM) very low for users of his suggested library, but it still uses 60 bytes! That seems unacceptable to me for core inclusion considering that some people may never even want to use these Alarms. Choosing a lower default number of Alarms does not seem like a good core solution either, and neither does making things compile time options. So, if this is ever going to be considered for core inclusion I would suggest a different approach for allocation memory. However since Mem did do a good job of minimizing RAM usage, any core implementation would probably take up more RAM and therefor as a standalone library his solution may be better.
If libraries are never going to be core solutions, compile time options may well be good solutions, especially if the library does something very specialized that could greatly benefit from compile time options to either save RAM or to increase speed. For example: I am working on an LED TDM library and have come to the conclusion that speed is paramount. Although I would like to create a library that could be easily used without recompiling, I have determined that this would potentially mean a significant (3x) speed decrease. Since this might very well push the library utility out of the problem space that it is trying to address in the first place, this does not seem worth it. I will probably leave certain things compile time options for this TDM library.
While I certainly agree that the programing interface is important to keep simple, the target user audience is also somewhat dependent on whether a library is meant for core inclusion or not. Obviously we want to keep interfaces simple, but often times a sacrifice in simplicity is warranted for better performance or flexibility. Sometimes the only way to make good decisions about which of these tradeoffs to make is by deciding who the likely target audience is.
Allowing the user to create his own callbacks is easy and probably not much more complicated for a newbie to use (it would look similar to the way attachInterrupt works). Only uses two more bytes per instance so nothing to worry about there.
Creating instances of alarms (or whatever they will be called) at runtime to minimize RAM usage to the minimum needed has also been implemented, I started out with a version of the library that allows the user to create instances of the timers he needs so memory is only consumed when needed, but it seemed a less friendly to newbies then the simpler version posted earlier.
Here is a fragment from one of my test sketches that creates three instances
AlarmClass Timer1;
AlarmClass Timer2;
AlarmClass Timer3;
void setup(){
// you can register time of day Alarms at any time but really shouldn't enable them until the internal clock is set
if( dtAlarms.registerTimer( &Timer1 ) ) {
Timer1.value = DateTime.now() + 11; // fire at the time of day 11 seconds from now
Timer1.Mode.isTimeOfDay = true; // the value given above is a time of day
Timer1.onTickHandler = &OnTimer1Tick;
Timer1.enable();
}
if( dtAlarms.registerTimer( &Timer2 ) ) {
Timer2.value = AlarmHMS(12,30,0) // this is 30 minutes after 12 noon
Timer2.onTickHandler = &OnTimer2Tick;
Timer2.Mode.isTimeOfDay = true;
Timer2.enable();
}
if( dtAlarms.registerTimer( &Timer3 ) ) {
Timer3.Mode.isTimeOfDay = false; // the timer value is treated as a delay in seconds, not absolute time
Timer3.value = 13; // delay in seconds from the time this alarm is enabled
Timer3.onTickHandler = &OnTimer1Tick;
Timer3.enable();
}
}
void OnTimer1Tick(void *Sender){
if( Sender == &Timer1)
Serial.print("Timer1 event: ");
else if( Sender == &Timer3)
Serial.print("Timer3 event: ");
timeDisplay();
}
void OnTimer2Tick(void *Sender){
Serial.print("Timer2 event: ");
}
mem,
can you tell me what to modify to get your dateTimeAlarm library to run with 0012? I am seeing the
same kind of library compile errors others have seen with moving to 0012
can you tell me what to modify to get your dateTimeAlarm library to run with 0012? I am seeing the
same kind of library compile errors others have seen with moving to 0012
In the DateTimeAlarm.h file comment out the following line:
//#include <wiring.h> // this line must be commented out or removed for 0012
mem,
Did you mean TimerAlarms.h ? I tried commenting out the include in TimerAlarms.h but it did not work. Same kind of errors at compile time. Any other ideas? I am using the Mac version.
I've been madly searching these forums since receiving my Diecimila a few weeks ago, trying to cobble together some alarm code that I can use to trigger a camera at a given time each day. I was very pleased to find this thread, but I can't seem to work out why I get compile errors when using mem's example code from reply #2 or reply #16. For reply #2, I get:
[EDIT] Never mind, I fixed this first problem..
For reply #16, I get:
In function 'void setup()':
error: 'class dtAlarmsClass' has no member named 'registerTimer' In function 'void loop()':
relating to:
Wire.begin();
// you can register time of day Alarms at any time but really shouldn't enable them until the internal clock is set
if( dtAlarms.registerTimer( &TimeForPhoto ) ) {
TimeForPhoto.value = AlarmHMS(12,30,0) // this is 30 minutes after 12 noon
TimeForPhoto.onTickHandler = &OnTimeForPhotoTick;
TimeForPhoto.Mode.isTimeOfDay = true;
TimeForPhoto.enable(); // the above registers an alarm, labelled 'TimeForPhoto', as one that triggers at the given time
of day.
}
I'm able to follow the coding to a certain extent, but this is well above anything I've tried before... I've ordered a Mini-DS1307 board to supply the time, so until that comes I thought I'd work on the alarm code.
Any help would be greatly appreciated - and by the way, congrats on such a friendly, supportive forum!
Hi again...
Fixing my first problem has left me with another; here's the code:
#include <DateTime.h>
#include <DateTimeAlarms.h>
AlarmID_t Alarm9,Alarm12,Timer11; // id to identify what triggered alarm if callbacks are shared
void setup(){
Serial.begin(19200);
Alarm9 = dtAlarms.createAlarm( DateTime.now() + 9, OnAlarm); // trigger 9 seconds from now
Alarm12 = dtAlarms.createAlarm(AlarmHMS(12,0,0), OnAlarm); // trigger at mid day
Timer11 = dtAlarms.createTimer( 11, OnTimer); // trigger in 11 seconds
}
void OnAlarm(AlarmID_t Sender){
// callback for time of day alarms
if( Sender == Alarm9) {
Serial.print("Alarm9: ");
dtAlarms.setValue(Alarm9, DateTime.now() + 9 ); // reset alarm to trigger at the time that is 9 seconds from now
}
else if( Sender == Alarm12)
{
Serial.print("Alarm12: ");
dtAlarms.setValue(Alarm12, AlarmHMS(12,0,0)); // reset alarm to trigger at noon
}
}
void OnTimer(AlarmID_t Sender){
// callback for time delay alarm
Serial.print("Timer11: 11 sec timer: ");
dtAlarms.setValue(Timer11, 11 ); // delay another 11 seconds
}
void loop(){
dtAlarms.waitUntilThisSecond(0); // this code blocks waiting for start of the next minute, background alarms are still serviced
digitalWrite(13, HIGH);
dtAlarms.delay(2000); // note we call the alarm delay to service the background alarms
digitalWrite(13,LOW);
dtAlarms.delay(2000); // delay is in milliseconds , all other alarm values are seconds
}
...which gives me the following error:
o: In function loop': undefined reference to dtAlarms'o: In function OnTimer(unsigned char)': o: In function OnAlarm(unsigned char)':
o: In function `setup':
I was pretty sure that I'd replaced the DateTimeAlarms.h file, but I decided to do a clean install of v0012 in a seperate location anyway. I have a DateTimeAlarms library, but it's only got the DateTimeAlarms.h file; I don't seem to have the DateTimeAlarms.cpp or DateTimeAlarms.o file anywhere, and can't locate it on the forums or main site.
I'm guessing that if someone can point me to that file, my problems may just disappear...
OK, so now we get to the bit that's confused me every time I've read this thread: hotcarrier wrote -
mem,
Did you mean TimerAlarms.h ?
... to which you replied -
Yes, DateTimeAlarms.h
:-? Sorry if I've missed something here, but the thread you directed me to has 'TimerAlarms' files in it, not 'DateTimeAlarms'. I tried renaming them, and replacing any 'TimerAlarm' references with 'DateTimeAlarms' references but that didn't work. Also tried it in 0011 with similar results. I AM getting a different error now though:
In file included from C:\arduino-0012\hardware\cores\arduino/WProgram.h:4,
c:/arduino-0012/hardware/tools/avr/lib/gcc/../../avr/include/stdlib.h:80: error: expected unqualified-id before 'int'
c:/arduino-0012/hardware/tools/avr/lib/gcc/../../avr/include/stdlib.h:80: error: expected `)' before 'int'
c:/arduino-0012/hardware/tools/avr/lib/gcc/../../avr/include/stdlib.h:80: error: expected `)' before 'int'
c:/arduino-0012/hardware/tools/avr/lib/gcc/../../avr/include/stdlib.h:111: error: expected unqualified-id before 'int'
c:/arduino-0012/hardware/tools/avr/lib/gcc/../../avr/include/stdlib.h:111: error: expected `)' before 'int'
c:/arduino-0012/hardware/tools/avr/lib/gcc/../../avr/include/stdlib.h:111: error: expected `)' before 'int'
c:/arduino-0012/hardware/tools/avr/lib/gcc/../../avr/include/stdlib.h:144: error: expected identifier before '(' token
c:/arduino-0012/hardware/tools/avr/lib/gcc/../../avr/include/stdlib.h:144: error: expected `)' before '(' token
c:/arduino-0012/hardware/tools/avr/lib/gcc/../../avr/include/stdlib.h:144: error: expected ',' or '...' before '(' token
c:/arduino-0012/hardware/tools/avr/lib/gcc/../../avr/include/stdlib.h:144: error: expected initializer before ')' token
c:/arduino-0012/hardware/tools/avr/lib/gcc/../../avr/include/stdlib.h:176: error: '__compar_fn_t' has not been declared
In file included from C:\arduino-0012\hardware\cores\arduino/WProgram.h:6,
In function 'void setup()':
Sorry, just picked up on your comment about MOVING #include <wiring.h> from one file to the other... much better, but still have this last little error:
In function 'void setup()':
error: 'class dtAlarmsClass' has no member named 'createAlarm'
Which is a lot nicer than what I had before...
Again, sorry for not reading your post correctly!! [smiley=embarassed.gif]
JB, the sketch you posted compiles on my PC without any errors in 0012 with the <wiring.h> moved from the .h file to the .cpp file.
Have you tried to use the .h and .cpp file I posted today in the other thread?
If you are still stuck, send me a Personal Message with your email address and I will email you the files you need to put in the DateTimeAlrams directory.
As we'd say in Australia - you beauty, all sorted!
I've read so many threads where you've helped others, on matters MUCH more complicated than mine. It's a rare thing for someone to be able to provide assistance so happily and helpfully to beginners and 'experts' alike; your parents would be proud!
Thanks for your help, and I'm sure I'll have more questions as my project matures. FYI, the project goes something like this:
A remote automated camera system to take photos of key wetlands once or twice a day
Using a Canon Powershot A720 consumer camera, with modified firmware (see CHDK Wiki | Fandom for more info - I'm sure there are people here who would be interested in what the CHDK community has achieved)
Thermistor to monitor enclosure temperature, and operate fans when required
Arduino to control fans, camera power & solenoid to turn camera on at specific times
Believe it or not, this is all part of a WORK project, so I get to spend my time playing with Arduino & all sorts of other fun bits & pieces; I'm LIVING the tinkering philosophy!
Thanks again for your help, that sketch has compiled happily under 0012. Tomorrow I'll start working on how to integrate this with the rest of the code I've pulled together - hopefully my DS1307 board isn't far away!
Hi JB, happy to help, and its a particular pleasure when I hear about interesting projects like yours. I am intrigued about the ways people use stuff that I have posted, I would be interested in hearing how you have implemented the alarms in your application,
When you get a chance, why not post some more information in the exhibition area.
I'm having some trouble compiling the following code (from reply #16) and hoped that someone could help me out...
#include <DateTime.h>
#include <DateTimeAlarms.h>
AlarmClass Timer1;
AlarmClass Timer2;
AlarmClass Timer3;
void setup(){
// you can register time of day Alarms at any time but really shouldn't enable them until the internal clock is set
if( dtAlarms.registerTimer( &Timer1 ) ) {
Timer1.value = DateTime.now() + 11; // fire at the time of day 11 seconds from now
Timer1.Mode.isTimeOfDay = true; // the value given above is a time of day
Timer1.onTickHandler = &OnTimer1Tick;
Timer1.enable();
}
if( dtAlarms.registerTimer( &Timer2 ) ) {
Timer2.value = AlarmHMS(12,30,0) // this is 30 minutes after 12 noon
Timer2.onTickHandler = &OnTimer2Tick;
Timer2.Mode.isTimeOfDay = true;
Timer2.enable();
}
if( dtAlarms.registerTimer( &Timer3 ) ) {
Timer3.Mode.isTimeOfDay = false; // the timer value is treated as a delay in seconds, not absolute time
Timer3.value = 13; // delay in seconds from the time this alarm is enabled
Timer3.onTickHandler = &OnTimer1Tick;
Timer3.enable();
}
}
void OnTimer1Tick(void *Sender){
if( Sender == &Timer1)
Serial.print("Timer1 event: ");
else if( Sender == &Timer3)
Serial.print("Timer3 event: ");
timeDisplay();
}
void OnTimer2Tick(void *Sender){
Serial.print("Timer2 event: ");
}
On trying to compile this code I get the following error:
In function 'void setup()':
error: 'class dtAlarmsClass' has no member named 'registerTimer' In function 'void OnTimer1Tick(void*)':
I'm using 0012, and have the latest DateTimeAlarm cpp and h files. I've got my DS1307 mini-board attached & sending me the time (in a seperate sketch), but now I need to create alarms to fire at specific times every day.