TimeAlarms scheduler

Just a quick update on this–I have this working but only when the Spark cloud time zone is set to 0 (i.e. GMT). I am going to add a method to the alarms library to set the time zone and get it out soon.

I still think Spark needs an internet controlled version of this and I am working on that in parallel.

Hey Everybody in the TimeAlarms thread!

I put the ported library on github and added it to the webIDE Library feature! Everyone should now have access to it. I included the example program as well.

The ported TimeAlarms library works with the new built-in real-time clock on the Spark core, Time.now().


@bko, this is a really important library to have so NICE JOB! :ok_hand:


Brilliant, thanks bko! Using it now, works perfectly so far

1 Like

@bko would this library still require an occasional time sync as suggested in the docs? http://docs.spark.io/firmware/#time-spark-synctime

Hi @scottsweb,

Yes, I recommend calling Spark.syncTime() at least once a day. Otherwise the local clock drifts up to about +/- 10 seconds per day on my core. I don’t think calling it more that once an hour is beneficial. If you need more exact time, you can check out my older NTP-based Spark Time library, but it consumes more resources and doesn’t current work with TimeAlarms (but that would be easy to fix).

It would probably be bad for the Spark cloud if we all called syncTime() at the same time at midnight GMT or something, so you probably want to call it based on relative time from when the core powered up.

1 Like

@bko Excellent. Thanks for the clarification and for your work on the library. I can see myself making use of this in many projects.

Greetings All!

Receiving compile errors with TimeAlarms:

In file included from ../inc/spark_wiring.h:30:0, from ../inc/application.h:31, from /SparkTime.h:4, from /SparkTime.cpp:31: ../../core-common-lib/SPARK_Firmware_Driver/inc/config.h:12:2: warning: #warning "Defaulting to Release Build" [-Wcpp] In file included from ../inc/spark_wiring.h:30:0, from ../inc/application.h:31, from /TimeAlarms.h:6, from /TimeAlarms.cpp:27: ../../core-common-lib/SPARK_Firmware_Driver/inc/config.h:12:2: warning: #warning "Defaulting to Release Build" [-Wcpp] /TimeAlarms.cpp: In member function 'void AlarmClass::updateNextTrigger()': /TimeAlarms.cpp:62:48: warning: comparison between signed and unsigned integer expressions [-Wsign-compare] /TimeAlarms.cpp:73:48: warning: comparison between signed and unsigned integer expressions [-Wsign-compare] /TimeAlarms.cpp: In member function 'AlarmID_t TimeAlarmsClass::alarmOnce(long int, OnTick_t)': /TimeAlarms.cpp:120:19: warning: comparison between signed and unsigned integer expressions [-Wsign-compare] /TimeAlarms.cpp: In member function 'AlarmID_t TimeAlarmsClass::alarmRepeat(long int, OnTick_t)': /TimeAlarms.cpp:136:18: warning: comparison between signed and unsigned integer expressions [-Wsign-compare] /TimeAlarms.cpp: In member function 'long int TimeAlarmsClass::getNextTrigger()': /TimeAlarms.cpp:326:31: warning: comparison between signed and unsigned integer expressions [-Wsign-compare] /TimeAlarms.cpp: In member function 'AlarmID_t TimeAlarmsClass::create(long int, OnTick_t, uint8_t, dtAlarmPeriod_t, uint8_t)': /TimeAlarms.cpp:332:46: warning: comparison between signed and unsigned integer expressions [-Wsign-compare] In file included from ../inc/spark_wiring.h:30:0, from ../inc/application.h:31, from /nis_0.1.cpp:2: ../../core-common-lib/SPARK_Firmware_Driver/inc/config.h:12:2: warning: #warning "Defaulting to Release Build" [-Wcpp] In file included from /nis_0.1.cpp:5:0: /SparkTime.h:48:12: error: expected ')' before '.' token /SparkTime.h:56:11: error: expected ')' before 'tnow' /SparkTime.h:56:11: error: expected ')' before 'tnow' /SparkTime.h:56:11: error: expected ')' before 'tnow' make: *** [/nis_0.1.o] Error 1

SparkTime compiled ok. As you would expect, if#include "TimeAlarms.h" is commented out in the .ino file the compile errors go away.

Hopefully something simple.

Hi @xPonic

TimeAlarms is ported to work with the built-in real-time clock that syncs from the cloud connection ( Time.now() ).

I could port it to work with my SparkTime NTP based library but the built in real-time clock uses fewer resources.

Thank you @bko! No port necessary.

1 Like

Thank you for the port @bko!

1 Like

@bko and anyone else. I’m getting a compile error with this library as automatically imported in the web IDE. If I comment out the include line, it compiles perfectly. I haven’t even tried to set up any alarms yet, just include and hit compile. The following is the tail of the error log. Please let me know if you need more:

