Scheduler_example19_Dynamic_Tasks.ino 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. /**
  2. TaskScheduler Test sketch - test of Task destructor
  3. Test case:
  4. Main task runs every 100 milliseconds 100 times and in 50% cases generates a task object
  5. which runs 1 to 10 times with 100 ms to 5 s interval, and then destroyed.
  6. Garbage collection deletes all the tasks which have finished (enabled in their respective
  7. OnDisable methods)
  8. This sketch uses the following libraries:
  9. - FreeMemory library: https://github.com/McNeight/MemoryFree
  10. - QueueArray library: https://playground.arduino.cc/Code/QueueArray/
  11. */
  12. #define _TASK_WDT_IDS // To enable task unique IDs
  13. #define _TASK_SLEEP_ON_IDLE_RUN // Compile with support for entering IDLE SLEEP state for 1 ms if not tasks are scheduled to run
  14. #define _TASK_LTS_POINTER // Compile with support for Local Task Storage pointer
  15. #include <TaskScheduler.h>
  16. #include <QueueArray.h>
  17. // int freeMemory();
  18. #if defined (ARDUINO_ARCH_AVR)
  19. #include <MemoryFree.h>
  20. #elif defined(__arm__)
  21. extern "C" char* sbrk(int incr);
  22. static int freeMemory() {
  23. char top = 't';
  24. return &top - reinterpret_cast<char*>(sbrk(0));
  25. }
  26. #elif defined (ARDUINO_ARCH_ESP8266) || defined (ARDUINO_ARCH_ESP32)
  27. int freeMemory() { return ESP.getFreeHeap();}
  28. #else
  29. // Supply your own freeMemory method
  30. int freeMemory() { return 0;}
  31. #endif
  32. Scheduler ts;
  33. // Callback methods prototypes
  34. void MainLoop();
  35. void GC();
  36. // Statis task
  37. Task tMain(100 * TASK_MILLISECOND, 100, &MainLoop, &ts, true);
  38. Task tGarbageCollection(200 * TASK_MILLISECOND, TASK_FOREVER, &GC, &ts, false);
  39. void Iteration();
  40. bool OnEnable();
  41. void OnDisable();
  42. int noOfTasks = 0;
  43. QueueArray <Task*> toDelete;
  44. void MainLoop() {
  45. Serial.print(millis()); Serial.print("\t");
  46. Serial.print("MainLoop run: ");
  47. int i = tMain.getRunCounter();
  48. Serial.print(i); Serial.print(F(".\t"));
  49. if ( random(0, 101) > 50 ) { // generate a new task only in 50% of cases
  50. // Generating another task
  51. long p = random(100, 5001); // from 100 ms to 5 seconds
  52. long j = random(1, 11); // from 1 to 10 iterations)
  53. Task *t = new Task(p, j, Iteration, &ts, false, OnEnable, OnDisable);
  54. Serial.print(F("Generated a new task:\t")); Serial.print(t->getId()); Serial.print(F("\tInt, Iter = \t"));
  55. Serial.print(p); Serial.print(", "); Serial.print(j);
  56. Serial.print(F("\tFree mem=")); Serial.print(freeMemory());
  57. Serial.print(F("\tNo of tasks=")); Serial.println(++noOfTasks);
  58. t->enable();
  59. }
  60. else {
  61. Serial.println(F("Skipped generating a task"));
  62. }
  63. }
  64. void Iteration() {
  65. Task &t = ts.currentTask();
  66. Serial.print(millis()); Serial.print("\t");
  67. Serial.print("Task N"); Serial.print(t.getId()); Serial.print(F("\tcurrent iteration: "));
  68. int i = t.getRunCounter();
  69. Serial.println(i);
  70. }
  71. bool OnEnable() {
  72. // to-do: think of something to put in here.
  73. return true;
  74. }
  75. void OnDisable() {
  76. Task *t = &ts.currentTask();
  77. unsigned int tid = t->getId();
  78. toDelete.push(t);
  79. tGarbageCollection.enableIfNot();
  80. Serial.print(millis()); Serial.print("\t");
  81. Serial.print("Task N"); Serial.print(tid); Serial.println(F("\tfinished"));
  82. }
  83. /**
  84. Standard Arduino setup and loop methods
  85. */
  86. void setup() {
  87. Serial.begin(115200);
  88. randomSeed(analogRead(0) + analogRead(5));
  89. noOfTasks = 0;
  90. Serial.println(F("Dynamic Task Creation/Destruction Example"));
  91. Serial.println();
  92. Serial.print(F("Free mem=")); Serial.print(freeMemory());
  93. Serial.print(F("\tNo of tasks=")); Serial.println(noOfTasks);
  94. Serial.println();
  95. }
  96. void GC() {
  97. if ( toDelete.isEmpty() ) {
  98. tGarbageCollection.disable();
  99. return;
  100. }
  101. Task *t = toDelete.pop();
  102. Serial.print(millis()); Serial.print("\t");
  103. Serial.print("Task N"); Serial.print(t->getId()); Serial.println(F("\tdestroyed"));
  104. Serial.print("Free mem="); Serial.print(freeMemory());
  105. Serial.print(F("\tNo of tasks=")); Serial.println(--noOfTasks);
  106. delete t;
  107. }
  108. void loop() {
  109. ts.execute();
  110. }