diff options
| author | Anatoli Arkhipenko <arkhipenko@hotmail.com> | 2015-10-22 23:17:45 -0400 |
|---|---|---|
| committer | Anatoli Arkhipenko <arkhipenko@hotmail.com> | 2015-10-22 23:17:45 -0400 |
| commit | ccd1047d0286027ff98ee7f1dfdfa1f9d5e6e4e3 (patch) | |
| tree | 2481326454d89e1977923475fda443ba3a78922c /examples | |
| parent | bb20df9c654cbed77bb5007814ae06f20f08ec36 (diff) | |
Support for taask IDs and Control Pointsv1.8.1
* Automatically and manually assigned task IDs
* Manually assigned Control Points within task's callback function
* Updated existing examples
* New example sketches
Diffstat (limited to 'examples')
5 files changed, 306 insertions, 96 deletions
diff --git a/examples/Scheduler_example/Scheduler_example.ino b/examples/Scheduler_example/Scheduler_example.ino index dece85a..74b60f9 100644 --- a/examples/Scheduler_example/Scheduler_example.ino +++ b/examples/Scheduler_example/Scheduler_example.ino @@ -1,3 +1,16 @@ +/** + * TaskScheduler Test + * + * Initially only tasks 1 and 2 are enabled + * Task1 runs every 2 seconds 10 times and then stops + * Task2 runs every 3 seconds indefinitely + * Task1 enables Task3 at its first run + * Task3 run every 5 seconds + * Task1 disables Task3 on its last iteration and changed Task2 to run every 1/2 seconds + * At the end Task2 is the only task running every 1/2 seconds + */ + + #include <TaskScheduler.h> Task t4(); @@ -5,18 +18,6 @@ Task t1(2000, 10, &t1Callback); Task t2(3000, -1, &t2Callback); Task t3(5000, -1, &t3Callback); -// Test -// Initially only tasks 1 and 2 are enabled -// Task1 runs every 2 seconds 10 times and then stops -// Task2 runs every 3 seconds indefinitely -// Task1 enables Task3 at its first run -// Task3 run every 5 seconds -// loop() runs every 1 second (a default scheduler delay, if no shorter tasks' interval is detected) -// Task1 disables Task3 on its last iteration and changed Task2 to run every 1/2 seconds -// Because Task2 interval is shorter than Scheduler default tick, loop() executes ecery 1/2 seconds now -// At the end Task2 is the only task running every 1/2 seconds - - Scheduler runner; @@ -74,9 +75,5 @@ void setup () { void loop () { - runner.execute(); - - Serial.println("Loop ticks at: "); - Serial.println(millis()); } diff --git a/examples/Scheduler_example3/Scheduler_example3.ino b/examples/Scheduler_example3/Scheduler_example3.ino index d683855..7111ac3 100644 --- a/examples/Scheduler_example3/Scheduler_example3.ino +++ b/examples/Scheduler_example3/Scheduler_example3.ino @@ -1,3 +1,12 @@ +/** + * TaskScheduler Test of OnEnable and OnDisable methods and illustration of using wrapper tasks for timout purposes + * + * A wrapper task runs every 30 seconds and initiates the test case + * Another task is run once for 5 seconds, and serves as a LED blinking timeout - 5 seconds + * Finally, a dedicated task which controls LED is running periodically until stopped, and makes the LED blink with 0.5 to 1 second interval. + * + */ + #define _TASK_SLEEP_ON_IDLE_RUN #include <TaskScheduler.h> diff --git a/examples/Scheduler_example4_StatusRequest/Scheduler_example4_StatusRequest.ino b/examples/Scheduler_example4_StatusRequest/Scheduler_example4_StatusRequest.ino index ffe4e3a..080de05 100644 --- a/examples/Scheduler_example4_StatusRequest/Scheduler_example4_StatusRequest.ino +++ b/examples/Scheduler_example4_StatusRequest/Scheduler_example4_StatusRequest.ino @@ -1,81 +1,80 @@ -/** This test demonstrates interaction between three simple tasks via StatusRequest object. - * Task T1 runs every 5 seconds and signals completion of a status request st. - * Tasks T2 and T3 are waiting on the same request (st) - * Task T3 does not renew its interest in status request st, so it is only invoked once (first iteration) - * Task T2 is invoked every time st completes, because it renews its interest in status of status request object st every iteration of T1 - */ - -#define _TASK_SLEEP_ON_IDLE_RUN -#define _TASK_STATUS_REQUEST - -#include <TaskScheduler.h> - -StatusRequest st; - -Scheduler ts; - -Task t1(5000, 1, &Callback1, &ts, true, NULL, &Disable1); -Task t2(&Callback2, &ts); -Task t3(&Callback3, &ts); - -/** T1 callback - * T1 just signals completion of st every 5 seconds - */ -void Callback1() { - Serial.println("T1: Signaling completion of ST"); - st.signalComplete(); -} - -/** T1 On Disable callback - * This callback renews the status request and restarts T1 delayed to run again in 5 seconds - */ -void Disable1() { - PrepareStatus(); - t1.restartDelayed(); -} - -/** T2 callback - * Invoked when status request st completes - */ -void Callback2() { - Serial.println("T2: Invoked due to completion of ST"); -} - - -/** T3 callback - * Invoked when status request st completes. - * This is only run once since T3 does not renew its interest in the status request st after first iteration - */ - void Callback3() { - Serial.println("T3: Invoked due to completion of ST"); - -} - -/** Prepare Status request st for another iteration - * - */ -void PrepareStatus() { - st.setWaiting(); // set the statusrequest object for waiting - t2.waitFor(&st); // request tasks 1 & 2 to wait on the object st -} - - -/** Main Arduino code - * Not much to do here. Just init Serial and set the initial status request - */ -void setup() { - - Serial.begin(115200); - Serial.println("TaskScheduler: Status Request Test 1. Simple Test."); - // put your setup code here, to run once: - PrepareStatus(); - t3.waitFor(&st); - - t1.delay(); -} - -void loop() { - // put your main code here, to run repeatedly: - ts.execute(); - +/** This test demonstrates interaction between three simple tasks via StatusRequest object.
+ * Task T1 runs every 5 seconds and signals completion of a status request st.
+ * Tasks T2 and T3 are waiting on the same request (st)
+ * Task T3 does not renew its interest in status request st, so it is only invoked once (first iteration)
+ * Task T2 is invoked every time st completes, because it renews its interest in status of status request object st every iteration of T1
+ */
+
+#define _TASK_SLEEP_ON_IDLE_RUN
+#define _TASK_STATUS_REQUEST
+#include <TaskScheduler.h>
+
+StatusRequest st;
+
+Scheduler ts;
+
+Task t1(5000, 1, &Callback1, &ts, true, NULL, &Disable1);
+Task t2(&Callback2, &ts);
+Task t3(&Callback3, &ts);
+
+/** T1 callback
+ * T1 just signals completion of st every 5 seconds
+ */
+void Callback1() {
+ Serial.println("T1: Signaling completion of ST");
+ st.signalComplete();
+}
+
+/** T1 On Disable callback
+ * This callback renews the status request and restarts T1 delayed to run again in 5 seconds
+ */
+void Disable1() {
+ PrepareStatus();
+ t1.restartDelayed();
+}
+
+/** T2 callback
+ * Invoked when status request st completes
+ */
+void Callback2() {
+ Serial.println("T2: Invoked due to completion of ST");
+}
+
+
+/** T3 callback
+ * Invoked when status request st completes.
+ * This is only run once since T3 does not renew its interest in the status request st after first iteration
+ */
+ void Callback3() {
+ Serial.println("T3: Invoked due to completion of ST");
+
+}
+
+/** Prepare Status request st for another iteration
+ *
+ */
+void PrepareStatus() {
+ st.setWaiting(); // set the statusrequest object for waiting
+ t2.waitFor(&st); // request tasks 1 & 2 to wait on the object st
+}
+
+
+/** Main Arduino code
+ * Not much to do here. Just init Serial and set the initial status request
+ */
+void setup() {
+
+ Serial.begin(115200);
+ Serial.println("TaskScheduler: Status Request Test 1. Simple Test.");
+
+ PrepareStatus();
+ t3.waitFor(&st);
+
+ t1.delay();
+}
+
+void loop() {
+
+ ts.execute();
+
}
diff --git a/examples/Scheduler_example6_IDLE/Scheduler_example6_IDLE.ino b/examples/Scheduler_example6_IDLE/Scheduler_example6_IDLE.ino new file mode 100644 index 0000000..f4df5d8 --- /dev/null +++ b/examples/Scheduler_example6_IDLE/Scheduler_example6_IDLE.ino @@ -0,0 +1,77 @@ + +/** + * This is a test to prove that processor really goes into IDLE sleep. + * For this setup: + * + * + +Task c(10, -1, &Count, &ts); +Task t(10000, 1, NULL, &ts, true, &tOn, &tOff); + +The result are: + +1): With #define _TASK_SLEEP_ON_IDLE_RUN enabled +Start +c1=10771 +c2=1001 + + +and + +2): With #define _TASK_SLEEP_ON_IDLE_RUN disabled (commented out) +Start +c1=529783 +c2=1001 + +C1 is scenario 2) is much higher than in scenario 1) because processor is put to sleep for 1), but not for 2) + + */ + + +/** + * Compile and run once with _TASK_SLEEP_ON_IDLE_RUN enabled, then with _TASK_SLEEP_ON_IDLE_RUN disabled. + * Compare the results. + */ + +//#define _TASK_SLEEP_ON_IDLE_RUN +#include <TaskScheduler.h> + +Scheduler ts; + +Task c(10, -1, &Count, &ts); +Task t(10000, 1, NULL, &ts, true, &tOn, &tOff); + + +volatile unsigned long c1, c2; +bool tOn() { + c1 = 0; + c2 = 0; + c.enable(); + + return true; +} + +void tOff() { + c.disable(); + Serial.print("c1=");Serial.println(c1); + Serial.print("c2=");Serial.println(c2); +} + +void setup() { + // put your setup code here, to run once: + Serial.begin(115200); + Serial.println("Start"); + t.delay(); + // ts.allowSleep(false); +} + +void Count() { + c2++; +} + + +void loop() { + // put your main code here, to run repeatedly: + ts.execute(); + c1++; +} diff --git a/examples/Scheduler_example7_WDT/Scheduler_example7_WDT.ino b/examples/Scheduler_example7_WDT/Scheduler_example7_WDT.ino new file mode 100644 index 0000000..ab880d2 --- /dev/null +++ b/examples/Scheduler_example7_WDT/Scheduler_example7_WDT.ino @@ -0,0 +1,128 @@ +/** + * TaskScheduler Test sketch - use of task IDs and watchdog timer to identify hung tasks + * Test case: + * Watchdog timer is set to 2 seconds (interrupt + reset) + * A hearbeat task (resetting the watchdog timer) is scheduled with 500 ms interval + * A number of tasks are running every 1 second and "rolling the dice" 0..9. If 5, task is made to enter infinite loop + * Device should reset in 2 seconds after a task enters infinite loop + * A task id and a control point number are saved to EEPROM prior to device reset, and are displayed after reboot. + * In real life, device might chose to NOT activate certain tasks which failed previously (failed sensors for instance) + */ + +#define _TASK_SLEEP_ON_IDLE_RUN +#define _TASK_WDT_IDS +#include <TaskScheduler.h> + +#include <EEPROM.h> +#include <avr/wdt.h> + +Scheduler ts; + +// Three tasks emulating accidental infinite loop +Task tTask1(1000, -1, &TaskCB, &ts, true); +Task tTask2(1000, -1, &TaskCB, &ts, true); +Task tTask3(1000, -1, &TaskCB, &ts, true); + +// Heartbeat task - resetting the watchdog timer periodically +// Initiates WDT on enable, and deactivates it on disable +Task tHB(500, -1, &HB, &ts, false, &HBOn, &HBOff); + +/** + * Emulating task callback function + * Prints task id and randomly "hangs" in two places. + * Control points are stored on the task prior to section which might hang, + * making this information available to the WDT interrupt handler + */ +void TaskCB() { + Task& T = ts.currentTask(); + + Serial.print("Task #:"); + Serial.print(T.getId()); + Serial.print(" current iteration = "); + Serial.println(T.getRunCounter()); + +// Hang if random number between 0 and 9 is 5 (10% probability) + T.setControlPoint(10); + if (random(10) == 5) for(;;); + +// Hang if random number between 0 and 99 is more that 85 (15% probability) + T.setControlPoint(85); + if (random(100) > 84) for(;;); +} + +/** + * This On Enable method sets up the WDT + * for interrupt and reset after 2 seconds + */ +bool HBOn() { + + //disable interrupts + cli(); + //reset watchdog + wdt_reset(); + //set up WDT interrupt + WDTCSR = (1<<WDCE)|(1<<WDE); + //Start watchdog timer with aDelay prescaller + WDTCSR = (1<<WDIE)|(1<<WDE)|(WDTO_2S & 0x2F); +// WDTCSR = (1<<WDIE)|(WDTO_2S & 0x2F); // interrupt only without reset + //Enable global interrupts + sei(); +} + +/** + * This On Disable method disables WDT + */ +void HBOff() { + wdt_disable(); +} + +/** + * This is a periodic reset of WDT + */ +void HB() { + wdt_reset(); + +} + +/** + * Watchdog timeout ISR + * + */ +ISR(WDT_vect) +{ + Task& T = ts.currentTask(); + + digitalWrite(13, HIGH); + EEPROM.write(0, (byte)T.getId()); + EEPROM.write(1, (byte)T.getControlPoint()); + digitalWrite(13, LOW); +} + +/** + * Standard arduino setup routine + */ +void setup() { + + Serial.begin(115200); + + randomSeed(analogRead(0)+analogRead(5)); + + pinMode(13, OUTPUT); + digitalWrite(13, LOW); + + + Serial.println("WDT heartbeat test"); + Serial.print("Last task before reset="); Serial.println(EEPROM.read(0)); + Serial.print("Last control point before reset="); Serial.println(EEPROM.read(1)); + + delay(2000); + + tHB.enableDelayed(); +} + +/** + * Not much is left for the loop() + */ +void loop() { + ts.execute(); +}
|
