diff --git a/README.md b/README.md index ff78732..e420409 100644 --- a/README.md +++ b/README.md @@ -1,13 +1,15 @@ -CronAlarms -========== +# CronAlarms + Using expressions suitable for the program cron (crontab syntax), the library allows performing tasks at specific times or after specific intervals. It depends on ctime library, provided by SDKs. API resembles the popular TimeAlarms library. Tasks can be created to continuously repeat or to occur only once. It is a wrapper of ccronexpr. -Usage ------ +## Usage + +### Using classic callback + Your sketch should call the `Cron.delay()` function in the main loop. It can also replace the Arduino delay() function if a time in milliseconds is specified as argument. The timeliness of triggers depends on sketch calling this function often. Alarms are serviced in the `Cron.delay()` method. Here is how you create an alarm to trigger a task repeatedly at a particular time of day: @@ -52,15 +54,50 @@ You can also set specific dates and times within a year, i.e. noon of 4th July. `Cron.create("0 0 12 4 7 *", Celebration, true);` -Other low level functions: -- disable( ID); - prevent the alarm associated with the given ID from triggering -- enable(ID); - enable the alarm +### Using lambda + +You can use a lambda instead of plain old callback. + +Using a lambda offers more flexibility: you can set its behavior depending on criteria set at runtime. + +eg. the lambda can capture the pinId and pinState and the lambda execute a `digitalWrite(pinId, pinState);` + +`Cron.create("0 0 12 4 7 *", [pinId,pinstate](){ digitalWrite(pinId, pinState) }, true);` +### Using callable + +You can use a callable instead of plain old callback. + +As for lambda, using a callable offers more flexibility: you can set its behavior depending on criteria set at runtime. + +eg. the lambda can capture the pinId and pinState and the lambda execute a `digitalWrite(pinId, pinState);` + +```C +class MyCallable { + public: + MyCallable(size_t value) : _value(value) {} + + void operator()() { + Serial.print("[callable] the value is: "); + Serial.println(_value); + } + + private: + size_t _value = 0; +}; + +size_t value = random(99999); // value known at runtime only +Cron.create("0 0 12 4 7 *", MyCallable(random), true); +``` + +### Other low level functions +- disable( ID); - prevent the alarm associated with the given ID from triggering +- enable(ID); - enable the alarm - getTriggeredAlarmId(); - returns the currently triggered alarm id, only valid in an alarm callback - globalUpdateNextTrigger(), globalenable(), and globaldisable() - can be used to temporarily suspend activity during timesetting or time zone change -FAQ ---- +## FAQ + _Q: What hardware and software is needed to use this library?_ A: This library requires an SDK with a ctime implementation. No internal or external hardware is used by the Alarm library. @@ -74,7 +111,7 @@ You can call Cron.delay() if you need to service the scheduler without a delay. _Q: Are there any restrictions on the code in a task handler function?_ -A: No. The scheduler does not use interrupts so your task handling function is no different from other functions you create in your sketch. +A: No. The scheduler does not use interrupts so your task handling function is no different from other functions you create in your sketch. _Q: What are the intervals that can be scheduled?_ diff --git a/examples/CronAlarms_example/CronAlarms_example.ino b/examples/CronAlarms_example/CronAlarms_example.ino index 436ecd4..4cd6605 100644 --- a/examples/CronAlarms_example/CronAlarms_example.ino +++ b/examples/CronAlarms_example/CronAlarms_example.ino @@ -24,6 +24,20 @@ CronId id; +class MyCallable { + public: + MyCallable(size_t rxBufferSize) : _rxBufferSize(rxBufferSize) {} + + void operator()() { + Serial.print("[callable] serial RX buffer size: "); + Serial.println(_rxBufSize); + } + + private: + size_t rxBufferSize = 0; +}; + + void setup() { #if defined(ESP8266) || defined(ESP32) WiFi.mode(WIFI_OFF); // disconect wifi to prevent NTP setting the time @@ -58,6 +72,18 @@ void setup() { Cron.create("*/15 * * * * *", Repeats, false); // timer for every 15 seconds id = Cron.create("*/2 * * * * *", Repeats2, false); // timer for every 2 seconds Cron.create("*/10 * * * * *", OnceOnly, true); // called once after 10 seconds + + // using lambda + size_t rxBufSize = Serial.getRxBufferSize(); // runtime defined value + Cron.create("*/10 * * * * *", // timer for every 10 seconds + [](rxBufSize)(){ + Serial.print("[lambda] serial RX buffer size: "); + Serial.println(rxBufSize); + }, false); + + // using callable + Cron.create("*/10 * * * * *", MyCallable(rxBufSize), false); // timer for every 10 seconds + Serial.println("Ending setup..."); } diff --git a/src/CronAlarms.cpp b/src/CronAlarms.cpp index 238339b..ec6a3b4 100644 --- a/src/CronAlarms.cpp +++ b/src/CronAlarms.cpp @@ -172,7 +172,7 @@ void CronClass::serviceAlarms() Alarm[servicedCronId].updateNextTrigger(); } if (TickHandler != NULL) { - (*TickHandler)(); // call the handler + TickHandler(); // call the handler } } } diff --git a/src/CronAlarms.h b/src/CronAlarms.h index a7b939f..be8563f 100644 --- a/src/CronAlarms.h +++ b/src/CronAlarms.h @@ -4,7 +4,7 @@ #define CronAlarms_h #include -#include +#include extern "C" { #include "ccronexpr/ccronexpr.h" @@ -28,7 +28,7 @@ typedef CronID_t CronId; // Arduino friendly name #define dtINVALID_ALARM_ID 255 #define dtINVALID_TIME (time_t)(-1) -typedef void (*OnTick_t)(); // alarm callback function typedef +using OnTick_t = std::function; // can store a plain old callback or a callable // class defining an alarm instance, only used by dtAlarmsClass class CronEventClass