In file included from doorbell.cpp:2:0:
doorbell.cpp: In function 'void setup()':
TimeAlarms/TimeAlarms.h:14:15: error: expected unqualified-id before '(' token
#define now() (Time.now()+time_zone_cache)
doorbell.cpp:55:38: note: in expansion of macro 'now'
digitalWrite(doorbellPin, LOW);
doorbell.cpp: In function 'void processSchedule()':
doorbell.cpp:143:52: warning: NULL used in arithmetic [-Wpointer-arith]
In file included from doorbell.cpp:2:0:
TimeAlarms/TimeAlarms.h:14:15: error: expected unqualified-id before '(' token
#define now() (Time.now()+time_zone_cache)
doorbell.cpp:147:60: note: in expansion of macro 'now'
void processSchedule() {
doorbell.cpp:145:13: warning: unused variable 'workingTime' [-Wunused-variable]

make: *** [doorbell.o] Error 1

Error: Could not compile. Please review your code.

I would like to use this, as apparently writing a recurring scheduler from scratch is hard indeed, and I can probably use this without a problem. Thanks for taking a look.

EDIT: If I comment out all calls to Time.now() this compiles fine. Which Time library must I use, if not the one provided in the core of spark?

EDIT 2: (Workaround) If I rename all instances of Time.now() to just now() it seems to compile fine, flash fine, and the code seems to work. This is nice and all, but it breaks the convention of using Time.now() doesn’t it?

EDIT 3: So I may have figured out the problem with now() vs Time.now(). I don’t know how to solve it, unfortunately, but this can help someone that does know how:

This exists in TimeAlarms.h:

extern time_t time_zone_cache;  // from spark_wiring_time.cpp
#define now() (Time.now()+time_zone_cache)

So in my ino file, when I type:


it is getting replaced in the compiler with:


Because Time class has no (Time.now()+time_zone_cache) method (even if it did, that syntax is invalid), it gives a compiler error and refuses to compile.

By replacing all references of Time.now() with just now() I get a compiling program, but the times are all whacky. For instance, when I call Time.zone(-5) to set my timezone to central time, the spark reports the time as 20:41 when in fact it is 01:41.

Anyone have an idea? Am I doing this wrong, or is there a bug in the library?

Hi @damccull

OK, definitely a bug but no one has run into it before since you call Alarm.delay(N); in loop to make the alarms update. I put in this macro to avoid editing the library in a million call sites for now() but it is hurting you in your code.

Try adding this after the #include for the library in your code:

#undef now()

If that works I will put it in the library and republish it.


Hi @bko. Thanks for checking on this for me. Here’s my results:

When adding Time.now() back in to replace instances of now() I get the correct time, calibrated for my set timezone again, and it compiles and runs properly.

I do have another issue I’d like your advice on. No matter which way I do it (with or without the #undef now()) I still can’t get the alarms to fire. I might be doing it wrong.

I have a global struct array:

struct ScheduledTime schedule[112];

Then in setup() I have this loop for testing:

for(int i = 0; i < 112;i++) {
    schedule[i].tstamp = Time.now() + (i * 2);
    schedule[i].active = (i%2 ? true : false);
    if(schedule[i].active) {
        AlarmId aid = Alarm.alarmRepeat(schedule[i].tstamp,EnableDoorbell);
        Spark.publish("Alarm set", "Alarm ID: " + String(aid) + " -- " + "Alarm Time: " + Time.timeStr(schedule[i].tstamp));
    } else {

When I monitor the events for this device, all the alarms set to EnableDoorbell report their ID as 255, and none of the alarms (regardless of their task) actually go off. The beginning of my loop() function is:


if(doorbellEnabledSchedule) {
    digitalWrite(D7, HIGH);
} else {
    digitalWrite(D7, LOW);

At the bottom of my file I have these two callback functions:

void EnableDoorbell() {
    doorbellEnabledSchedule = true;
    Spark.publish("doorbellState","enabled:" + String(schedule[scheduleCurrentEntry].tstamp));

void disableDoorbell() {
    doorbellEnabledSchedule = false;
    Spark.publish("doorbellState","disabled:" + String(schedule[scheduleCurrentEntry].tstamp));

With this code in appropriate places, it never executes the callbacks. I never get events published, nor a blinking LED.

Hi @damccull

I don’t the library works properly with Alarm.delay(0);

It has a while loop that will never service the alarms if the value is zero. Try a small positive number and see if that works.

Well, I tried it at 0, then at 1, then at 100, and again at 1000, but I still don’t get alarms fired. This is weird. I feel like I’m doing it way wrong, since noone else seems to have the problem. @bko Can I PM you a link to a gist containing my entire sketch?

Hi @damccull

Sure! I can look at it tonight.

Re-reading your code above, you seem to be taking the current time plus 0, 2, 4,…222 seconds and making a repeating alarm for all those times. That seems very fast to me and I am not sure what you are trying to do. I think most folks are using the hour, minute, second interface, not the 32-bit time one you are using.

You know that by default the library allows for dtNBR_ALARMS which is defined to be 6 while you are making 112 alarms. You should look at the return value of the Alarm.alarmRepeat() call, aid in your code above and see if it is dtINVALID_ALARM_ID which is value 255.

@bko I didn’t know it only allowed 6 alarms! How can I increase that number? I hope I don’t have to modify the library as a whole. Thanks for letting me know that 255 is the invalid alarm id value. I couldn’t figure out why all my alarms were getting the same ID :slight_smile: Is this library even going to be able to handle 112 alarms if I need it to?

I’m only using the stepped times in the for-loop to test and see if I can get the code working. Eventually, these will be user-configurable.

I did look at the various public methods of the library, and it seems like all the hour, minute, second functions simply translate them into a unix timestamp anyways and then pass it to the method I’m using, so I figured that it would be easier for testing to just use the timestamp as given.

For real time use we can definitely look into STM32’s onchip RTCAlarm interrupts like we currently do for Spark.sleep.


You should probably look at the original author’s site here:


You can increase the number of alarms by changing the line:

#define dtNBR_ALARMS 6   // max is 255

You won’t be able to load the library invisibly on the web IDE then–you will need to grab the files from github and add it as files on tabs using the little circle-plus in the upper part of the web IDE page.