TaskScheduler.html 97 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806
  1. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
  2. <HTML>
  3. <HEAD>
  4. <META HTTP-EQUIV="CONTENT-TYPE" CONTENT="text/html; charset=utf-8">
  5. <TITLE></TITLE>
  6. <META NAME="GENERATOR" CONTENT="LibreOffice 3.5 (Linux)">
  7. <META NAME="CREATED" CONTENT="20150206;16300000">
  8. <META NAME="CHANGEDBY" CONTENT="Anatoli Arkhipenko">
  9. <META NAME="CHANGED" CONTENT="20151022;23060000">
  10. <META NAME="Info 1" CONTENT="">
  11. <META NAME="Info 2" CONTENT="">
  12. <META NAME="Info 3" CONTENT="">
  13. <META NAME="Info 4" CONTENT="">
  14. <STYLE TYPE="text/css">
  15. <!--
  16. @page { margin: 0.79in }
  17. P { margin-bottom: 0.08in; direction: ltr; color: #000000; widows: 0; orphans: 0 }
  18. P.western { font-family: "Liberation Serif", "MS PMincho", serif; font-size: 12pt; so-language: en-US }
  19. P.cjk { font-family: "WenQuanYi Micro Hei", "MS Mincho"; font-size: 12pt; so-language: zh-CN }
  20. P.ctl { font-family: "Lohit Hindi", "MS Mincho"; font-size: 12pt; so-language: hi-IN }
  21. A:link { color: #0000ff }
  22. -->
  23. </STYLE>
  24. </HEAD>
  25. <BODY LANG="en-US" TEXT="#000000" LINK="#0000ff" BGCOLOR="#ffffff" DIR="LTR">
  26. <P CLASS="western" STYLE="margin-bottom: 0in"><B>Task Scheduler –
  27. cooperative multitasking for Arduino microcontrollers</B></P>
  28. <P CLASS="western" STYLE="margin-bottom: 0in"><B>Version 1.8.1:
  29. 2015-10-21</B></P>
  30. <P CLASS="western" STYLE="margin-bottom: 0in"><BR>
  31. </P>
  32. <P CLASS="western" STYLE="margin-bottom: 0in"><B>OVERVIEW</B>:</P>
  33. <P CLASS="western" STYLE="margin-bottom: 0in">A lightweight
  34. implementation of cooperative multitasking (task scheduling)
  35. supporting:</P>
  36. <OL>
  37. <LI><P CLASS="western" STYLE="margin-bottom: 0in">Periodic task
  38. execution (with dynamic execution period in milliseconds)</P>
  39. <LI><P CLASS="western" STYLE="margin-bottom: 0in">Number of
  40. iterations (n times)</P>
  41. <LI><P CLASS="western" STYLE="margin-bottom: 0in">Execution of tasks
  42. in predefined sequence</P>
  43. <LI><P CLASS="western" STYLE="margin-bottom: 0in">Dynamic change of
  44. task execution parameters (frequency, number of iterations, callback
  45. function)</P>
  46. <LI><P CLASS="western" STYLE="margin-bottom: 0in">Power saving via
  47. entering IDLE sleep mode between tasks are scheduled to run</P>
  48. <LI><P CLASS="western" STYLE="margin-bottom: 0in">Support for task
  49. invocation via Status Request object</P>
  50. <LI><P CLASS="western" STYLE="margin-bottom: 0in">Support for task
  51. IDs and Control Points for error handling and watchdog timer</P>
  52. </OL>
  53. <P CLASS="western" STYLE="margin-bottom: 0in"><BR>
  54. </P>
  55. <P CLASS="western" STYLE="margin-bottom: 0in"><B>TASK</B>:</P>
  56. <P CLASS="western" STYLE="margin-bottom: 0in">“Task” is a
  57. container concept that links together:</P>
  58. <OL>
  59. <LI><P CLASS="western" STYLE="margin-bottom: 0in">Execution interval</P>
  60. <LI><P CLASS="western" STYLE="margin-bottom: 0in">Execution event
  61. (Status Request)</P>
  62. <LI><P CLASS="western" STYLE="margin-bottom: 0in">Number of
  63. execution iterations</P>
  64. <LI><P CLASS="western" STYLE="margin-bottom: 0in">Piece of code
  65. performing task activities (callback functions)</P>
  66. </OL>
  67. <P CLASS="western" STYLE="margin-bottom: 0in"><BR>
  68. </P>
  69. <P CLASS="western" STYLE="margin-bottom: 0in"><B>Tasks</B> are linked
  70. into execution <B>chains</B>, which are processed by the “Scheduler”
  71. in the order they are linked.</P>
  72. <P CLASS="western" STYLE="margin-bottom: 0in"><BR>
  73. </P>
  74. <P CLASS="western" STYLE="margin-bottom: 0in">Each task performs its
  75. function via callback function. Scheduler calls Task’s callback
  76. function periodically until task is disabled or task runs out of
  77. iterations. In addition to “regular” callback, two methods could
  78. be enabled for each task: a callback function invoked once when task
  79. is enabled, and a callback function invoked once when the task is
  80. disabled. Those two special methods allows task to properly initiate
  81. themselves for execution and clean-up after execution is over.
  82. </P>
  83. <P CLASS="western" STYLE="margin-bottom: 0in"><BR>
  84. </P>
  85. <P CLASS="western" STYLE="margin-bottom: 0in">Tasks are responsible
  86. for supporting <B>cooperative</B> <B>multitasking</B> by being “good
  87. neighbors”, i.e., running their callback functions quickly in a
  88. non-blocking way and releasing control as soon as possible.
  89. </P>
  90. <P CLASS="western" STYLE="margin-bottom: 0in"><BR>
  91. </P>
  92. <P CLASS="western" STYLE="margin-bottom: 0in">“Scheduler” is
  93. executing Tasks' callback functions in the order the tasks were added
  94. to the chain, from first to last. Scheduler stops and exists after
  95. processing the chain once in order to allow other statements in the
  96. main code of <B>loop()</B> function to run. This <B>a “scheduling
  97. pass”.</B></P>
  98. <P CLASS="western" STYLE="margin-bottom: 0in"><BR>
  99. </P>
  100. <P CLASS="western" STYLE="margin-bottom: 0in">If compiled with
  101. <FONT FACE="Courier New, monospace">_TASK_SLEEP_ON_IDLE_RUN</FONT>
  102. enabled, the scheduler will place processor into IDLE sleep mode (for
  103. approximately 1 ms, as the timer interrupt will wake it up), after
  104. what is determined to be an “idle” pass. An Idle Pass is a pass
  105. through the task chain when no Tasks were scheduled to run their
  106. callback functions. This is done to avoid repetitive empty passes
  107. through the chain when no tasks need to be executed. If any of the
  108. tasks in the chain always requires immediate execution (aInterval =
  109. 0), then there will be no IDLE sleep between task callback execution.</P>
  110. <P CLASS="western" STYLE="margin-bottom: 0in"><BR>
  111. </P>
  112. <P CLASS="western" STYLE="margin-bottom: 0in; page-break-after: avoid">
  113. <B>Below is the flowchart of a Task lifecycle:</B></P>
  114. <P CLASS="western" STYLE="margin-bottom: 0in"><IMG SRC="TaskScheduler_html.png" NAME="graphics1" ALIGN=BOTTOM WIDTH=664 HEIGHT=747 BORDER=0></P>
  115. <P CLASS="western" STYLE="margin-bottom: 0in"><BR>
  116. </P>
  117. <P CLASS="western" STYLE="margin-bottom: 0in"><B>Note: </B>Task
  118. Scheduler uses <B>millis()</B> to determine if tasks are ready to be
  119. invoked. Therefore, if you put your device to any “deep” sleep
  120. mode disabling timer interrupts, the <B>millis()</B> count will be
  121. suspended, leading to effective suspension of scheduling. Upon wake
  122. up, active tasks need to be re-enabled, which will effectively reset
  123. their internal time scheduling variables to the new value of
  124. <B>millis(). </B>Time spent in deep sleep mode should be considered
  125. “frozen”, i.e., if a task was scheduled to run in 1 second from
  126. now, and device was put to sleep for 5 minutes, upon wake up, the
  127. task will still be scheduled 1 second from the time of wake up.
  128. Executing <B>enable() </B>function on this tasks will make it run as
  129. soon as possible. This is a concern only for tasks which are required
  130. to run in a truly periodical manner (in absolute time terms).
  131. </P>
  132. <P CLASS="western" STYLE="margin-bottom: 0in"><BR>
  133. </P>
  134. <P CLASS="western" STYLE="margin-bottom: 0in">In addition to
  135. time-only invocation, tasks can be scheduled to wait on an event
  136. employing StatusRequest objects (more about Status Requests later).</P>
  137. <P CLASS="western" STYLE="margin-bottom: 0in">Consider a scenario
  138. when one task (t1) is performing a function which affects execution
  139. of many tasks (t2, t3). In this case the task t1 will “signal”
  140. completion of its function via Status Request object. Tasks t2 and t3
  141. are “waiting” on the same Status Request object. As soon as
  142. status request completes, t2 and t3 are activated.</P>
  143. <P CLASS="western" STYLE="margin-bottom: 0in"><BR>
  144. </P>
  145. <P CLASS="western" STYLE="margin-bottom: 0in">Alternative scenario is
  146. the ne task (t1) and waiting for the completion of a number of tasks
  147. (t2, t3). When done, t2 and t3 signal completion of their functions,
  148. t1 is invoked.
  149. </P>
  150. <P CLASS="western" STYLE="margin-bottom: 0in"><BR>
  151. </P>
  152. <P CLASS="western" STYLE="margin-bottom: 0in">Please see the examples
  153. at the end of this document.</P>
  154. <P CLASS="western" STYLE="margin-bottom: 0in"><BR>
  155. </P>
  156. <P CLASS="western" STYLE="margin-bottom: 0in"><B>COMPILE PARAMETERS:</B></P>
  157. <P CLASS="western" STYLE="margin-bottom: 0in">This library could be
  158. compiled with several options.
  159. </P>
  160. <P CLASS="western" STYLE="margin-bottom: 0in">These parameters must
  161. be defined before inclusion of the library header file into the
  162. sketch.</P>
  163. <P CLASS="western" STYLE="margin-bottom: 0in"><BR>
  164. </P>
  165. <P CLASS="western" STYLE="margin-bottom: 0in">#define
  166. <B>_TASK_TIMECRITICAL</B></P>
  167. <P CLASS="western" STYLE="margin-bottom: 0in">...will compile the
  168. library with time critical tracking option enabled.</P>
  169. <P CLASS="western" STYLE="margin-bottom: 0in">Time critical option
  170. keeps track where next execution time of the task falls, and makes it
  171. available via API through Task::<B> getOverrun() </B>function. If
  172. <B>getOverrun </B>returns a negative value, this Task’s next
  173. execution time is in the past, and task is behind schedule. This most
  174. probably means that either task’s callback function runtime is too
  175. long, or the execution interval is too short (then schedule is too
  176. aggressive).</P>
  177. <P CLASS="western" STYLE="margin-bottom: 0in">A positive value
  178. indicates that task is on schedule, and callback functions have
  179. enough time to finish before the next scheduled pass.
  180. </P>
  181. <P CLASS="western" STYLE="margin-bottom: 0in"><BR>
  182. </P>
  183. <P CLASS="western" STYLE="margin-bottom: 0in">#define
  184. <B>_TASK_SLEEP_ON_IDLE_RUN</B></P>
  185. <P CLASS="western" STYLE="margin-bottom: 0in">...will compile the
  186. library with the <B>sleep</B> option enabled (AVR boards only).</P>
  187. <P CLASS="western" STYLE="margin-bottom: 0in">When enabled, scheduler
  188. will put the microcontroller into <B>SLEEP_MODE_IDLE</B> state if
  189. none of the tasks’ callback functions were activated during pass.
  190. <B>IDLE</B> state is interrupted by timers once every 1 ms. Helps
  191. conserve power. Device in SLEEP_MODE_IDLE wakes up to all hardware
  192. and timer interrupts, so scheduling is kept current.</P>
  193. <P CLASS="western" STYLE="margin-bottom: 0in"><BR>
  194. </P>
  195. <P CLASS="western" STYLE="margin-bottom: 0in">#define
  196. <B>_TASK_STATUS_REQUEST</B></P>
  197. <P CLASS="western" STYLE="margin-bottom: 0in">…will compile
  198. TaskScheduler with support for StatusRequest object. Status Requests
  199. are objects allowing tasks to wait on an event, and signal event
  200. completion to each other.
  201. </P>
  202. <P CLASS="western" STYLE="margin-bottom: 0in"><BR>
  203. </P>
  204. <P CLASS="western" STYLE="margin-bottom: 0in">#define <B>_TASK_WDT_IDS</B></P>
  205. <P CLASS="western" STYLE="margin-bottom: 0in">…will compile
  206. TaskScheduler with support for Task Ids and Control Points. Each task
  207. can be (and is by default) assigned an ID, which could be used to
  208. identify the task in case there is a problem with it. Furthermore
  209. within the task, Control Points could be defined to further help with
  210. pinpointing potential problem areas. For instance, the tasks which
  211. deal with external resources (sensors, serial communications,
  212. anything hardware dependent) can be blocked (or hung), by failed
  213. hardware. In this case, a watchdog timer could be employed to trap
  214. such a failed task, and identify which one (by task id) and where in
  215. the task (by a control point) the problem is likely located.</P>
  216. <P CLASS="western" STYLE="margin-bottom: 0in">
  217. </P>
  218. <P CLASS="western" STYLE="margin-bottom: 0in"><B>Note: </B>by
  219. default, talk IDs are assigned sequentially (1, 2, 3, …) to the
  220. tasks as they are being created. Programmer can assign a specific
  221. task id. <B>Task ids are unsigned integers.</B></P>
  222. <P CLASS="western" STYLE="margin-bottom: 0in">Control points provide
  223. a way to identify potential problem points within a task. Control
  224. points are <B>unsigned integers </B>as well. Please note that there
  225. is only one control point per task, and it is set to zero when the
  226. task’s callback function is invoked (this is done to prevent
  227. “stray” control point from previous task(s) confusing the
  228. matters.</P>
  229. <P CLASS="western" STYLE="margin-bottom: 0in">Example #7 contains a
  230. test of task ID and control points functionality.
  231. </P>
  232. <P CLASS="western" STYLE="margin-bottom: 0in"><BR>
  233. </P>
  234. <P CLASS="western" STYLE="margin-bottom: 0in"><B>NOTE: above
  235. parameters are DISABLED by default, and need to be explicitly
  236. enabled.</B></P>
  237. <P CLASS="western" STYLE="margin-bottom: 0in"><BR>
  238. </P>
  239. <P CLASS="western" STYLE="margin-bottom: 0in"><BR>
  240. </P>
  241. <P CLASS="western" STYLE="margin-bottom: 0in"><BR>
  242. </P>
  243. <P CLASS="western" STYLE="margin-bottom: 0in"><FONT SIZE=4><B>API
  244. DOCUMENTATION:</B></FONT></P>
  245. <P CLASS="western" STYLE="margin-bottom: 0in"><BR>
  246. </P>
  247. <P CLASS="western" STYLE="margin-bottom: 0in; page-break-after: avoid">
  248. <FONT SIZE=4><B>TASKS:</B></FONT></P>
  249. <P CLASS="western" STYLE="margin-bottom: 0in"><BR>
  250. </P>
  251. <P CLASS="western" STYLE="margin-bottom: 0in">CREATION:</P>
  252. <P CLASS="western" STYLE="margin-bottom: 0in"><B>Task();</B></P>
  253. <P CLASS="western" STYLE="margin-bottom: 0in"><BR>
  254. </P>
  255. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in">Default
  256. constructor.
  257. </P>
  258. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in">Takes
  259. no parameters and creates a task that could be scheduled to run at
  260. every scheduling pass indefinitely, but does not have a callback
  261. function defined, so no execution will actually take place.
  262. </P>
  263. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in">All
  264. tasks are created <B>disabled</B> by default.</P>
  265. <P CLASS="western" STYLE="margin-bottom: 0in"><BR>
  266. </P>
  267. <P CLASS="western" STYLE="margin-bottom: 0in; page-break-after: avoid">
  268. <B>Task(unsigned long aInterval, long aIterations, void
  269. (*aCallback)(), Scheduler* aScheduler, bool aEnable, bool
  270. (*aOnEnable)(), void (*aOnDisable)())</B></P>
  271. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><BR>
  272. </P>
  273. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in">Constructor
  274. with parameters.
  275. </P>
  276. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in">Creates
  277. a task that is scheduled to run every &lt;aInterval&gt; milliseconds,
  278. &lt;aIterations&gt; times, executing &lt;aCallback&gt; function on
  279. every pass.
  280. </P>
  281. <OL>
  282. <LI><P CLASS="western" STYLE="margin-bottom: 0in">aInterval is in
  283. milliseconds (<B>default = 0)</B></P>
  284. <LI><P CLASS="western" STYLE="margin-bottom: 0in">aIteration in
  285. number of times, -1 for indefinite execution (<B>default = -1)</B><BR><B>Note:
  286. </B>Tasks do not remember the number of iteration set initially.
  287. After the iterations are done, internal iteration counter is 0. If
  288. you need to perform another set of iterations, you need to set the
  289. number of iterations again. <BR><B>Note: </B>Tasks which performed
  290. all their iterations remain active.
  291. </P>
  292. <LI><P CLASS="western" STYLE="margin-bottom: 0in">aCallback is a
  293. pointer to a void callback function without parameters (<B>default =
  294. NULL)</B></P>
  295. <LI><P CLASS="western" STYLE="margin-bottom: 0in">aScheduler –
  296. <B>optional</B> reference to existing scheduler. If supplied (not
  297. NULL) this task will be appended to the task chain of the current
  298. scheduler). (<B>default = NULL)</B></P>
  299. <LI><P CLASS="western" STYLE="margin-bottom: 0in">aEnable –
  300. <B>optional</B>. Value of <B>true </B>will create task enabled.
  301. (<B>default = false)</B></P>
  302. <LI><P CLASS="western" STYLE="margin-bottom: 0in">aOnEnable is a
  303. pointer to a bool callback function without parameters, invoked when
  304. task is enabled. If OnEnable function returns <B>true</B>, task is
  305. enabled. If <B>OnEnable</B> function return <B>false</B>, task
  306. remains disabled (<B>default = NULL)</B></P>
  307. <LI><P CLASS="western" STYLE="margin-bottom: 0in">aOnDisable is a
  308. pointer to a void callback function without parameters, invoked when
  309. task is disabled (<B>default = NULL)</B></P>
  310. </OL>
  311. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><BR>
  312. </P>
  313. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in">All
  314. tasks are created <B>disabled</B> by default (unless aEnable = true).
  315. You have to explicitly enable the task for execution.</P>
  316. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in">Enabled
  317. task is scheduled for execution immediately. Enable tasks with delay
  318. (standard execution interval or specific execution interval) in order
  319. to defer first run of the task.</P>
  320. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><BR>
  321. </P>
  322. <P CLASS="western" STYLE="margin-bottom: 0in; page-break-after: avoid">
  323. <B>Task(void (*aCallback)(), Scheduler* aScheduler, bool
  324. (*aOnEnable)(), void (*aOnDisable)())</B></P>
  325. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><BR>
  326. </P>
  327. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in">If
  328. compiled with support for Status Request objects, this constructor
  329. creates a Task for activation on event (since such tasks must run
  330. <B>waitFor() </B>method, their <I>interval</I>, <I>iteration</I> and
  331. <I>enabled</I> status will be set by that method.</P>
  332. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><BR>
  333. </P>
  334. <P CLASS="western" STYLE="margin-bottom: 0in"><B>INFORMATION</B></P>
  335. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in">The
  336. following 3 “getter” functions return task status
  337. (enabled/disabled), execution interval in milliseconds, number of
  338. <I><B>remaining</B></I> iterations.
  339. </P>
  340. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><BR>
  341. </P>
  342. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><B>bool
  343. isEnabled() </B>
  344. </P>
  345. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><B>unsigned
  346. long getInterval()</B></P>
  347. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><B>long
  348. getIterations() </B>
  349. </P>
  350. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><BR>
  351. </P>
  352. <P CLASS="western" STYLE="margin-bottom: 0in"><B>long getOverrun()</B></P>
  353. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in">If
  354. library is compiled with <FONT FACE="Courier New, monospace">_TASK_TIMECRITICAL</FONT>
  355. enabled, tasks are monitored for “long running” scenario. A “long
  356. running” task is a task that does not finish processing its
  357. callback functions quickly, and thus creates a situation for itself
  358. and other tasks where they don't run on a scheduled interval, but
  359. rather “catch up” and are behind. When task scheduler sets the
  360. next execution target time, it adds Task's execution interval to the
  361. previously scheduled execution time:</P>
  362. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"> <B>next
  363. execution time = previous execution time + task execution interval</B></P>
  364. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><BR>
  365. </P>
  366. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in">If
  367. <B>next execution time</B> happens to be already in the past (<B>next
  368. execution time</B> &lt; <B>millis()</B>), then task is considered
  369. <I><B>overrun</B></I>. <B>GetOverrun</B> function returns number of
  370. milliseconds between next execution time and current time. If the
  371. <B>value is negative</B>, the task is overrun by that many
  372. milliseconds.
  373. </P>
  374. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in">Positive
  375. value indicate number of milliseconds of slack this task has for
  376. execution purposes.
  377. </P>
  378. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><BR>
  379. </P>
  380. <P CLASS="western" STYLE="margin-bottom: 0in"><B>unsigned long
  381. getRunCounter()</B></P>
  382. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in">Returns
  383. the number of the current run. “Current run” is the number of
  384. times a callback function has been invoked since the last time a task
  385. was enabled. <BR><BR>
  386. </P>
  387. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><B>NOTE:
  388. </B>The <B>runCounter</B> value is incremented <I>before</I> callback
  389. function is invoked. If a task is checking the <B>runCounter</B>
  390. value within its callback function, then the first run value is 1.
  391. </P>
  392. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in">If
  393. task T1 is checking the <B>runCounter</B> value of another task (T2)
  394. , then value = 0 indicates that T2 has not been invoked yet, and
  395. value = 1 indicates that T2 has run once.
  396. </P>
  397. <P CLASS="western" STYLE="margin-bottom: 0in"><BR>
  398. </P>
  399. <P CLASS="western" STYLE="margin-bottom: 0in"><B>bool
  400. isFirstIteration()</B></P>
  401. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in">Indicates
  402. whether current pass is a first iteration of the task.
  403. </P>
  404. <P CLASS="western" STYLE="margin-bottom: 0in"><B>bool
  405. isLastIteration()</B></P>
  406. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in">For
  407. tasks with a limited number of iterations only, indicates whether
  408. current pass is the last iteration.
  409. </P>
  410. <P CLASS="western" STYLE="margin-bottom: 0in"><BR>
  411. </P>
  412. <P CLASS="western" STYLE="margin-bottom: 0in; page-break-after: avoid">
  413. <B>CONTROL:</B></P>
  414. <P CLASS="western" STYLE="margin-bottom: 0in; page-break-after: avoid">
  415. <BR>
  416. </P>
  417. <P CLASS="western" STYLE="margin-bottom: 0in"><B>void enable();</B></P>
  418. <P CLASS="western" STYLE="margin-bottom: 0in"><BR>
  419. </P>
  420. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in">Enables
  421. the task, and schedules it for immediate execution (without delay) at
  422. this or next scheduling pass depending on when the task was enabled.
  423. Scheduler will execute the next pass without any delay because there
  424. is a task which was enabled and requires execution.
  425. </P>
  426. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><BR>
  427. </P>
  428. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><B>Note:
  429. </B>enable() invokes task’s <B>OnEnable</B> method (if not NULL),
  430. which can prepare task for execution. <B>OnEnable</B> must return a
  431. value of <B>true</B> for task to be enabled. If <B>OnEnable</B>
  432. returns <B>false</B>, task remains disabled. <B>OnEnable</B> is
  433. invoked every time <B>enable</B> is called, regardless if task is
  434. already enabled or not.
  435. </P>
  436. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><BR>
  437. </P>
  438. <P CLASS="western" STYLE="margin-bottom: 0in"><B>bool enableIfNot();</B></P>
  439. <P CLASS="western" STYLE="margin-bottom: 0in"><BR>
  440. </P>
  441. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in">Enables
  442. the task only if it was previously disabled. Returns previous enable
  443. state: <B>true</B> if task was already enabled, and <B>false</B> if
  444. task was disabled.</P>
  445. <P CLASS="western" STYLE="margin-bottom: 0in"><BR>
  446. </P>
  447. <P CLASS="western" STYLE="margin-bottom: 0in"><B>void delay();</B></P>
  448. <P CLASS="western" STYLE="margin-bottom: 0in"><BR>
  449. </P>
  450. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in">Schedules
  451. the task for execution after a delay (aInterval), but does not change
  452. the enabled/disabled status of the task.
  453. </P>
  454. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><BR>
  455. </P>
  456. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><B>Note:
  457. </B>a delay of 0 (zero) will delay task for current execution
  458. interval. Use <B>forceNextIteration() </B>method to force execution
  459. of the task’s callback during immediate next scheduling pass.
  460. </P>
  461. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><BR>
  462. </P>
  463. <P CLASS="western" STYLE="margin-bottom: 0in"><B>void
  464. forceNextIteration();</B></P>
  465. <P CLASS="western" STYLE="margin-bottom: 0in"><BR>
  466. </P>
  467. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in">Schedules
  468. the task for execution during immediate next scheduling pass.</P>
  469. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><BR>
  470. </P>
  471. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><B>Note:
  472. </B>Task’s schedule is adjusted to run from this moment in time.
  473. For instance: if a task was running every 10 seconds: 10, 20, 30, ..,
  474. calling <B>forceNextIteration </B>at 44th second of task execution
  475. will make subsequent schedule look like: 44, 54, 64, 74, ..</P>
  476. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><BR>
  477. </P>
  478. <P CLASS="western" STYLE="margin-bottom: 0in"><B>void
  479. enableDelayed();</B></P>
  480. <P CLASS="western" STYLE="margin-bottom: 0in"><BR>
  481. </P>
  482. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in">Enables
  483. the task, and schedules it for execution after a delay (aInterval).
  484. </P>
  485. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><BR>
  486. </P>
  487. <P CLASS="western" STYLE="margin-bottom: 0in"><B>void enableDelayed
  488. (unsigned long aDelay);</B></P>
  489. <P CLASS="western" STYLE="margin-bottom: 0in"><BR>
  490. </P>
  491. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in">Enables
  492. the task, and schedules it for execution after a specific delay
  493. (aDelay, which maybe different from aInterval).
  494. </P>
  495. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><BR>
  496. </P>
  497. <P CLASS="western" STYLE="margin-bottom: 0in"><B>void restart();</B></P>
  498. <P CLASS="western" STYLE="margin-bottom: 0in"><BR>
  499. </P>
  500. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in">For
  501. tasks with limited number of iterations only, <B>restart</B> function
  502. will re-enable the task, set the number of iterations back to when
  503. the task was created and and schedule the task for execution as soon
  504. as possible.</P>
  505. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><BR>
  506. </P>
  507. <P CLASS="western" STYLE="margin-bottom: 0in"><B>void restartDelayed
  508. (unsigned long aDelay);</B></P>
  509. <P CLASS="western" STYLE="margin-bottom: 0in"><BR>
  510. </P>
  511. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in">Same
  512. as <B>restart() </B>function, with the only difference being that
  513. Task is scheduled to run first iteration after a delay = <B>aDelay</B>
  514. milliseconds.</P>
  515. <P CLASS="western" STYLE="margin-bottom: 0in"><BR>
  516. </P>
  517. <P CLASS="western" STYLE="margin-bottom: 0in"><B>bool disable();</B></P>
  518. <P CLASS="western" STYLE="margin-bottom: 0in"><BR>
  519. </P>
  520. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in">Disables
  521. the task. Scheduler will not execute this task any longer, even if it
  522. remains in the chain. Task can be later re-enabled for execution.
  523. </P>
  524. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in">Return
  525. previous enabled state: <B>true</B> if task was enabled prior to
  526. calling disable, and <B>false</B> otherwise.</P>
  527. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in">If
  528. not NULL, task’s <B>OnDisable</B> method is invoked. <B>OnDisable</B>
  529. is invoked only if task was enabled. Calling <B>disable</B> 3 times
  530. for instance will invoke <B>OnDisable</B> only once.</P>
  531. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><BR>
  532. </P>
  533. <P CLASS="western" STYLE="margin-bottom: 0in"><B>void set(unsigned
  534. long aInterval, long aIterations, void (*aCallback)() , bool
  535. (*aOnEnable)() , void (*aOnDisable)());</B></P>
  536. <P CLASS="western" STYLE="margin-bottom: 0in"><BR>
  537. </P>
  538. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in">Allows
  539. dynamic control of task execution parameters in one function call.
  540. </P>
  541. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><B>Note</B><B>:
  542. </B>OnEnable and OnDisable parameters can be omitted. In that case
  543. they will be assigned to NULL and not called.
  544. </P>
  545. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><BR>
  546. </P>
  547. <P CLASS="western" STYLE="margin-bottom: 0in">Next five “setter”
  548. functions allow changes of individual task execution control
  549. parameters.
  550. </P>
  551. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><B>void
  552. setInterval (unsigned long aInterval) </B>
  553. </P>
  554. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><B>void
  555. setIterations (long aIterations) </B>
  556. </P>
  557. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><B>void
  558. setCallback (void (*aCallback)()) </B>
  559. </P>
  560. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><B>void
  561. setOnEnable (bool (*aCallback)()) </B>
  562. </P>
  563. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><B>void
  564. setOnDisable (void (*aCallback)()) </B>
  565. </P>
  566. <P CLASS="western" STYLE="margin-bottom: 0in"><BR>
  567. </P>
  568. <P CLASS="western" STYLE="margin-bottom: 0in"><B>Note: </B>Next
  569. execution time calculation takes place <B>after</B> the callback
  570. function is called, so new interval will be used immediately by the
  571. scheduler. For the situations when one task is changing the interval
  572. parameter for the other, <B>setInterval</B> function calls <B>delay
  573. </B>explicitly to guarantee schedule change, however it <B>does not
  574. </B>enable the task if task is disabled.</P>
  575. <P CLASS="western" STYLE="margin-bottom: 0in"><B>Note: </B>Tasks that
  576. ran through all their allocated iterations are disabled.
  577. <B>SetIterations()</B> method <B>DOES NOT</B> enable the task. Either
  578. <B>enable</B> explicitly, or use <B>restart</B> methods.
  579. </P>
  580. <P CLASS="western" STYLE="margin-bottom: 0in"><BR>
  581. </P>
  582. <P CLASS="western" STYLE="margin-bottom: 0in"><B>STATUS REQUEST
  583. METHODS:</B></P>
  584. <P CLASS="western" STYLE="margin-bottom: 0in; page-break-after: avoid">
  585. <BR>
  586. </P>
  587. <P CLASS="western" STYLE="margin-bottom: 0in; page-break-after: avoid">
  588. <B>void waitFor(StatusRequest* aStatusRequest);</B></P>
  589. <P CLASS="western" STYLE="margin-bottom: 0in; page-break-after: avoid">
  590. <BR>
  591. </P>
  592. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in">If
  593. compiled with support for Status Requests, this method makes task
  594. wait for the completion of <B>aStatusRequest</B> event.
  595. </P>
  596. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><B>waitFor()
  597. </B>sets tasks interval to <B>0 (zero)</B> for immediate execution
  598. when event happens, and also sets the number of <B>iterations to 1</B>.</P>
  599. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><B>Note:
  600. aStatusRequest</B> should be “activated” by calling <B>setWaiting()
  601. </B>method before making a task wait on it. Otherwise, the task will
  602. execute immediately.
  603. </P>
  604. <P CLASS="western" STYLE="margin-bottom: 0in"><BR>
  605. </P>
  606. <P CLASS="western" STYLE="margin-bottom: 0in"><BR>
  607. </P>
  608. <P CLASS="western" STYLE="margin-bottom: 0in"><B>StatusRequest*
  609. getStatusRequest()</B></P>
  610. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in">Returns
  611. a StatusReqeust object this Task was waiting on.
  612. </P>
  613. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><BR>
  614. </P>
  615. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><BR>
  616. </P>
  617. <P CLASS="western" STYLE="margin-bottom: 0in"><B>TASK ID, CONTROL
  618. POINTS METHODS:</B></P>
  619. <P CLASS="western" STYLE="margin-bottom: 0in; page-break-after: avoid">
  620. <BR>
  621. </P>
  622. <P CLASS="western" STYLE="margin-bottom: 0in; page-break-after: avoid">
  623. <B>void setId(unsigned int aID);</B></P>
  624. <P CLASS="western" STYLE="margin-bottom: 0in; page-break-after: avoid">
  625. <BR>
  626. </P>
  627. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in">If
  628. compiled with support for Task IDs, this method will set the task ID
  629. explicitly.
  630. </P>
  631. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in">Calling
  632. this method is not necessary as task IDs are assigned automatically
  633. during task creation: 1, 2, 3, …</P>
  634. <P CLASS="western" STYLE="margin-bottom: 0in"><BR>
  635. </P>
  636. <P CLASS="western" STYLE="margin-bottom: 0in; page-break-after: avoid">
  637. <B>unsigned int getId();</B></P>
  638. <P CLASS="western" STYLE="margin-bottom: 0in; page-break-after: avoid">
  639. <BR>
  640. </P>
  641. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in">If
  642. compiled with support for Task IDs, this method return current task’s
  643. ID.</P>
  644. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><BR>
  645. </P>
  646. <P CLASS="western" STYLE="margin-bottom: 0in; page-break-after: avoid">
  647. <B>void setControlPoint (unsigned int aPoint);</B></P>
  648. <P CLASS="western" STYLE="margin-bottom: 0in; page-break-after: avoid">
  649. <BR>
  650. </P>
  651. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in">If
  652. compiled with support for Task IDs, this method will set a control
  653. point in the task’s code. Control points are similar to “try…catch”
  654. blocks, with control point ID specifying where in the code the “try”
  655. part started, and a mechanism like watchdog timer providing the
  656. “catch” functionality.</P>
  657. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><BR>
  658. </P>
  659. <P CLASS="western" STYLE="margin-bottom: 0in; page-break-after: avoid">
  660. <B>unsigned int getControlPoint()</B></P>
  661. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in; page-break-after: avoid">
  662. <BR>
  663. </P>
  664. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in; page-break-after: avoid">
  665. If compiled with support for Task IDs, this method will return
  666. currently set control point for this task.</P>
  667. <P CLASS="western" STYLE="margin-bottom: 0in; page-break-after: avoid">
  668. <BR>
  669. </P>
  670. <P CLASS="western" STYLE="margin-bottom: 0in; page-break-after: avoid">
  671. <BR>
  672. </P>
  673. <P CLASS="western" STYLE="margin-bottom: 0in; page-break-after: avoid">
  674. <BR>
  675. </P>
  676. <P CLASS="western" STYLE="margin-bottom: 0in; page-break-inside: avoid; page-break-after: avoid">
  677. <FONT SIZE=4><B>TASK SCHEDULER:</B></FONT></P>
  678. <P CLASS="western" STYLE="margin-bottom: 0in; page-break-inside: avoid; page-break-after: avoid">
  679. <BR>
  680. </P>
  681. <P CLASS="western" STYLE="margin-bottom: 0in; page-break-inside: avoid; page-break-after: avoid">
  682. <B>CREATION:</B></P>
  683. <P CLASS="western" STYLE="margin-bottom: 0in; page-break-inside: avoid; page-break-after: avoid">
  684. <BR>
  685. </P>
  686. <P CLASS="western" STYLE="margin-bottom: 0in"><B>Scheduler()</B><BR><BR>
  687. </P>
  688. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in">Default
  689. constructor.
  690. </P>
  691. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in">Takes
  692. no parameters. Creates task scheduler with default parameters and an
  693. empty task queue.
  694. </P>
  695. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><BR>
  696. </P>
  697. <P CLASS="western" STYLE="margin-bottom: 0in"><B>void init()</B></P>
  698. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><BR>
  699. </P>
  700. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in">Initializes
  701. the task queue and scheduler parameters, Executed as part of
  702. constructor, so don't need to be explicitly called after creation.</P>
  703. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><B>Note:
  704. </B>be default (if compiled with <FONT FACE="Courier New, monospace">_TASK_TIMECRITICAL</FONT>
  705. enabled) scheduler is allowed to put processor to IDLE sleep mode. If
  706. this behavior was changed via <B>allowSleep() </B>function, <B>inti()
  707. </B>will <B>NOT</B> reset allow sleep particular parameter.
  708. </P>
  709. <P CLASS="western" STYLE="margin-bottom: 0in"><BR><B>void
  710. addTask(Task&amp; aTask)</B></P>
  711. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><BR>
  712. </P>
  713. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in">Adds
  714. task aTask to the execution queue (or chain) of tasks by appending it
  715. to the end of the chain. If two tasks are scheduled for execution,
  716. the sequence will match the order in which tasks were appended to the
  717. chain. However, in reality, due to different timing of task
  718. execution, the actual order may be different.
  719. </P>
  720. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><B>Note:
  721. </B>Currently, changing the execution sequence in a chain dynamically
  722. is not supported.
  723. </P>
  724. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in">If
  725. you need to reorder the chain sequence – initialize the scheduler
  726. and re-add the tasks in a different order.
  727. </P>
  728. <P CLASS="western" STYLE="margin-bottom: 0in"><BR><B>void
  729. deleteTask(Task&amp; aTask)</B></P>
  730. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><BR>
  731. </P>
  732. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in">Deletes
  733. task aTask from the execution chain. The chain of remaining tasks is
  734. linked together (i.e</P>
  735. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in">if
  736. original task chain is 1 → 2 → 3 → 4, deleting 3 will result in
  737. 1 → 2 → 4).</P>
  738. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><B>Note:
  739. </B>it is not required to delete a task from the chain. A disabled
  740. task will not be executed anyway, but you save a few microseconds per
  741. scheduling pass by deleting it, since it is not even considered for
  742. execution.
  743. </P>
  744. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in">An
  745. example of proper use of this function would be running some sort of
  746. <B>initialize</B> task in the chain, and then deleting it from the
  747. chain since it only needs to run once.
  748. </P>
  749. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><BR>
  750. </P>
  751. <P CLASS="western" STYLE="margin-bottom: 0in"><B>void allowSleep(bool
  752. aState) </B>
  753. </P>
  754. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><BR>
  755. </P>
  756. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in">Available
  757. in API only if compiled with <FONT FACE="Courier New, monospace">_TASK_TIMECRITICAL</FONT>
  758. enabled. Controls whether scheduler is allowed (<B>aState =true</B>),
  759. or not (<B>aState =false</B>) to put processor into IDLE sleep mode
  760. in case not tasks are scheduled to run.</P>
  761. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in">The
  762. <B>default</B> behavior of scheduler upon creation is to allow sleep
  763. mode.
  764. </P>
  765. <P CLASS="western" STYLE="margin-bottom: 0in"><BR><B>void enableAll()</B></P>
  766. <P CLASS="western" STYLE="margin-bottom: 0in"><B>void disableAll()</B></P>
  767. <P CLASS="western" STYLE="margin-bottom: 0in"><BR>
  768. </P>
  769. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in">enables
  770. and disables (respectively) all tasks in the chain. Convenient if
  771. your need to enable/disable majority of the tasks (i.e. disable all
  772. and then enable one).
  773. </P>
  774. <P CLASS="western" STYLE="margin-bottom: 0in"><BR><B>Task&amp;
  775. currentTask()<BR></B><BR>
  776. </P>
  777. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in">Returns
  778. reference to the task, currently executing via <B>execute()</B> loop.
  779. Could be used by callback functions to identify which of the Tasks
  780. invoked callback function.</P>
  781. <P CLASS="western" STYLE="margin-bottom: 0in"><BR><B>void execute()</B></P>
  782. <P CLASS="western" STYLE="margin-bottom: 0in"><BR>
  783. </P>
  784. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in">Executes
  785. one scheduling pass, including end-of-pass sleep. This function
  786. typically placed inside the <B>loop()</B> function of the sketch.
  787. Since <B>execute</B> exits after every pass, you can put additional
  788. statements after <B>execute</B> inside the <B>loop()</B>
  789. </P>
  790. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><BR>
  791. </P>
  792. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><BR>
  793. </P>
  794. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><BR>
  795. </P>
  796. <P CLASS="western" STYLE="margin-bottom: 0in; page-break-after: avoid">
  797. <B>STATUS REQUEST:</B></P>
  798. <P CLASS="western" STYLE="margin-bottom: 0in; page-break-after: avoid">
  799. <BR>
  800. </P>
  801. <P CLASS="western" STYLE="margin-bottom: 0in; page-break-after: avoid">
  802. <B>CREATION:</B></P>
  803. <P CLASS="western" STYLE="margin-bottom: 0in; page-break-after: avoid">
  804. <BR>
  805. </P>
  806. <P CLASS="western" STYLE="margin-bottom: 0in"><B>StatusRequest()</B><BR><BR>
  807. </P>
  808. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in">Default
  809. constructor.
  810. </P>
  811. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in">Takes
  812. no parameters. Creates Status Request object, which is assigned a
  813. status of “completed” on creation.
  814. </P>
  815. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><BR>
  816. </P>
  817. <P CLASS="western" STYLE="margin-bottom: 0in"><B>void
  818. setWaiting(unsigned int aCount)</B></P>
  819. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in">Activates
  820. Status Request object. By default each object is set to wait on one
  821. event only, however, if <B>aCount</B> is supplied, Status Request can
  822. wait on multiple events. For instance, <B>setWaiting(3)</B> will wait
  823. on three signals. An example could be waiting for completion of
  824. measurements from 3 sensors.
  825. </P>
  826. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><BR>
  827. </P>
  828. <P CLASS="western" STYLE="margin-bottom: 0in"><B>bool signal(int
  829. aStatus)</B></P>
  830. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in">Signals
  831. completion of the event to the Status Request object, and passes a
  832. completion code, which could be interrogated later.
  833. </P>
  834. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><B>Note:
  835. </B> passing a <B>negative</B> status code to the status request
  836. object is considered reporting an error condition, and will complete
  837. the status request regardless of how many outstanding signals it is
  838. still waiting for.
  839. </P>
  840. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><B>Note</B>:
  841. only the latest status code is kept.</P>
  842. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><BR>
  843. </P>
  844. <P CLASS="western" STYLE="margin-bottom: 0in"><B>bool signalComplete
  845. (int aStatus)</B></P>
  846. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in">Signals
  847. completion of <B>ALL</B> events to the Status Request object, and
  848. passes a completion code, which could be interrogated later. The
  849. status request completes regardless of how many events it is still
  850. waiting on.
  851. </P>
  852. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><BR>
  853. </P>
  854. <P CLASS="western" STYLE="margin-bottom: 0in"><B>bool pending() </B>
  855. </P>
  856. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in">Returns
  857. <B>true</B> if status request is still waiting for event or events to
  858. happen.</P>
  859. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><BR>
  860. </P>
  861. <P CLASS="western" STYLE="margin-bottom: 0in"><B>bool completed () </B>
  862. </P>
  863. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in">Returns
  864. <B>true</B> if status has completed.</P>
  865. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><BR>
  866. </P>
  867. <P CLASS="western" STYLE="margin-bottom: 0in"><B>int getStatus()</B></P>
  868. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in">Returns
  869. the status code passed to the status request object by the <B>signal()
  870. </B>and <B>signalComplete() </B>methods.
  871. </P>
  872. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in">Any
  873. <B>positive</B> number is considered a successful completion status.</P>
  874. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in">A
  875. 0 (zero) is considered a default successful completion status.</P>
  876. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in">Any
  877. <B>negative</B> number is considered an error code and unsuccessful
  878. completion of a request.</P>
  879. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><BR>
  880. </P>
  881. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><BR>
  882. </P>
  883. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><BR>
  884. </P>
  885. <P CLASS="western" STYLE="margin-bottom: 0in; page-break-after: avoid">
  886. <B>IMPLEMENTATION SCENARIOS AND IDEAS:</B></P>
  887. <P CLASS="western" STYLE="margin-bottom: 0in"><BR>
  888. </P>
  889. <OL>
  890. <LI><P CLASS="western" STYLE="margin-bottom: 0in"><B>EVENT DRIVEN
  891. PROGRAMMING</B></P>
  892. </OL>
  893. <P CLASS="western" STYLE="margin-bottom: 0in"><BR>
  894. </P>
  895. <P CLASS="western" STYLE="margin-bottom: 0in">Each of the processes
  896. of your application becomes a separate and distinct programming area,
  897. which may or may not interact and control each other.
  898. </P>
  899. <P CLASS="western" STYLE="margin-bottom: 0in"><BR>
  900. </P>
  901. <P CLASS="western" STYLE="margin-bottom: 0in">Example:
  902. </P>
  903. <P CLASS="western" STYLE="margin-bottom: 0in">In a plant watering
  904. system you need to measure soil humidity, control pump and display
  905. the results</P>
  906. <P CLASS="western" STYLE="margin-bottom: 0in">Each of the areas
  907. becomes a task:</P>
  908. <P CLASS="western" STYLE="margin-bottom: 0in"><BR>
  909. </P>
  910. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><FONT FACE="Courier New, monospace"><FONT SIZE=2>Task
  911. <B>tMeasure</B> (TMEASURE_INTERVAL*SECOND, -1,
  912. &amp;measureCallback);<BR>Task <B>tWater</B>
  913. (TWATER_INTERVAL*SECOND, RETRIES, &amp;waterCallback);<BR>Task
  914. <B>tDisplay</B> (TDISPLAY_INTERVAL*SECOND, -1, &amp;displayCallback);
  915. <BR></FONT></FONT><BR>
  916. </P>
  917. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><FONT FACE="Courier New, monospace"><FONT SIZE=2>Scheduler
  918. </FONT></FONT><FONT FACE="Courier New, monospace"><FONT SIZE=2><B>taskManager</B></FONT></FONT><FONT FACE="Courier New, monospace"><FONT SIZE=2>;</FONT></FONT><BR><BR>
  919. </P>
  920. <P CLASS="western" STYLE="margin-bottom: 0in">Further, once you turn
  921. on the pump, you keep it running for TWATER_INTERVAL interval and
  922. then turn it off. Turning off a pump is also a task which only needs
  923. to run once for every time the pump is turned on:</P>
  924. <P CLASS="western" STYLE="margin-bottom: 0in"><BR>
  925. </P>
  926. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><FONT FACE="Courier New, monospace"><FONT SIZE=2>Task
  927. </FONT></FONT><FONT FACE="Courier New, monospace"><FONT SIZE=2><B>tWaterOff</B></FONT></FONT><FONT FACE="Courier New, monospace"><FONT SIZE=2>
  928. (WATERTIME*SECOND, 1,</FONT></FONT><FONT FACE="Courier New, monospace">
  929. &amp;waterOffCallback);</FONT><BR><BR>
  930. </P>
  931. <P CLASS="western" STYLE="margin-bottom: 0in">Example of the callback
  932. function:</P>
  933. <P CLASS="western" STYLE="margin-bottom: 0in"><BR>
  934. </P>
  935. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><FONT FACE="Courier New, monospace"><FONT SIZE=2>void
  936. waterOffCallback() {<BR> motorOff();<BR>
  937. tWater.enableDelayed();<BR>}</FONT></FONT></P>
  938. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><BR>
  939. </P>
  940. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><FONT FACE="Courier New, monospace"><FONT SIZE=2>or</FONT></FONT></P>
  941. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><BR>
  942. </P>
  943. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><FONT FACE="Courier New, monospace"><FONT SIZE=2>void
  944. waterCallback() {<BR> if (tWater.getIterations()) {</FONT></FONT></P>
  945. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><FONT FACE="Courier New, monospace"><FONT SIZE=2>//
  946. If this is not the last iteration = turn the pump on<BR>
  947. motorOn();<BR> tWaterOff.set(parameters.watertime * SECOND, 1,
  948. &amp;waterOffCallback);<BR> tWaterOff.enableDelayed();<BR>
  949. return;<BR> }</FONT></FONT></P>
  950. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><FONT FACE="Courier New, monospace"><FONT SIZE=2>//
  951. We could not reach target humidity – something is wrong<BR>
  952. motorOff;<BR> taskManager.disableAll();<BR> tError.enable();<BR>}</FONT></FONT></P>
  953. <P CLASS="western" STYLE="margin-bottom: 0in"><BR>
  954. </P>
  955. <P CLASS="western" STYLE="margin-bottom: 0in"><FONT FACE="Times New Roman, serif">Your
  956. sample <B>setup</B>() and <B>loop</B>() (partially) are as follows. </FONT>
  957. </P>
  958. <P CLASS="western" STYLE="margin-bottom: 0in"><FONT FACE="Times New Roman, serif"><B>Note:
  959. </B>please note that tWater is <B>not</B> activated during setup().
  960. It is activated by tMeasure callback once the watering conditions are
  961. met. </FONT>
  962. </P>
  963. <P CLASS="western" STYLE="margin-bottom: 0in"><BR>
  964. </P>
  965. <P CLASS="western" STYLE="margin-bottom: 0in"><FONT FACE="Times New Roman, serif"> </FONT><FONT FACE="Courier New, monospace">setup()</FONT></P>
  966. <P CLASS="western" STYLE="margin-bottom: 0in"><FONT FACE="Courier New, monospace">
  967. ...</FONT></P>
  968. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in">
  969. <FONT FACE="Courier New, monospace">tWater.setIterations(parameters.retries);<BR>
  970. tWaterOff.setInterval(parameters.watertime * SECOND);<BR><BR><BR>
  971. taskManager.init();<BR> taskManager.addTask(tMeasure);<BR>
  972. taskManager.addTask(tDisplay);<BR> taskManager.addTask(tWater);<BR>
  973. taskManager.addTask(tWaterOff);<BR> <BR> tMeasure.enable();<BR>
  974. tDisplay.enable();<BR><BR> currentHumidity =
  975. measureHumidity();<BR>}<BR><BR><BR>void loop ()<BR>{<BR>
  976. taskManager.execute();<BR>}</FONT><FONT FACE="Times New Roman, serif"><BR></FONT><BR>
  977. </P>
  978. <OL START=2>
  979. <LI><P CLASS="western" STYLE="margin-bottom: 0in">“<FONT FACE="Times New Roman, serif"><B>NATIVE”
  980. SUPPORT FOR FINITE STATE MACHINE</B></FONT></P>
  981. </OL>
  982. <P CLASS="western" STYLE="margin-bottom: 0in"><BR>
  983. </P>
  984. <P CLASS="western" STYLE="margin-bottom: 0in"><FONT FACE="Times New Roman, serif">Define
  985. “states” as callback function or functions. Each callback
  986. function executes activities specific to a “state” and then
  987. “transitions” to the next state by assigning next callback
  988. function to the task. </FONT>
  989. </P>
  990. <P CLASS="western" STYLE="margin-bottom: 0in"><FONT FACE="Times New Roman, serif">Transition
  991. from one state to the next is achieved by setting next callback
  992. function at the end of preceding one. </FONT>
  993. </P>
  994. <P CLASS="western" STYLE="margin-bottom: 0in"><FONT FACE="Times New Roman, serif"><B>Note:
  995. </B>do not call the next callback function. Let the schedule take
  996. care of that during the next pass. (Thus letting other tasks run). </FONT>
  997. </P>
  998. <P CLASS="western" STYLE="margin-bottom: 0in"><BR>
  999. </P>
  1000. <P CLASS="western" STYLE="margin-bottom: 0in"><FONT FACE="Times New Roman, serif">Example:
  1001. Blinking LED 2 times a second could be achieved this way</FONT></P>
  1002. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><BR>
  1003. </P>
  1004. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><FONT FACE="Courier New, monospace">Task
  1005. tLedBlinker (500, -1, &amp;ledOnCallback);</FONT></P>
  1006. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><FONT FACE="Courier New, monospace">Scheduler
  1007. taskManager;</FONT></P>
  1008. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><BR>
  1009. </P>
  1010. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><FONT FACE="Courier New, monospace">void
  1011. ledOnCallback() {</FONT></P>
  1012. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><FONT FACE="Courier New, monospace"> turnLedOn();</FONT></P>
  1013. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><FONT FACE="Courier New, monospace"> tLedBlinker.setCallback(&amp;ledOffCallback);</FONT></P>
  1014. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><FONT FACE="Courier New, monospace">}</FONT></P>
  1015. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><BR>
  1016. </P>
  1017. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><FONT FACE="Courier New, monospace">void
  1018. ledOffCallback() {</FONT></P>
  1019. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><FONT FACE="Courier New, monospace"> turnLedOff();</FONT></P>
  1020. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><FONT FACE="Courier New, monospace"> tLedBlinker.setCallback(&amp;ledOnCallback);</FONT></P>
  1021. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><FONT FACE="Courier New, monospace">}</FONT></P>
  1022. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><BR>
  1023. </P>
  1024. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><FONT FACE="Courier New, monospace">setup()
  1025. {</FONT></P>
  1026. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><FONT FACE="Courier New, monospace"> taskManager.init();<BR>
  1027. taskManager.addTask(tLedBlinker);</FONT></P>
  1028. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><FONT FACE="Courier New, monospace"> </FONT></P>
  1029. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><FONT FACE="Courier New, monospace"> tLedBlinker.enable();</FONT></P>
  1030. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><FONT FACE="Courier New, monospace">}</FONT></P>
  1031. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><BR>
  1032. </P>
  1033. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><FONT FACE="Courier New, monospace">loop
  1034. () {</FONT></P>
  1035. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><FONT FACE="Courier New, monospace"> taskManager.execute();</FONT></P>
  1036. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><FONT FACE="Courier New, monospace">}</FONT><FONT FACE="Times New Roman, serif"><BR></FONT><BR>
  1037. </P>
  1038. <P CLASS="western" STYLE="margin-bottom: 0in"><FONT FACE="Times New Roman, serif">Obviously
  1039. the example is simple, but gives the idea of how the tasks could be
  1040. used to go through states.</FONT></P>
  1041. <P CLASS="western" STYLE="margin-bottom: 0in"><BR>
  1042. </P>
  1043. <P CLASS="western" STYLE="margin-bottom: 0in"><BR>
  1044. </P>
  1045. <P CLASS="western" STYLE="margin-bottom: 0in"><BR>
  1046. </P>
  1047. <OL START=3>
  1048. <LI><P CLASS="western" STYLE="margin-bottom: 0in"><FONT FACE="Times New Roman, serif"><B>MULTIPLE
  1049. POSSIBLE CALLBACKS FOR TASK</B></FONT></P>
  1050. </OL>
  1051. <P CLASS="western" STYLE="margin-bottom: 0in"><BR>
  1052. </P>
  1053. <P CLASS="western" STYLE="margin-bottom: 0in"><FONT FACE="Times New Roman, serif">There
  1054. may be a need to select an option for callback function based on
  1055. certain criteria, or randomly. </FONT>
  1056. </P>
  1057. <P CLASS="western" STYLE="margin-bottom: 0in"><FONT FACE="Times New Roman, serif">You
  1058. can achieve that by defining an array of callback function pointers
  1059. and selecting one based on the criteria you need. </FONT>
  1060. </P>
  1061. <P CLASS="western" STYLE="margin-bottom: 0in"><FONT FACE="Times New Roman, serif">Example:
  1062. when a robot detects an obstacle, it may go left, right backwards,
  1063. etc. Each of the “directions” or “behaviors” are represented
  1064. by a different callback function. </FONT>
  1065. </P>
  1066. <P CLASS="western" STYLE="margin-bottom: 0in"><BR>
  1067. </P>
  1068. <P CLASS="western" STYLE="margin-bottom: 0in"><FONT FACE="Times New Roman, serif">Another
  1069. example of using multiple callbacks:</FONT></P>
  1070. <P CLASS="western" STYLE="margin-bottom: 0in"><FONT FACE="Times New Roman, serif">You
  1071. may need to “initialize” variables for a particular task.</FONT></P>
  1072. <P CLASS="western" STYLE="margin-bottom: 0in"><FONT FACE="Times New Roman, serif">In
  1073. this case, define a tasks with two callbacks:</FONT></P>
  1074. <P CLASS="western" STYLE="margin-bottom: 0in"><BR>
  1075. </P>
  1076. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><FONT FACE="Courier New, monospace"><FONT SIZE=2>Task
  1077. <B>tWork</B> (T_INTERVAL, -1, &amp;workCallbackInit);</FONT></FONT></P>
  1078. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in">…</P>
  1079. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><BR>
  1080. </P>
  1081. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><FONT FACE="Courier New, monospace"><FONT SIZE=2>void
  1082. workCallbackInit() {</FONT></FONT></P>
  1083. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><FONT FACE="Courier New, monospace"><FONT SIZE=2> //
  1084. do your initializationstuff here</FONT></FONT></P>
  1085. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><FONT FACE="Courier New, monospace"><FONT SIZE=2> </FONT></FONT></P>
  1086. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><FONT FACE="Courier New, monospace"><FONT SIZE=2> //
  1087. finally assigne the main callback function </FONT></FONT>
  1088. </P>
  1089. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><FONT FACE="Courier New, monospace"><FONT SIZE=2> tWork.setCallback(&amp;workCallback);</FONT></FONT></P>
  1090. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><FONT FACE="Courier New, monospace"><FONT SIZE=2>}</FONT></FONT></P>
  1091. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><BR>
  1092. </P>
  1093. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><FONT FACE="Courier New, monospace"><FONT SIZE=2>void
  1094. workCallback() {</FONT></FONT></P>
  1095. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><FONT FACE="Courier New, monospace"><FONT SIZE=2> //
  1096. main callback function</FONT></FONT></P>
  1097. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><FONT FACE="Courier New, monospace"><FONT SIZE=2> …</FONT></FONT></P>
  1098. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><FONT FACE="Courier New, monospace"><FONT SIZE=2>}</FONT></FONT></P>
  1099. <P CLASS="western" STYLE="margin-bottom: 0in"><BR>
  1100. </P>
  1101. <P CLASS="western" STYLE="margin-bottom: 0in"><FONT FACE="Times New Roman, serif">The
  1102. task will initialize during first execution pass and switch to
  1103. “regular” callback execution starting with second pass. There is
  1104. a delay between first and second passes of the task (scheduling
  1105. period, if defined). In order to execute the second pass immediately
  1106. after initialization first pass, change the above code like this:</FONT></P>
  1107. <P CLASS="western" STYLE="margin-bottom: 0in"><BR>
  1108. </P>
  1109. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><FONT FACE="Courier New, monospace"><FONT SIZE=2>void
  1110. workCallbackInit() {</FONT></FONT></P>
  1111. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><FONT FACE="Courier New, monospace"><FONT SIZE=2> //
  1112. do your initializationstuff here</FONT></FONT></P>
  1113. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><FONT FACE="Courier New, monospace"><FONT SIZE=2> </FONT></FONT></P>
  1114. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><FONT FACE="Courier New, monospace"><FONT SIZE=2> //
  1115. finally assigne the main callback function </FONT></FONT>
  1116. </P>
  1117. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><FONT FACE="Courier New, monospace"><FONT SIZE=2> tWork.setCallback(&amp;workCallback);</FONT></FONT></P>
  1118. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><FONT FACE="Courier New, monospace"><FONT SIZE=2> tWork.enable();</FONT></FONT></P>
  1119. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><FONT FACE="Courier New, monospace"><FONT SIZE=2>}</FONT></FONT></P>
  1120. <P CLASS="western" STYLE="margin-bottom: 0in"><BR>
  1121. </P>
  1122. <P CLASS="western" STYLE="margin-bottom: 0in"><FONT FACE="Times New Roman, serif">The
  1123. task will run initialization first, then immediately second pass, and
  1124. then switch to processing at regular intervals starting with a third
  1125. pass. </FONT>
  1126. </P>
  1127. <P CLASS="western" STYLE="margin-bottom: 0in"><BR>
  1128. </P>
  1129. <OL START=3>
  1130. <LI><P CLASS="western" STYLE="margin-bottom: 0in"><FONT FACE="Times New Roman, serif"><B>INTERRUP-DRIVEN
  1131. EXECUTION SUPPORT </B></FONT>
  1132. </P>
  1133. </OL>
  1134. <P CLASS="western" STYLE="margin-bottom: 0in"><BR>
  1135. </P>
  1136. <P CLASS="western" STYLE="margin-bottom: 0in"><FONT FACE="Times New Roman, serif">In
  1137. case of interrupt-driven program flow, tasks could be scheduled to
  1138. run once to request asynchronous execution (request), and then
  1139. re-enabled (restarted) again with a different callback function to
  1140. process the results. </FONT>
  1141. </P>
  1142. <P CLASS="western" STYLE="margin-bottom: 0in"><BR>
  1143. </P>
  1144. <P CLASS="western" STYLE="margin-bottom: 0in"><FONT FACE="Times New Roman, serif"><B>Example</B>:
  1145. event driven distance calculation for ultrasonic pulses. EchoPin #6
  1146. triggers pin change interrupts on rising and falling edges to
  1147. determine the length of ultrasonic pulse.</FONT></P>
  1148. <P CLASS="western" STYLE="margin-bottom: 0in"><BR>
  1149. </P>
  1150. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><FONT FACE="Courier New, monospace"><FONT SIZE=2>#include
  1151. &lt;DirectIO.h&gt;<BR>#include &lt;TaskScheduler.h&gt;<BR>#include
  1152. &lt;PinChangeInt.h&gt;<BR><BR><BR>#define TRIGGERPIN 5<BR>#define
  1153. ECHOPIN 6<BR><BR>Output&lt;TRIGGERPIN&gt;
  1154. pTrigger;<BR>Input&lt;ECHOPIN&gt; pEcho;<BR><BR>Scheduler
  1155. r;<BR><BR>Task tMeasure(1000, -1, &amp;measureCallback, &amp;r,
  1156. true);<BR>Task tDisplay(1000, -1, &amp;displayCallback, &amp;r,
  1157. true);<BR>Task tPing(0, 1, &amp;pingCalcCallback, &amp;r,
  1158. false);<BR><BR><BR>volatile bool pulseBusy = false;<BR>volatile bool
  1159. pulseTimeout = false;<BR>volatile unsigned long pulseStart =
  1160. 0;<BR>volatile unsigned long pulseStop = 0;<BR>volatile unsigned long
  1161. pingDistance = 0;<BR><BR><BR>void pingTrigger(unsigned long aTimeout)
  1162. {<BR> if (pulseBusy) return; // do not trigger if in the middle of
  1163. a pulse<BR> if (pEcho == HIGH) return; // do not trigger if ECHO pin
  1164. is high<BR> <BR> pulseBusy = true;<BR> pulseTimeout = false;</FONT></FONT></P>
  1165. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><FONT FACE="Courier New, monospace"><FONT SIZE=2><BR>
  1166. pTrigger = LOW;<BR> delayMicroseconds(4);<BR> pTrigger = HIGH;<BR><BR>
  1167. tPing.setInterval (aTimeout);<BR><BR> delayMicroseconds(10);<BR>
  1168. pTrigger = LOW; <BR></FONT></FONT><BR>
  1169. </P>
  1170. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in">
  1171. <FONT FACE="Courier New, monospace"><FONT SIZE=2>tPing.restartDelayed();
  1172. // timeout countdown starts now<BR></FONT></FONT><BR>
  1173. </P>
  1174. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><FONT FACE="Courier New, monospace"><FONT SIZE=2>//
  1175. will start the pulse clock on the rising edge of ECHO pin</FONT></FONT></P>
  1176. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in">
  1177. <FONT FACE="Courier New, monospace"><FONT SIZE=2>PCintPort::attachInterrupt(ECHOPIN,
  1178. &amp;pingStartClock, RISING); <BR>}<BR><BR></FONT></FONT><BR>
  1179. </P>
  1180. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><FONT FACE="Courier New, monospace"><FONT SIZE=2>//
  1181. Start clock on the <B>rising</B> edge of the ultrasonic pulse<BR>void
  1182. pingStartClock() {<BR> pulseStart = micros();<BR>
  1183. PCintPort::detachInterrupt(ECHOPIN); // not sure this is necessary<BR>
  1184. PCintPort::attachInterrupt(ECHOPIN, &amp;pingStopClock, FALLING); <BR>
  1185. tPing.restartDelayed();<BR>}<BR><BR>// Stop clock on the <B>falling</B>
  1186. edge of the ultrasonic pulse<BR>void pingStopClock() {<BR> pulseStop
  1187. = micros();<BR> PcintPort::detachInterrupt(ECHOPIN);</FONT></FONT></P>
  1188. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in">
  1189. <FONT FACE="Courier New, monospace"><FONT SIZE=2>pingDistance =
  1190. pulseStop - pulseStart;<BR> pulseBusy = false;<BR> tPing.disable();
  1191. // disable timeout<BR>}<BR></FONT></FONT><BR>
  1192. </P>
  1193. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><FONT FACE="Courier New, monospace"><FONT SIZE=2>//
  1194. Stop clock because of the timeout – the wave did not return<BR>void
  1195. pingCalcCallback() {<BR> if (pulseBusy) {<BR> pingStopClock();<BR>
  1196. }<BR> pulseTimeout = true;<BR>}<BR><BR><BR><BR>// Initial measure
  1197. callback sets the trigger<BR>void measureCallback() {<BR> if
  1198. (pulseBusy) { // already measuring, try again<BR>
  1199. tMeasure.enable();<BR> return;<BR> }<BR> pingTrigger(30); // 30
  1200. milliseconds or max range of ~5.1 meters<BR>
  1201. tMeasure.setCallback(&amp;measureCallbackWait);<BR>}<BR></FONT></FONT><BR>
  1202. </P>
  1203. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><FONT FACE="Courier New, monospace"><FONT SIZE=2>//
  1204. Wait for the measurement to <BR>void measureCallbackWait() {<BR> if
  1205. (pulseBusy) return;<BR> tMeasure.setCallback(&amp;measureCallback);
  1206. <BR>}<BR><BR><BR>bool state = true;<BR><BR>void displayCallback() {<BR>
  1207. char d[256];<BR> <BR> unsigned long cm = pingDistance * 17 / 100;
  1208. // cm<BR> <BR> snprintf(d, 256, &quot;pulseStart =
  1209. %8lu\tpulseStop=%8lu\tdistance, cm=%8lu&quot;, pulseStart, pulseStop,
  1210. cm);<BR> Serial.println(d);<BR> <BR>}<BR><BR>void setup() {<BR> //
  1211. put your setup code here, to run once:<BR> <BR>
  1212. Serial.begin(115200);<BR> <BR><BR> pTrigger = LOW;<BR> pEcho =
  1213. LOW;<BR> <BR>}<BR><BR>void loop() {<BR> // put your main code here,
  1214. to run repeatedly:<BR> r.execute();<BR>}<BR></FONT></FONT><BR>
  1215. </P>
  1216. <OL START=3>
  1217. <LI><P CLASS="western" STYLE="margin-bottom: 0in"><FONT FACE="Times New Roman, serif"><B>USING
  1218. ONENABLE AND ONDISBALE METHODS </B></FONT>
  1219. </P>
  1220. </OL>
  1221. <P CLASS="western" STYLE="margin-bottom: 0in"><BR>
  1222. </P>
  1223. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><FONT FACE="Times New Roman, serif">Consider
  1224. a task to flash onboard LED for 5 seconds with random frequency. Task
  1225. should be repeated every 30 seconds indefinitely. Since frequency is
  1226. random, there are two challenges:</FONT></P>
  1227. <OL START=3>
  1228. <OL>
  1229. <LI><P CLASS="western" STYLE="margin-bottom: 0in"><FONT FACE="Times New Roman, serif">We
  1230. need to make sure LED is turned OFF at the last iteration</FONT></P>
  1231. <LI><P CLASS="western" STYLE="margin-bottom: 0in"><FONT FACE="Times New Roman, serif">We
  1232. need to calculate random frequency every time</FONT></P>
  1233. </OL>
  1234. </OL>
  1235. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><BR>
  1236. </P>
  1237. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><FONT FACE="Times New Roman, serif">Below
  1238. is the implementation using TaskScheduler </FONT>
  1239. </P>
  1240. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><BR>
  1241. </P>
  1242. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><FONT FACE="Courier New, monospace"><FONT SIZE=2><BR></FONT></FONT><BR>
  1243. </P>
  1244. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><FONT FACE="Courier New, monospace"><FONT SIZE=2>#define
  1245. _TASK_SLEEP_ON_IDLE_RUN</FONT></FONT></P>
  1246. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><FONT FACE="Courier New, monospace"><FONT SIZE=2>#include
  1247. &lt;TaskScheduler.h&gt;</FONT></FONT></P>
  1248. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><BR>
  1249. </P>
  1250. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><FONT FACE="Courier New, monospace"><FONT SIZE=2>#define
  1251. LEDPIN 13</FONT></FONT></P>
  1252. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><BR>
  1253. </P>
  1254. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><BR>
  1255. </P>
  1256. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><FONT FACE="Courier New, monospace"><FONT SIZE=2>Scheduler
  1257. ts;</FONT></FONT></P>
  1258. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><BR>
  1259. </P>
  1260. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><FONT FACE="Courier New, monospace"><FONT SIZE=2>Task
  1261. tWrapper(30000, -1, &amp;WrapperCallback, &amp;ts, true);</FONT></FONT></P>
  1262. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><FONT FACE="Courier New, monospace"><FONT SIZE=2>Task
  1263. tBlink(5000, 1, NULL, &amp;ts, false, &amp;BlinkOnEnable,
  1264. &amp;BlinkOnDisable);</FONT></FONT></P>
  1265. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><FONT FACE="Courier New, monospace"><FONT SIZE=2>Task
  1266. tLED(0, -1, NULL, &amp;ts, false, NULL, &amp;LEDOff);</FONT></FONT></P>
  1267. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><BR>
  1268. </P>
  1269. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><FONT FACE="Courier New, monospace"><FONT SIZE=2>void
  1270. WrapperCallback() {</FONT></FONT></P>
  1271. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in">
  1272. <FONT FACE="Courier New, monospace"><FONT SIZE=2>Serial.println(&quot;In
  1273. WrapperCallback&quot;);</FONT></FONT></P>
  1274. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in">
  1275. <FONT FACE="Courier New, monospace"><FONT SIZE=2>tBlink.restartDelayed();
  1276. // LED blinking is initiated </FONT></FONT>
  1277. </P>
  1278. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in">
  1279. <FONT FACE="Courier New, monospace"><FONT SIZE=2>//every
  1280. 30 seconds for 5 seconds</FONT></FONT></P>
  1281. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><FONT FACE="Courier New, monospace"><FONT SIZE=2>}</FONT></FONT></P>
  1282. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><BR>
  1283. </P>
  1284. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><BR>
  1285. </P>
  1286. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><FONT FACE="Courier New, monospace"><FONT SIZE=2>//
  1287. Upon being enabled, tBlink will define the parameters</FONT></FONT></P>
  1288. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><FONT FACE="Courier New, monospace"><FONT SIZE=2>//
  1289. and enable LED blinking task, which actually controls</FONT></FONT></P>
  1290. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><FONT FACE="Courier New, monospace"><FONT SIZE=2>//
  1291. the hardware (LED in this example)</FONT></FONT></P>
  1292. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><FONT FACE="Courier New, monospace"><FONT SIZE=2>bool
  1293. BlinkOnEnable() {</FONT></FONT></P>
  1294. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in">
  1295. <FONT FACE="Courier New, monospace"><FONT SIZE=2>Serial.println(&quot;In
  1296. BlinkOnEnable&quot;);</FONT></FONT></P>
  1297. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in">
  1298. <FONT FACE="Courier New, monospace"><FONT SIZE=2>tLED.setInterval(
  1299. 500 + random(501) );</FONT></FONT></P>
  1300. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in">
  1301. <FONT FACE="Courier New, monospace"><FONT SIZE=2>tLED.setCallback(
  1302. &amp;LEDOn);</FONT></FONT></P>
  1303. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in">
  1304. <FONT FACE="Courier New, monospace"><FONT SIZE=2>tLED.enable();</FONT></FONT></P>
  1305. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><BR>
  1306. </P>
  1307. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in">
  1308. <FONT FACE="Courier New, monospace"><FONT SIZE=2>return true; //
  1309. Task should be enabled</FONT></FONT></P>
  1310. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><FONT FACE="Courier New, monospace"><FONT SIZE=2>}</FONT></FONT></P>
  1311. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><BR>
  1312. </P>
  1313. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><FONT FACE="Courier New, monospace"><FONT SIZE=2>//
  1314. tBlink does not really need a callback function</FONT></FONT></P>
  1315. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><FONT FACE="Courier New, monospace"><FONT SIZE=2>//
  1316. since it just waits for 5 seconds for the first </FONT></FONT>
  1317. </P>
  1318. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><FONT FACE="Courier New, monospace"><FONT SIZE=2>//
  1319. and only iteration to occur. Once the iteration</FONT></FONT></P>
  1320. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><FONT FACE="Courier New, monospace"><FONT SIZE=2>//
  1321. takes place, tBlink is disabled by the Scheduler, </FONT></FONT>
  1322. </P>
  1323. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><FONT FACE="Courier New, monospace"><FONT SIZE=2>//
  1324. thus executing its OnDisable method below.</FONT></FONT></P>
  1325. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><BR>
  1326. </P>
  1327. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><FONT FACE="Courier New, monospace"><FONT SIZE=2>void
  1328. BlinkOnDisable() {</FONT></FONT></P>
  1329. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in">
  1330. <FONT FACE="Courier New, monospace"><FONT SIZE=2>Serial.println(&quot;In
  1331. BlinkOnDisable&quot;);</FONT></FONT></P>
  1332. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in">
  1333. <FONT FACE="Courier New, monospace"><FONT SIZE=2>tLED.disable();</FONT></FONT></P>
  1334. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><FONT FACE="Courier New, monospace"><FONT SIZE=2>}</FONT></FONT></P>
  1335. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><BR>
  1336. </P>
  1337. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><FONT FACE="Courier New, monospace"><FONT SIZE=2>void
  1338. LEDOn () {</FONT></FONT></P>
  1339. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in">
  1340. <FONT FACE="Courier New, monospace"><FONT SIZE=2>Serial.println(&quot;In
  1341. LEDOn&quot;);</FONT></FONT></P>
  1342. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in">
  1343. <FONT FACE="Courier New, monospace"><FONT SIZE=2>digitalWrite(LEDPIN,
  1344. HIGH);</FONT></FONT></P>
  1345. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in">
  1346. <FONT FACE="Courier New, monospace"><FONT SIZE=2>tLED.setCallback(
  1347. &amp;LEDOff);</FONT></FONT></P>
  1348. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><FONT FACE="Courier New, monospace"><FONT SIZE=2>}</FONT></FONT></P>
  1349. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><BR>
  1350. </P>
  1351. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><FONT FACE="Courier New, monospace"><FONT SIZE=2>void
  1352. LEDOff () {</FONT></FONT></P>
  1353. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in">
  1354. <FONT FACE="Courier New, monospace"><FONT SIZE=2>Serial.println(&quot;In
  1355. LEDOff&quot;);</FONT></FONT></P>
  1356. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in">
  1357. <FONT FACE="Courier New, monospace"><FONT SIZE=2>digitalWrite(LEDPIN,
  1358. LOW);</FONT></FONT></P>
  1359. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in">
  1360. <FONT FACE="Courier New, monospace"><FONT SIZE=2>tLED.setCallback(
  1361. &amp;LEDOn);</FONT></FONT></P>
  1362. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><FONT FACE="Courier New, monospace"><FONT SIZE=2>}</FONT></FONT></P>
  1363. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><BR>
  1364. </P>
  1365. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><FONT FACE="Courier New, monospace"><FONT SIZE=2>//
  1366. Note that LEDOff method serves as OnDisable method</FONT></FONT></P>
  1367. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><FONT FACE="Courier New, monospace"><FONT SIZE=2>//
  1368. to make sure the LED is turned off when the tBlink</FONT></FONT></P>
  1369. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><FONT FACE="Courier New, monospace"><FONT SIZE=2>//
  1370. task finishes (or disabled ahead of time)</FONT></FONT></P>
  1371. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><BR>
  1372. </P>
  1373. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><FONT FACE="Courier New, monospace"><FONT SIZE=2>void
  1374. setup() {</FONT></FONT></P>
  1375. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><BR>
  1376. </P>
  1377. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in">
  1378. <FONT FACE="Courier New, monospace"><FONT SIZE=2>Serial.begin(115200);
  1379. </FONT></FONT>
  1380. </P>
  1381. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in">
  1382. <FONT FACE="Courier New, monospace"><FONT SIZE=2>pinMode(LEDPIN,
  1383. OUTPUT); </FONT></FONT>
  1384. </P>
  1385. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><FONT FACE="Courier New, monospace"><FONT SIZE=2>}</FONT></FONT></P>
  1386. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><BR>
  1387. </P>
  1388. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><FONT FACE="Courier New, monospace"><FONT SIZE=2>void
  1389. loop() {</FONT></FONT></P>
  1390. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in">
  1391. <FONT FACE="Courier New, monospace"><FONT SIZE=2>// put your main
  1392. code here, to run repeatedly:</FONT></FONT></P>
  1393. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><BR>
  1394. </P>
  1395. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in">
  1396. <FONT FACE="Courier New, monospace"><FONT SIZE=2>ts.execute();</FONT></FONT></P>
  1397. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><FONT FACE="Courier New, monospace"><FONT SIZE=2>}</FONT></FONT></P>
  1398. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><BR>
  1399. </P>
  1400. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><BR>
  1401. </P>
  1402. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><BR>
  1403. </P>
  1404. <OL START=3>
  1405. <LI><P CLASS="western" STYLE="margin-bottom: 0in"><FONT FACE="Times New Roman, serif"><B>USING
  1406. STATUS REQUEST OBJECTS </B></FONT>
  1407. </P>
  1408. </OL>
  1409. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><BR>
  1410. </P>
  1411. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><FONT FACE="Times New Roman, serif"><FONT SIZE=2 STYLE="font-size: 11pt">This
  1412. test emulates querying 3 sensors once every 10 seconds, each could
  1413. respond with a different delay (ultrasonic sensors for instance) and
  1414. printing a min value of the three when all three have reported their
  1415. values.</FONT></FONT></P>
  1416. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><BR>
  1417. </P>
  1418. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><FONT FACE="Times New Roman, serif"><FONT SIZE=2 STYLE="font-size: 11pt">The
  1419. overall timeout of 1 second is setup as well.</FONT></FONT></P>
  1420. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><FONT FACE="Times New Roman, serif"><FONT SIZE=2 STYLE="font-size: 11pt">An
  1421. error message needs to be printed if a timeout occurred instead of a
  1422. value.</FONT></FONT></P>
  1423. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><BR>
  1424. </P>
  1425. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><BR>
  1426. </P>
  1427. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><FONT FACE="Courier New, monospace"><FONT SIZE=2>#define
  1428. _TASK_SLEEP_ON_IDLE_RUN</FONT></FONT></P>
  1429. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><FONT FACE="Courier New, monospace"><FONT SIZE=2>#define
  1430. _TASK_STATUS_REQUEST</FONT></FONT></P>
  1431. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><BR>
  1432. </P>
  1433. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><FONT FACE="Courier New, monospace"><FONT SIZE=2>#include
  1434. &lt;TaskScheduler.h&gt;</FONT></FONT></P>
  1435. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><BR>
  1436. </P>
  1437. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><FONT FACE="Courier New, monospace"><FONT SIZE=2>StatusRequest
  1438. measure;</FONT></FONT></P>
  1439. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><BR>
  1440. </P>
  1441. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><FONT FACE="Courier New, monospace"><FONT SIZE=2>Scheduler
  1442. ts; </FONT></FONT>
  1443. </P>
  1444. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><BR>
  1445. </P>
  1446. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><FONT FACE="Courier New, monospace"><FONT SIZE=2>Task
  1447. tCycle(10000, -1, &amp;CycleCallback, &amp;ts, true);</FONT></FONT></P>
  1448. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><FONT FACE="Courier New, monospace"><FONT SIZE=2>Task
  1449. tMeasure(1000, 1, &amp;MeasureCallback, &amp;ts, false,
  1450. &amp;MeasureEnable, &amp;MeasureDisable);</FONT></FONT></P>
  1451. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><FONT FACE="Courier New, monospace"><FONT SIZE=2>Task
  1452. tCalculate(&amp;CalcCallback, &amp;ts);</FONT></FONT></P>
  1453. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><FONT FACE="Courier New, monospace"><FONT SIZE=2>Task
  1454. tSensor1(0, 1, &amp;S1Callback, &amp;ts, false, &amp;S1Enable);</FONT></FONT></P>
  1455. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><FONT FACE="Courier New, monospace"><FONT SIZE=2>Task
  1456. tSensor2(0, 1, &amp;S2Callback, &amp;ts, false, &amp;S2Enable);</FONT></FONT></P>
  1457. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><FONT FACE="Courier New, monospace"><FONT SIZE=2>Task
  1458. tSensor3(0, 1, &amp;S3Callback, &amp;ts, false, &amp;S3Enable);</FONT></FONT></P>
  1459. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><BR>
  1460. </P>
  1461. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><BR>
  1462. </P>
  1463. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><FONT FACE="Courier New, monospace"><FONT SIZE=2>long
  1464. distance, d1, d2, d3;</FONT></FONT></P>
  1465. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><BR>
  1466. </P>
  1467. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><FONT FACE="Courier New, monospace"><FONT SIZE=2>void
  1468. CycleCallback() {</FONT></FONT></P>
  1469. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in">
  1470. <FONT FACE="Courier New, monospace"><FONT SIZE=2>Serial.println(&quot;CycleCallback:
  1471. Initiating measurement cycle every 10 seconds&quot;);</FONT></FONT></P>
  1472. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><BR>
  1473. </P>
  1474. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in">
  1475. <FONT FACE="Courier New, monospace"><FONT SIZE=2>tMeasure.restartDelayed();</FONT></FONT></P>
  1476. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><FONT FACE="Courier New, monospace"><FONT SIZE=2>}</FONT></FONT></P>
  1477. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><BR>
  1478. </P>
  1479. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><BR>
  1480. </P>
  1481. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><BR>
  1482. </P>
  1483. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><FONT FACE="Courier New, monospace"><FONT SIZE=2>bool
  1484. MeasureEnable() {</FONT></FONT></P>
  1485. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in">
  1486. <FONT FACE="Courier New, monospace"><FONT SIZE=2>Serial.println(&quot;MeasureEnable:
  1487. Activating sensors&quot;); </FONT></FONT>
  1488. </P>
  1489. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><BR>
  1490. </P>
  1491. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in">
  1492. <FONT FACE="Courier New, monospace"><FONT SIZE=2>distance = 0;</FONT></FONT></P>
  1493. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in">
  1494. <FONT FACE="Courier New, monospace"><FONT SIZE=2>measure.setWaiting(3);
  1495. // Set the StatusRequest to wait for 3 signals. </FONT></FONT>
  1496. </P>
  1497. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in">
  1498. <FONT FACE="Courier New, monospace"><FONT SIZE=2>tCalculate.waitFor(&amp;measure);</FONT></FONT></P>
  1499. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><BR>
  1500. </P>
  1501. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in">
  1502. <FONT FACE="Courier New, monospace"><FONT SIZE=2>tSensor1.restart();</FONT></FONT></P>
  1503. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in">
  1504. <FONT FACE="Courier New, monospace"><FONT SIZE=2>tSensor2.restart();</FONT></FONT></P>
  1505. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in">
  1506. <FONT FACE="Courier New, monospace"><FONT SIZE=2>tSensor3.restart();</FONT></FONT></P>
  1507. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><BR>
  1508. </P>
  1509. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in">
  1510. <FONT FACE="Courier New, monospace"><FONT SIZE=2>return true;</FONT></FONT></P>
  1511. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><FONT FACE="Courier New, monospace"><FONT SIZE=2>}</FONT></FONT></P>
  1512. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><BR>
  1513. </P>
  1514. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><FONT FACE="Courier New, monospace"><FONT SIZE=2>void
  1515. MeasureCallback() {</FONT></FONT></P>
  1516. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in">
  1517. <FONT FACE="Courier New, monospace"><FONT SIZE=2>Serial.println(&quot;MeasureCallback:
  1518. Invoked by calculate task or one second later&quot;); </FONT></FONT>
  1519. </P>
  1520. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><BR>
  1521. </P>
  1522. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in">
  1523. <FONT FACE="Courier New, monospace"><FONT SIZE=2>if
  1524. (measure.pending()) {</FONT></FONT></P>
  1525. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in">
  1526. <FONT FACE="Courier New, monospace"><FONT SIZE=2>tCalculate.disable();</FONT></FONT></P>
  1527. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in">
  1528. <FONT FACE="Courier New, monospace"><FONT SIZE=2>measure.signalComplete(-1);
  1529. // signal error</FONT></FONT></P>
  1530. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in">
  1531. <FONT FACE="Courier New, monospace"><FONT SIZE=2>Serial.println(&quot;MeasureCallback:
  1532. Timeout!&quot;);</FONT></FONT></P>
  1533. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in">
  1534. <FONT FACE="Courier New, monospace"><FONT SIZE=2>}</FONT></FONT></P>
  1535. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in">
  1536. <FONT FACE="Courier New, monospace"><FONT SIZE=2>else {</FONT></FONT></P>
  1537. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in">
  1538. <FONT FACE="Courier New, monospace"><FONT SIZE=2>Serial.print(&quot;MeasureCallback:
  1539. Min distance=&quot;);Serial.println(distance);</FONT></FONT></P>
  1540. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in">
  1541. <FONT FACE="Courier New, monospace"><FONT SIZE=2>}</FONT></FONT></P>
  1542. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><FONT FACE="Courier New, monospace"><FONT SIZE=2>}</FONT></FONT></P>
  1543. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><BR>
  1544. </P>
  1545. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><FONT FACE="Courier New, monospace"><FONT SIZE=2>void
  1546. MeasureDisable() {</FONT></FONT></P>
  1547. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in">
  1548. <FONT FACE="Courier New, monospace"><FONT SIZE=2>Serial.println(&quot;MeasureDisable:
  1549. Cleaning up&quot;); </FONT></FONT>
  1550. </P>
  1551. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in">
  1552. </P>
  1553. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in">
  1554. <FONT FACE="Courier New, monospace"><FONT SIZE=2>tSensor1.disable();</FONT></FONT></P>
  1555. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in">
  1556. <FONT FACE="Courier New, monospace"><FONT SIZE=2>tSensor2.disable();</FONT></FONT></P>
  1557. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in">
  1558. <FONT FACE="Courier New, monospace"><FONT SIZE=2>tSensor3.disable();</FONT></FONT></P>
  1559. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><FONT FACE="Courier New, monospace"><FONT SIZE=2>}</FONT></FONT></P>
  1560. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><BR>
  1561. </P>
  1562. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><BR>
  1563. </P>
  1564. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><FONT FACE="Courier New, monospace"><FONT SIZE=2>void
  1565. CalcCallback() {</FONT></FONT></P>
  1566. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in">
  1567. <FONT FACE="Courier New, monospace"><FONT SIZE=2>Serial.println(&quot;CalcCallback:
  1568. calculating&quot;); </FONT></FONT>
  1569. </P>
  1570. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in">
  1571. <FONT FACE="Courier New, monospace"><FONT SIZE=2>distance = -1;</FONT></FONT></P>
  1572. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in">
  1573. <FONT FACE="Courier New, monospace"><FONT SIZE=2>if (
  1574. measure.getStatus() &gt;= 0) { // only calculate if statusrequest
  1575. ended successfully</FONT></FONT></P>
  1576. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in">
  1577. <FONT FACE="Courier New, monospace"><FONT SIZE=2>distance = d1 &lt;
  1578. d2 ? d1 : d2;</FONT></FONT></P>
  1579. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in">
  1580. <FONT FACE="Courier New, monospace"><FONT SIZE=2>distance = d3 &lt;
  1581. distance ? d3 : distance;</FONT></FONT></P>
  1582. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in">
  1583. <FONT FACE="Courier New, monospace"><FONT SIZE=2>tMeasure.forceNextIteration();</FONT></FONT></P>
  1584. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in">
  1585. <FONT FACE="Courier New, monospace"><FONT SIZE=2>}</FONT></FONT></P>
  1586. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><FONT FACE="Courier New, monospace"><FONT SIZE=2>}</FONT></FONT></P>
  1587. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><BR>
  1588. </P>
  1589. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><BR>
  1590. </P>
  1591. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><FONT FACE="Courier New, monospace"><FONT SIZE=2>/**
  1592. Simulation code for sensor 1</FONT></FONT></P>
  1593. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"> <FONT FACE="Courier New, monospace"><FONT SIZE=2>*
  1594. ----------------------------</FONT></FONT></P>
  1595. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in">
  1596. <FONT FACE="Courier New, monospace"><FONT SIZE=2>*/</FONT></FONT></P>
  1597. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><FONT FACE="Courier New, monospace"><FONT SIZE=2>bool
  1598. S1Enable() {</FONT></FONT></P>
  1599. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in">
  1600. <FONT FACE="Courier New, monospace"><FONT SIZE=2>Serial.print(&quot;S1Enable:
  1601. Triggering sensor1. Delay=&quot;); </FONT></FONT>
  1602. </P>
  1603. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><BR>
  1604. </P>
  1605. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in">
  1606. <FONT FACE="Courier New, monospace"><FONT SIZE=2>tSensor1.setInterval(
  1607. random(1200) ); // Simulating sensor delay, which could go over 1
  1608. second and cause timeout</FONT></FONT></P>
  1609. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in">
  1610. <FONT FACE="Courier New, monospace"><FONT SIZE=2>d1 = 0;</FONT></FONT></P>
  1611. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in">
  1612. </P>
  1613. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in">
  1614. <FONT FACE="Courier New, monospace"><FONT SIZE=2>Serial.println(
  1615. tSensor1.getInterval() );</FONT></FONT></P>
  1616. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in">
  1617. <FONT FACE="Courier New, monospace"><FONT SIZE=2>return true;</FONT></FONT></P>
  1618. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><FONT FACE="Courier New, monospace"><FONT SIZE=2>}</FONT></FONT></P>
  1619. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><BR>
  1620. </P>
  1621. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><FONT FACE="Courier New, monospace"><FONT SIZE=2>void
  1622. S1Callback() {</FONT></FONT></P>
  1623. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in">
  1624. <FONT FACE="Courier New, monospace"><FONT SIZE=2>Serial.print(&quot;S1Callback:
  1625. Emulating measurement. d1=&quot;); </FONT></FONT>
  1626. </P>
  1627. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in">
  1628. <FONT FACE="Courier New, monospace"><FONT SIZE=2>d1 = random(501); //
  1629. pick a value from 0 to 500 &quot;centimeters&quot; simulating a
  1630. measurement </FONT></FONT>
  1631. </P>
  1632. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in">
  1633. <FONT FACE="Courier New, monospace"><FONT SIZE=2>measure.signal();</FONT></FONT></P>
  1634. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in">
  1635. </P>
  1636. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in">
  1637. <FONT FACE="Courier New, monospace"><FONT SIZE=2>Serial.println(d1); </FONT></FONT>
  1638. </P>
  1639. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><FONT FACE="Courier New, monospace"><FONT SIZE=2>}</FONT></FONT></P>
  1640. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><BR>
  1641. </P>
  1642. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><BR>
  1643. </P>
  1644. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><FONT FACE="Courier New, monospace"><FONT SIZE=2>/**
  1645. Simulation code for sensor 2</FONT></FONT></P>
  1646. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"> <FONT FACE="Courier New, monospace"><FONT SIZE=2>*
  1647. ----------------------------</FONT></FONT></P>
  1648. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in">
  1649. <FONT FACE="Courier New, monospace"><FONT SIZE=2>*/</FONT></FONT></P>
  1650. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><FONT FACE="Courier New, monospace"><FONT SIZE=2>bool
  1651. S2Enable() {</FONT></FONT></P>
  1652. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in">
  1653. <FONT FACE="Courier New, monospace"><FONT SIZE=2>Serial.print(&quot;S2Enable:
  1654. Triggering sensor2. Delay=&quot;); </FONT></FONT>
  1655. </P>
  1656. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><BR>
  1657. </P>
  1658. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in">
  1659. <FONT FACE="Courier New, monospace"><FONT SIZE=2>tSensor2.setInterval(
  1660. random(1200) ); // Simulating sensor delay, which could go over 1
  1661. second and cause timeout</FONT></FONT></P>
  1662. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in">
  1663. <FONT FACE="Courier New, monospace"><FONT SIZE=2>d2 = 0;</FONT></FONT></P>
  1664. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><BR>
  1665. </P>
  1666. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in">
  1667. <FONT FACE="Courier New, monospace"><FONT SIZE=2>Serial.println(
  1668. tSensor2.getInterval() );</FONT></FONT></P>
  1669. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in">
  1670. <FONT FACE="Courier New, monospace"><FONT SIZE=2>return true;</FONT></FONT></P>
  1671. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><FONT FACE="Courier New, monospace"><FONT SIZE=2>}</FONT></FONT></P>
  1672. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><BR>
  1673. </P>
  1674. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><FONT FACE="Courier New, monospace"><FONT SIZE=2>void
  1675. S2Callback() {</FONT></FONT></P>
  1676. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in">
  1677. <FONT FACE="Courier New, monospace"><FONT SIZE=2>Serial.print(&quot;S2Callback:
  1678. Emulating measurement. d2=&quot;); </FONT></FONT>
  1679. </P>
  1680. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in">
  1681. <FONT FACE="Courier New, monospace"><FONT SIZE=2>d2 = random(501); //
  1682. pick a value from 0 to 500 &quot;centimeters&quot; simulating a
  1683. measurement</FONT></FONT></P>
  1684. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in">
  1685. <FONT FACE="Courier New, monospace"><FONT SIZE=2>measure.signal();</FONT></FONT></P>
  1686. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><BR>
  1687. </P>
  1688. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in">
  1689. <FONT FACE="Courier New, monospace"><FONT SIZE=2>Serial.println(d2);
  1690. </FONT></FONT>
  1691. </P>
  1692. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><FONT FACE="Courier New, monospace"><FONT SIZE=2>}</FONT></FONT></P>
  1693. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><BR>
  1694. </P>
  1695. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><BR>
  1696. </P>
  1697. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><FONT FACE="Courier New, monospace"><FONT SIZE=2>/**
  1698. Simulation code for sensor 3</FONT></FONT></P>
  1699. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"> <FONT FACE="Courier New, monospace"><FONT SIZE=2>*
  1700. ----------------------------</FONT></FONT></P>
  1701. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in">
  1702. <FONT FACE="Courier New, monospace"><FONT SIZE=2>*/</FONT></FONT></P>
  1703. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><FONT FACE="Courier New, monospace"><FONT SIZE=2>bool
  1704. S3Enable() {</FONT></FONT></P>
  1705. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in">
  1706. <FONT FACE="Courier New, monospace"><FONT SIZE=2>Serial.print(&quot;S3Enable:
  1707. Triggering sensor3. Delay=&quot;); </FONT></FONT>
  1708. </P>
  1709. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><BR>
  1710. </P>
  1711. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in">
  1712. <FONT FACE="Courier New, monospace"><FONT SIZE=2>tSensor3.setInterval(
  1713. random(1200) ); // Simulating sensor delay, which could go over 1
  1714. second and cause timeout</FONT></FONT></P>
  1715. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in">
  1716. <FONT FACE="Courier New, monospace"><FONT SIZE=2>d3 = 0;</FONT></FONT></P>
  1717. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><BR>
  1718. </P>
  1719. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in">
  1720. <FONT FACE="Courier New, monospace"><FONT SIZE=2>Serial.println(
  1721. tSensor3.getInterval() );</FONT></FONT></P>
  1722. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in">
  1723. <FONT FACE="Courier New, monospace"><FONT SIZE=2>return true;</FONT></FONT></P>
  1724. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><FONT FACE="Courier New, monospace"><FONT SIZE=2>}</FONT></FONT></P>
  1725. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><BR>
  1726. </P>
  1727. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><FONT FACE="Courier New, monospace"><FONT SIZE=2>void
  1728. S3Callback() {</FONT></FONT></P>
  1729. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in">
  1730. <FONT FACE="Courier New, monospace"><FONT SIZE=2>Serial.print(&quot;S3Callback:
  1731. Emulating measurement. d3=&quot;); </FONT></FONT>
  1732. </P>
  1733. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in">
  1734. <FONT FACE="Courier New, monospace"><FONT SIZE=2>d3 = random(501); //
  1735. pick a value from 0 to 500 &quot;centimeters&quot; simulating a
  1736. measurement</FONT></FONT></P>
  1737. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in">
  1738. <FONT FACE="Courier New, monospace"><FONT SIZE=2>measure.signal();</FONT></FONT></P>
  1739. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in">
  1740. </P>
  1741. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in">
  1742. <FONT FACE="Courier New, monospace"><FONT SIZE=2>Serial.println(d3); </FONT></FONT>
  1743. </P>
  1744. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><FONT FACE="Courier New, monospace"><FONT SIZE=2>}</FONT></FONT></P>
  1745. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><BR>
  1746. </P>
  1747. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><BR>
  1748. </P>
  1749. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><FONT FACE="Courier New, monospace"><FONT SIZE=2>/**
  1750. Main Arduino code</FONT></FONT></P>
  1751. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"> <FONT FACE="Courier New, monospace"><FONT SIZE=2>*
  1752. Not much is left here - everything is taken care of by the framework</FONT></FONT></P>
  1753. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in">
  1754. <FONT FACE="Courier New, monospace"><FONT SIZE=2>*/</FONT></FONT></P>
  1755. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><FONT FACE="Courier New, monospace"><FONT SIZE=2>void
  1756. setup() {</FONT></FONT></P>
  1757. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><BR>
  1758. </P>
  1759. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in">
  1760. <FONT FACE="Courier New, monospace"><FONT SIZE=2>Serial.begin(115200);</FONT></FONT></P>
  1761. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in">
  1762. <FONT FACE="Courier New, monospace"><FONT SIZE=2>Serial.println(&quot;TaskScheduler
  1763. StatusRequest Sensor Emulation Test. Complex Test.&quot;); </FONT></FONT>
  1764. </P>
  1765. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in">
  1766. <FONT FACE="Courier New, monospace"><FONT SIZE=2>randomSeed(analogRead(A1)+millis());</FONT></FONT></P>
  1767. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><FONT FACE="Courier New, monospace"><FONT SIZE=2>}</FONT></FONT></P>
  1768. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><BR>
  1769. </P>
  1770. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><FONT FACE="Courier New, monospace"><FONT SIZE=2>void
  1771. loop() {</FONT></FONT></P>
  1772. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in">
  1773. </P>
  1774. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in">
  1775. <FONT FACE="Courier New, monospace"><FONT SIZE=2>ts.execute();</FONT></FONT></P>
  1776. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><BR>
  1777. </P>
  1778. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><FONT FACE="Courier New, monospace"><FONT SIZE=2>}</FONT></FONT></P>
  1779. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><BR>
  1780. </P>
  1781. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><BR>
  1782. </P>
  1783. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><BR>
  1784. </P>
  1785. <OL START=3>
  1786. <LI><P CLASS="western" STYLE="margin-bottom: 0in"><FONT FACE="Times New Roman, serif"><B>FUTHER
  1787. INFROMATION</B></FONT></P>
  1788. </OL>
  1789. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><BR>
  1790. </P>
  1791. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><FONT FACE="Courier New, monospace"><FONT SIZE=2>Please
  1792. refer to examples, provided with TaskScheduler package for further
  1793. information and implementation options.</FONT></FONT></P>
  1794. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><BR>
  1795. </P>
  1796. <P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><FONT FACE="Courier New, monospace"><FONT SIZE=2>Real
  1797. time examples of TaskScheduler are available here:</FONT></FONT></P>
  1798. <OL>
  1799. <LI><P CLASS="western" STYLE="margin-bottom: 0in"><FONT FACE="Courier New, monospace"><FONT SIZE=2><FONT COLOR="#0000ff"><U><A HREF="http://www.instructables.com/id/APIS-Automated-Plant-Irrigation-System/">http://www.instructables.com/id/APIS-Automated-Plant-Irrigation-System/</A></U></FONT></FONT></FONT></P>
  1800. <LI><P CLASS="western" STYLE="margin-bottom: 0in"><FONT FACE="Courier New, monospace"><FONT SIZE=2><FONT COLOR="#0000ff"><U><A HREF="http://www.instructables.com/id/Wave-your-hand-to-control-OWI-Robotic-Arm-no-strin/">http://www.instructables.com/id/Wave-your-hand-to-control-OWI-Robotic-Arm-no-strin/</A></U></FONT></FONT></FONT></P>
  1801. <LI><P CLASS="western" STYLE="margin-bottom: 0in"><FONT FACE="Courier New, monospace"><FONT SIZE=2><FONT COLOR="#0000ff"><U><A HREF="http://www.instructables.com/id/Arduino-Nano-based-Hexbug-Scarab-Robotic-Spider">http://www.instructables.com/id/Arduino-Nano-based-Hexbug-Scarab-Robotic-Spider</A></U></FONT></FONT></FONT></P>
  1802. </OL>
  1803. <P CLASS="western" STYLE="margin-bottom: 0in"><BR>
  1804. </P>
  1805. </BODY>
  1806. </HTML>