| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297 |
- <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
- <html>
- <head>
- <meta http-equiv="content-type" content="text/html; charset=utf-8">
- <title></title>
- <meta name="generator" content="LibreOffice 4.2.8.2 (Linux)">
- <meta name="created" content="20150206;163000000000000">
- <meta name="changedby" content="Anatoli Arkhipenko">
- <meta name="changed" content="20161222;100000000000">
- <style type="text/css">
- <!--
- @page { margin: 0.79in }
- p { margin-bottom: 0.08in; direction: ltr; color: #000000; widows: 0; orphans: 0 }
- p.western { font-family: "Liberation Serif", "MS PMincho", serif; font-size: 12pt; so-language: en-US }
- p.cjk { font-family: "WenQuanYi Micro Hei", "MS Mincho"; font-size: 12pt; so-language: zh-CN }
- p.ctl { font-family: "Lohit Hindi", "MS Mincho"; font-size: 12pt; so-language: hi-IN }
- a:link { color: #0000ff }
- -->
- </style>
- </head>
- <body lang="en-US" text="#000000" link="#0000ff" bgcolor="#ffffff" dir="ltr" style="background: #ffffff">
- <p class="western" style="margin-bottom: 0in"><font size="4" style="font-size: 15pt"><b>Task
- Scheduler</b></font></p>
- <p class="western" style="margin-bottom: 0in"><b>Cooperative
- multitasking for Arduino microcontrollers</b></p>
- <p class="western" style="margin-bottom: 0in; border-top: none; border-bottom: 1px solid #000000; border-left: none; border-right: none; padding-top: 0in; padding-bottom: 0.01in; padding-left: 0in; padding-right: 0in">
- <font size="2" style="font-size: 11pt"><b>Version 2.2.1: 2016-12-20</b></font></p>
- <p class="western" style="margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-bottom: 0in"><b>OVERVIEW</b>:</p>
- <p class="western" style="margin-bottom: 0in">A lightweight
- implementation of cooperative multitasking (task scheduling)
- supporting:</p>
- <ol>
- <li><p class="western" style="margin-bottom: 0in">Periodic task
- execution, with dynamic execution period in <b>milliseconds
- (</b>default<b>)</b> or <b>microseconds (</b>if explicitly enabled<b>)</b>
- – frequency of execution</p>
- <li><p class="western" style="margin-bottom: 0in">Number of
- iterations (limited or infinite number of iterations)</p>
- <li><p class="western" style="margin-bottom: 0in">Execution of tasks
- in predefined sequence</p>
- <li><p class="western" style="margin-bottom: 0in">Dynamic change of
- task execution parameters (frequency, number of iterations, callback
- methods)</p>
- <li><p class="western" style="margin-bottom: 0in">Power saving via
- entering IDLE sleep mode when tasks are not scheduled to run</p>
- <li><p class="western" style="margin-bottom: 0in">Support for
- event-driven task invocation via Status Request object</p>
- <li><p class="western" style="margin-bottom: 0in">Support for task
- IDs and Control Points for error handling and watchdog timer</p>
- <li><p class="western" style="margin-bottom: 0in">Support for Local
- Task Storage pointer (allowing use of same callback code for
- multiple tasks)</p>
- <li><p class="western" style="margin-bottom: 0in">Support for
- layered task prioritization</p>
- </ol>
- <p class="western" style="margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-bottom: 0in">Scheduling overhead:
- between 15 and 18 microseconds per scheduling pass (Arduino UNO rev 3
- @ 16MHz clock, single scheduler w/o prioritization)</p>
- <p class="western" style="margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-bottom: 0in"><b>TASK</b>:</p>
- <p class="western" style="margin-bottom: 0in">“Task” is an
- action, a part of the program logic, which requires scheduled
- execution. A concept of Task combines the following aspects:</p>
- <ol>
- <li><p class="western" style="margin-bottom: 0in">Program code
- performing specific activities (callback methods)</p>
- <li><p class="western" style="margin-bottom: 0in">Execution interval</p>
- <li><p class="western" style="margin-bottom: 0in">Number of
- execution iterations</p>
- <li><p class="western" style="margin-bottom: 0in">(Optionally)
- Execution start event (Status Request)</p>
- <li><p class="western" style="margin-bottom: 0in">(Optionally)
- Pointer to a Local Task Storage area</p>
- </ol>
- <p class="western" style="margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-bottom: 0in"><b>Tasks</b> perform
- certain functions, which could require periodic or one-time
- execution, update of specific variables, or waiting for specific
- events. Tasks also could be controlling specific hardware, or
- triggered by hardware interrupts.
- </p>
- <p class="western" style="margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-bottom: 0in">For execution purposes
- <b>Tasks</b> are linked into execution <b>chains</b>, which are
- processed by the <b>Scheduler</b> in the order they were added
- (linked together).</p>
- <p class="western" style="margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-bottom: 0in"><b>Starting with
- version 2.0.0 TaskScheduler supports task prioritization. Please
- refer to the specific chapter of this manual for details on layered
- prioritization. </b>
- </p>
- <p class="western" style="margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-bottom: 0in">Each task performs its
- function via a callback method. Scheduler calls Task’s callback
- method periodically until task is disabled or runs out of iterations.
- In addition to “regular” callback method, two additional methods
- could be utilized for each task: a callback method invoked every time
- the task is enabled, and a callback method invoked once when the task
- is disabled. Those two special methods allow tasks to properly
- initiate themselves for execution, and clean-up after execution is
- over (E.g., setup pin modes on enable, and always bring pin level to
- LOW at the end).
- </p>
- <p class="western" style="margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-bottom: 0in">Tasks are responsible
- for supporting <b>cooperative</b> <b>multitasking</b> by being “good
- neighbors”, i.e., running their callback methods quickly in a
- non-blocking way, and releasing control back to scheduler as soon as
- possible.
- </p>
- <p class="western" style="margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-bottom: 0in"><b>Scheduler</b> is
- executing Tasks' callback methods in the order the tasks were added
- to the chain, from first to last. Scheduler stops and exists after
- processing the chain once in order to allow other statements in the
- main code of <b>loop()</b> method to run. This is referred to as a
- <b>“scheduling pass”.</b></p>
- <p class="western" style="margin-bottom: 0in">(Normally, there is no
- need to have any other statements in the <b>loop</b>() method other
- than the Scheduler's <b>execute</b>() method).</p>
- <p class="western" style="margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-bottom: 0in; page-break-after: avoid">
- <b>Below is the flowchart of a Task lifecycle:</b></p>
- <p class="western" style="margin-bottom: 0in"><img src="data:image/png;base64,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VmEiIiKyTpIk3qVLkNqkItWWDVGoZlcDLX0C4ejidtvPnzt1QjXP++NMFkKCgzEkoo/aB5E14zOciIiIqJx8fX3VJkni0kl8f/xGtGjnpzqJn0w/iCN7ElDtfzfQPSSYydxkUxhkEBEREVWQtow2MzMTsXFbsWr+Gni0boPwXmFcXks2iUEGERERkYlIdShJEpeNyJYxyCAiIiIiIpNikEFERERERCbFIIOIiIiIiEyKQQYREREREZkUgwwiIiIiIjIpBhlERERERGRSDDKIiIiIiMikGGQQEREREZFJMcggIiIiIiKTYpBBREREREQmxSCDiIiIiIhMikEGERERERGZFIMMojK6fPkyEhMT9R4GERGZMVdXV7UR2SoGGURltH37dhVorFq1Su+hEBGRmZKLUefOndN7GES6YZBBVEbXr1/HzJkzERoaqvdQiIjITN1xxx16D4FIVwwyiIiIiIjIpBhkEBERERGRSTHIICIiIiIik2KQQVQOYWFheg+ByOyMHTtW5SsRERExyCAqh+joaCZ+ExmJiYnBlClT9B4GERGZCQYZRERERERkUgwyiIiIiIjIpBhkEBERERGRSTHIICIiIiIik2KQQUREREREJsUgg4iIiIiITIpBBhERERERmRSDDCIiIiIiMikGGUREREREZFIMMoiIiIiIyKQYZBARERERkUkxyCAiIiIiIpNikEFERERERCbFIIOIiIiIiEyKQQYREREREZkUgwwiIiIiIjIpBhlERERERGRSDDKIiIiIiMikGGQQEREREZFJMcggIiIiIiKTYpBBREREREQmxSCDiIiIiIhMikEGUQkWLFiAL7/8Mt9tY8eOhYODg/p66NChePrpp/UYGhEREZFZYpBBVAJfX18888wz+W5LSkoyfO3s7Mwgg4iIiMgIgwyiEgQEBKhA4tixY7fdZ2dnh48++kiHURERERGZLwYZRKWwZMkS9OzZ87bbx40bZ1g2RURERES3MMggKoV7770Xjo6OyMrKMtwmsxhTpkzRcVRERERE5olBBlEpLV26NN9shsxi2Nvb6zgiIiIiIvPEIIOolIxnM6pXr85ZDCIiIqIiMMggKgNJ8h44cCD++c9/chaDiIiIqAgMMqjU5s6bh6xTp/Qehu7atm2L7OxszmTkcWzcGKMjI/UeBhEREZkZBhlUahJg9B/1qt7D0B3/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wCpCBgAAAACrCBkAAAAArCJkAAAAALCKkAEAAADAKkIGAAAAAKsIGQAAAACsImQAAAAAsIqQAQAAAMAqQgYAAAAAqwgZAAAAAKwiZAAAAACwipABAAAAwCpCBgAAAACrCBkAAAAArCJkAAAAALCKkAEAAADAKkIGAAAAAKsIGQAAAACsImQAAAAAsIqQAQAAAMAqQgYAAAAAqwgZAAAAAKwiZAAAAACwipABAAAAwCpCBgAAAACrCBkAAAAArCJkAAAAALCKkAEAAADAKkIGAAAAAKsIGQAAAACsImQAAAAAsIqQAQAAAMAqQgYAAAAAqwgZAAAAAKwiZAAAAACwipABAAAAwCpCBgAAAACrCBkAAAAArCJkAAAAALCKkAEAAADAKkIGAAAAAKsIGQAAAACsImQAAAAAsIqQAQAAAMAqQgYAAAAAqwgZAAAAAKwiZAAAAACwipABAAAAwCpCBgAAAACrCBkAAAAArCJkAAAAALCKkAEAAADAKkIGAAAAAKsIGQAAAACsImQAAAAAsIqQAQAAAMAqQgYAAAAAqwgZAAAAAKwiZAAAAACwipABAAAAwCpCBgAAAACrCBkAAAAArPr/wUsVjSCfiXgAAAAASUVORK5CYII=" name="Image1" align="bottom" width="664" height="517" border="0"></p>
- <p class="western" style="margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-bottom: 0in"><b>TaskScheduler</b>
- library maybe compiled with different compilation controls
- enabled/disabled. This is a way to limit TaskScheduler functionality
- (and size) for specific purpose (sketch). This is achieved by
- defining specific #<b>define</b> parameters <i>before</i>
- TaskScheduler.h header file. Specifically:</p>
- <p class="western" style="margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-bottom: 0in">If compiled with
- <font face="Courier New, monospace">_TASK_SLEEP_ON_IDLE_RUN</font>
- enabled, the scheduler will place processor into IDLE sleep mode (for
- approximately 1 ms, as the timer interrupt will wake it up), after
- what is determined to be an “idle” pass. An Idle Pass is a pass
- through the task chain when no Tasks were scheduled to run their
- callback methods. This is done to avoid repetitive idle passes
- through the chain when no tasks need to be executed. If any of the
- tasks in the chain always requires immediate execution (aInterval =
- 0), then there will be no IDLE sleep between task's callback method
- execution.</p>
- <p class="western" style="margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-bottom: 0in"><b>NOTE: </b>Task
- Scheduler uses <b>millis()</b> (or <b>micros()</b>) to determine if
- tasks are ready to be invoked. Therefore, if you put your device to
- any “deep” sleep mode disabling timer interrupts, the
- <b>millis()/micros()</b> count will be suspended, leading to
- effective suspension of scheduling. Upon wake up, active tasks need
- to be re-enabled, which will effectively reset their internal time
- scheduling variables to the new value of <b>millis()/micros(). </b>Time
- spent in deep sleep mode should be considered “frozen”, i.e., if
- a task was scheduled to run in 1 second from now, and device was put
- to sleep for 5 minutes, upon wake up, the task will still be
- scheduled 1 second from the time of wake up. Executing <b>enable()
- </b>method on this tasks will make it run as soon as possible. This
- is a concern only for tasks which are required to run in a truly
- periodical manner (in absolute time terms).
- </p>
- <p class="western" style="margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-bottom: 0in">In addition to
- time-only (<b>millis()/micros</b>() only) invocation, tasks can be
- scheduled to wait on an event employing StatusRequest objects (more
- about Status Requests later).</p>
- <p class="western" style="margin-bottom: 0in">Consider a scenario
- when one task (t1) is performing a function which affects execution
- of many tasks (t2, t3). In this case the task t1 will “signal”
- completion of its function via Status Request object. Tasks t2 and t3
- are “waiting” on the same Status Request object. As soon as
- status request completes, t2 and t3 are activated.</p>
- <p class="western" style="margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-bottom: 0in">Alternative scenario is
- the ne task (t1) and waiting for the completion of a number of tasks
- (t2, t3). When done, t2 and t3 signal completion of their functions,
- t1 is invoked.
- </p>
- <p class="western" style="margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-bottom: 0in">Please see the code
- examples at the end of this document, and included with the library
- package for details.</p>
- <p class="western" style="margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-bottom: 0in"><b>COMPILE PARAMETERS:</b></p>
- <p class="western" style="margin-bottom: 0in">This library could be
- compiled in several configurations.</p>
- <p class="western" style="margin-bottom: 0in">Parameters (<b>#define</b>s)
- defining what functionality should or should not be included need be
- defined before the library header file in the body of Arduino sketch.</p>
- <p class="western" style="margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-bottom: 0in">#define <b>_TASK_MICRO_RES</b></p>
- <p class="western" style="margin-bottom: 0in">...will compile the
- library with microsecond scheduling resolution, instead of default
- millisecond resolution.</p>
- <p class="western" style="margin-bottom: 0in">All time parameters for
- execution interval, delay, etc. will be treated as <b>microseconds</b>,
- instead of milliseconds.
- </p>
- <p class="western" style="margin-bottom: 0in"><b>NOTE: </b>Sleep mode
- <b>SLEEP_MODE_IDLE</b> (see below) is automatically <b>disabled</b>
- for microsecond resolution. Time constants <b>TASK_SECOND,
- TASK_MINUTE</b> and <b>TASK_HOUR</b> are adjusted for microsecond
- duration.
- </p>
- <p class="western" style="margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-bottom: 0in">#define
- <b>_TASK_TIMECRITICAL</b></p>
- <p class="western" style="margin-bottom: 0in">...will compile the
- library with time critical tracking option enabled.</p>
- <p class="western" style="margin-bottom: 0in">Time critical option
- keeps track when current execution took place relative to when it was
- scheduled, and where next execution time of the task falls. Two
- methods provide this information.
- </p>
- <p class="western" style="margin-bottom: 0in"><b>Task::getStartDelay()
- </b>method: return number of milliseconds (or microseconds) between
- current system time (millis/micros) and point in time when the task
- was scheduled to start. A value of 0 (zero) indicates that task
- started right on time per schedule.
- </p>
- <p class="western" style="margin-bottom: 0in"><b>Task::getOverrun()</b>
- method: If <b>getOverrun </b>returns a negative value, this Task’s
- next execution time point is <i>already</i> in the past, and task is
- behind schedule. This most probably means that either task’s
- callback method's runtime is too long, or the execution interval is
- too short (and therefore schedule is too aggressive).</p>
- <p class="western" style="margin-bottom: 0in">A positive value
- indicates that task is on schedule, and callback methods have enough
- time to finish before the next scheduled pass.
- </p>
- <p class="western" style="margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-bottom: 0in">#define
- <b>_TASK_SLEEP_ON_IDLE_RUN</b></p>
- <p class="western" style="margin-bottom: 0in">...will compile the
- library with the <b>sleep</b> option enabled (AVR boards only).</p>
- <p class="western" style="margin-bottom: 0in">When enabled, scheduler
- will put the microcontroller into <b>SLEEP_MODE_IDLE</b> state if
- none of the tasks’ callback methods were activated during execution
- pass. <b>IDLE</b> state is interrupted by timers once every 1 ms.
- Putting microcontroller to IDLE state helps conserve power. Device
- in SLEEP_MODE_IDLE wakes up to all hardware and timer interrupts, so
- scheduling is kept current.</p>
- <p class="western" style="margin-bottom: 0in"><b>NOTE: </b>This
- compilation option is not available with the microsecond resolution
- option.</p>
- <p class="western" style="margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-bottom: 0in; page-break-after: avoid">
- #define <b>_TASK_STATUS_REQUEST</b></p>
- <p class="western" style="margin-bottom: 0in">…will compile
- TaskScheduler with support for StatusRequest object. Status Requests
- are objects allowing tasks to wait on an event, and signal event
- completion to each other.
- </p>
- <p class="western" style="margin-bottom: 0in"><b>NOTE: </b> tas of
- version 2.2.1 each task has internal StatusRequest object, which
- triggered active at the moment Task is enabled, and triggered
- complete at the moment the task is disabled. These events could be
- used by other Tasks for event-driven execution</p>
- <p class="western" style="margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-bottom: 0in">#define <b>_TASK_WDT_IDS</b></p>
- <p class="western" style="margin-bottom: 0in">…will compile
- TaskScheduler with support for Task IDs and Control Points. Each task
- can be (and is by default) assigned an ID, which could be used to
- identify the task in case there is a problem with it. Furthermore
- within the task, Control Points could be defined to further help with
- pinpointing potential problem areas. For instance, the tasks which
- deal with external resources (sensors, serial communications,
- anything hardware dependent) can be blocked (or hung), by failed
- hardware. In this case, a watchdog timer could be employed to trap
- such a failed task, and identify which one (by task id) and where in
- the task (by a control point) the problem is likely located.</p>
- <p class="western" style="margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-bottom: 0in"><b>NOTE: </b>by
- default, talk IDs are assigned sequentially (1, 2, 3, …) to the
- tasks as they are being created. Programmer can assign a specific
- task id. <b>Task ids are unsigned integers.</b></p>
- <p class="western" style="margin-bottom: 0in">Control points provide
- a way to identify potential problem points within a task. Control
- points are <b>unsigned integers </b>as well. Please note that there
- is only one control point per task, and it is set to zero when the
- task’s callback method is invoked (this is done to prevent “stray”
- control point from previous task(s) confusing the matters.</p>
- <p class="western" style="margin-bottom: 0in">Example #7 contains a
- test of task ID and control points functionality.
- </p>
- <p class="western" style="margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-bottom: 0in">#define
- <b>_TASK_LTS_POINTER</b></p>
- <p class="western" style="margin-bottom: 0in">…will compile
- TaskScheduler with support for Local Task Storage pointer (LTS). LTS
- is a generic (void*) pointer which could be set to reference a
- variable or a structure specific to a particular task. A callback
- method can get access to specific variables by getting reference to a
- currently running task from the scheduler, and then casting (void*)
- LTS pointer to the appropriate pointer type.
- </p>
- <p class="western" style="margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-bottom: 0in"><b>NOTE: </b>above
- parameters are<b> DISABLED </b>by default, and need to be explicitly
- enabled by placing appropriate #define statements in front of the
- #include statement for the TaskScheduler header file.</p>
- <p class="western" style="margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-bottom: 0in">#define <b>_TASK_PRIORITY</b></p>
- <p class="western" style="margin-bottom: 0in">…will compile
- TaskScheduler with support for layered task prioritization. Task
- prioritization is achieved by creating several schedulers, and
- organizing them in priority layers. Tasks are assigned to schedulers
- corresponding to their priority. Tasks assigned to the “higher”
- layers are evaluated for invocation more frequently, and are given
- priority in execution in case of the scheduling coincidence. More
- about layered prioritization in the API documentation and
- TaskScheduler examples.
- </p>
- <p class="western" style="margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-bottom: 0in"><b>TASK PRIORITY AND
- COOPERATIVE MULTITASKING:</b></p>
- <p class="western" style="margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-bottom: 0in">Starting with version
- 2.0.0 TaskScheduler supports task prioritization. Priority is
- associated with a <b>Scheduler</b>, not individual <b>Tasks</b>,
- hence the concept of priority layers. Tasks subsequently are assigned
- to schedulers corresponding to their desired priority. The lowest
- priority Scheduler is called “<b>base scheduler</b>” or “<b>base
- layer</b>”. Let’s call higher priority schedulers by their
- priority number, with larger number corresponding to higher priority
- of task execution.
- </p>
- <p class="western" style="margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-bottom: 0in">Task prioritization is
- achieved by executing the entire chain of tasks of the higher
- priority scheduler for every single step (task) of the lower priority
- chain. <b>Note</b> that actual callback method invocation depends on
- priority <b>and </b>the timing of task schedule. However, higher
- priority tasks are evaluated more frequently and are given priority
- in case of scheduling collision.
- </p>
- <p class="western" style="margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-bottom: 0in">For most tasks
- TaskScheduler <b>does not need </b>task priority functionality.
- Prioritization requires additional scheduling overhead, and should be
- used only for critical tasks.</p>
- <p class="western" style="margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-bottom: 0in">A few points on that:</p>
- <p class="western" style="margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-bottom: 0in">1. Plain (non-layered)
- execution chain is simple and efficient. The main idea is to minimize
- scheduling overhead by Scheduler going through the chain. Each
- priority layer adds scheduling overhead to overall task chain
- execution. Let’s review 3 scenarios:</p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><b>I.
- Flat chain of 7 tasks:</b></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">Scheduling
- evaluation sequence:</p>
- <p class="western" align="center" style="margin-left: 0.49in; margin-bottom: 0in">
- 1 <font face="Wingdings"></font> 2 <font face="Wingdings"></font>
- 3 <font face="Wingdings"></font> 4 <font face="Wingdings"></font>
- 5 <font face="Wingdings"></font> 6 <font face="Wingdings"></font>
- 7</p>
- <p class="western" align="center" style="margin-left: 0.49in; margin-bottom: 0in">
- <br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">Scheduling
- overhead:</p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">O
- = B * T = 7 * 18 = 126 microseconds,</p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">Where:</p>
- <p class="western" style="margin-left: 0.98in; margin-bottom: 0in">O
- – scheduling overhead</p>
- <p class="western" style="margin-left: 0.98in; margin-bottom: 0in">B
- – number of tasks in the base layer</p>
- <p class="western" style="margin-left: 0.98in; margin-bottom: 0in">T
- – scheduling overhead of a single task execution evaluation
- (currently with Arduino Uno running at 16 Mhz is between 15 and 18
- microseconds).</p>
- <p class="western" style="margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><b>II.
- Two priority layers of 7 tasks. </b>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><b> </b>Tasks
- 1, 2, 3, 4, 5 are base priority and 6, 7 are higher priority:</p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">Scheduling
- evaluation sequence:</p>
- <p class="western" align="center" style="margin-left: 0.49in; margin-bottom: 0in">
- 6 <font face="Wingdings"></font> 7 <font face="Wingdings"></font>
- 1 <font face="Wingdings"></font> 6 <font face="Wingdings"></font>
- 7 <font face="Wingdings"></font> 2 <font face="Wingdings"></font>
- 6 <font face="Wingdings"></font> 7 <font face="Wingdings"></font>
- 3 <font face="Wingdings"></font> 6 <font face="Wingdings"></font>
- 7 <font face="Wingdings"></font> 4 <font face="Wingdings"></font>
- 6 <font face="Wingdings"></font> 7 <font face="Wingdings"></font>
- 5</p>
- <p class="western" align="center" style="margin-left: 0.49in; margin-bottom: 0in">
- <br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">Scheduling
- overhead:</p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">O
- = (B + B * P1) * T = (5 + 5 * 2) * 18 = 270 microseconds,</p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">Where:</p>
- <p class="western" style="margin-left: 0.98in; margin-bottom: 0in">O
- – scheduling overhead</p>
- <p class="western" style="margin-left: 0.98in; margin-bottom: 0in">B
- – number of tasks in the base layer</p>
- <p class="western" style="margin-left: 0.98in; margin-bottom: 0in">P1
- – number of tasks in the priority 1 layer</p>
- <p class="western" style="margin-left: 0.98in; margin-bottom: 0in">T
- – scheduling overhead of a single task execution evaluation
- (currently with Arduino Uno running at 16 Mhz is between 15 and 18
- microseconds).</p>
- <p class="western" style="margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><b>III.
- Three priority layers of 7 tasks. </b>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><b> </b>Tasks
- 1, 2, 3, are base priority, 4, 5 are priority 1, and 6, 7 are
- priority 2:</p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">Scheduling
- evaluation sequence:</p>
- <p class="western" align="center" style="margin-left: 0.49in; margin-bottom: 0in">
- 6 <font face="Wingdings"></font> 7 <font face="Wingdings"></font>
- 4 <font face="Wingdings"></font> 6 <font face="Wingdings"></font>
- 7 <font face="Wingdings"></font> 5 <font face="Wingdings"></font>
- 1 <font face="Wingdings"></font> 6 <font face="Wingdings"></font>
- 7 <font face="Wingdings"></font> 4 <font face="Wingdings"></font>
- 6 <font face="Wingdings"></font> 7 <font face="Wingdings"></font>
- 5 <font face="Wingdings"></font> 2 <font face="Wingdings"></font>6
- <font face="Wingdings"></font> 7 <font face="Wingdings"></font>
- 4 <font face="Wingdings"></font> 6 <font face="Wingdings"></font>
- 7 <font face="Wingdings"></font> 5 <font face="Wingdings"></font>
- 3
- </p>
- <p class="western" align="center" style="margin-left: 0.49in; margin-bottom: 0in">
- <br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">Scheduling
- overhead:</p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">O
- = (B + B * P1 + B * P1 * P2) * T = (3 + 3 * 2 + 3 * 2 * 2) * 18 = 378
- microseconds,</p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">Where:</p>
- <p class="western" style="margin-left: 0.98in; margin-bottom: 0in">O
- – scheduling overhead</p>
- <p class="western" style="margin-left: 0.98in; margin-bottom: 0in">B
- – number of tasks in the base layer</p>
- <p class="western" style="margin-left: 0.98in; margin-bottom: 0in">P1
- – number of tasks in the priority 1 layer</p>
- <p class="western" style="margin-left: 0.98in; margin-bottom: 0in">P2
- – number of tasks in the priority 2 layer</p>
- <p class="western" style="margin-left: 0.98in; margin-bottom: 0in">T
- – scheduling overhead of a single task execution evaluation
- (currently with Arduino Uno running at 16 Mhz is between 15 and 18
- microseconds).</p>
- <p class="western" style="margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-bottom: 0in">Scheduling overhead of
- a 3 layer prioritization approach is 3 times higher than that of a
- flat execution chain. <b>Do</b> evaluate if task prioritization is
- really required for your sketch.</p>
- <p class="western" style="margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-bottom: 0in">2. TaskScheduler is <b>NOT</b>
- a pre-emptive multi-tasking library. Nor is it a Real-Time OS. There
- is no way to break execution of one task in favor of another.
- Therefore callback methods require careful programming for
- cooperative behavior.</p>
- <p class="western" style="margin-bottom: 0in">This has, however,
- significant benefits: you don't need to worry about concurrency
- inside the callback method, since only one callback method runs at a
- time, and could not be interrupted. All resources are yours for that
- period of time, no one can switch the value of variables (except
- interrupt functions of course...), etc. It is a stable and
- predictable environment, and it helps a lot with writing stable code.
- </p>
- <p class="western" style="margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-bottom: 0in">A number of things
- could be done instead of priorities:</p>
- <p class="western" style="margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-bottom: 0in">1. Schedule your
- critical tasks to run more frequently than the other tasks</p>
- <p class="western" style="margin-bottom: 0in">. <br>(Since you can
- control the interval, you could also change the task to run more or
- less frequently as the situation demands).</p>
- <p class="western" style="margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-bottom: 0in">2. If one particular
- callback routine is critical, create a couple of tasks referring to
- the same callback and "sprinkle" them around the chain:</p>
- <p class="western" style="margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-bottom: 0in"> <font face="FreeMono, MS Mincho, monospace"><font size="2" style="font-size: 10pt">Scheduler
- ts;</font></font></p>
- <p class="western" style="margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-bottom: 0in"> <font face="FreeMono, MS Mincho, monospace"><font size="2" style="font-size: 10pt">Task
- t1(20, TASK_FOREVER, &callback1, &ts);</font></font></p>
- <p class="western" style="margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-bottom: 0in"> <font face="FreeMono, MS Mincho, monospace"><font size="2" style="font-size: 10pt">Task
- t2(1000, TASK_FOREVER, &callback2, &ts);</font></font></p>
- <p class="western" style="margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-bottom: 0in"> <font face="FreeMono, MS Mincho, monospace"><font size="2" style="font-size: 10pt">Task
- t3(20, TASK_FOREVER, &callback1, &ts);</font></font></p>
- <p class="western" style="margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-bottom: 0in"> <font face="FreeMono, MS Mincho, monospace"><font size="2" style="font-size: 10pt">Task
- t4(1000, TASK_FOREVER, &callback4, &ts);</font></font></p>
- <p class="western" style="margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-bottom: 0in"> <font face="FreeMono, MS Mincho, monospace"><font size="2" style="font-size: 10pt">t3.delay(10);</font></font></p>
- <p class="western" style="margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-bottom: 0in">Note that t1 and t3
- call the same callback method, and are shifted in time by 10 millis.
- So effectively callback1 will be called every 10 millis, but would be
- "sandwiched" between t2 and t4.
- </p>
- <p class="western" style="margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-bottom: 0in">3. Use short efficient
- callback methods written for cooperative multitasking.</p>
- <p class="western" style="margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-bottom: 0in">What that means is:</p>
- <p class="western" style="margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">a)
- <b>DO NOT</b> use Arduino's <font face="FreeMono, MS Mincho, monospace"><font size="2" style="font-size: 10pt"><b>delay</b></font></font><font face="FreeMono, MS Mincho, monospace"><font size="2" style="font-size: 10pt">()</font></font><font face="Andale Mono, MS Mincho">
- </font>function. It is blocking and will hold the entire chain.
- Instead break the callback method into two, switch the callback
- method of the task where delay is necessary and delay the task by
- that number of millis. You get your delay, and other tasks get a
- chance to run:</p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">instead
- of:</p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">
- <font face="FreeMono, MS Mincho, monospace"><font size="2" style="font-size: 10pt">void
- callback() {</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">
- <font face="FreeMono, MS Mincho, monospace"><font size="2" style="font-size: 10pt">...
- stuff</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">
- <font face="FreeMono, MS Mincho, monospace"><font size="2" style="font-size: 10pt">delay(1000);</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">
- <font face="FreeMono, MS Mincho, monospace"><font size="2" style="font-size: 10pt">...
- more stuff</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">
- <font face="FreeMono, MS Mincho, monospace"><font size="2" style="font-size: 10pt">}</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">
-
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">do
- this:</p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">
- <font face="FreeMono, MS Mincho, monospace"><font size="2" style="font-size: 10pt">void
- callback1() {</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">
- <font face="FreeMono, MS Mincho, monospace"><font size="2" style="font-size: 10pt">...
- stuff</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">
- <font face="FreeMono, MS Mincho, monospace"><font size="2" style="font-size: 10pt">t1.setCallback(&callback2);</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">
- <font face="FreeMono, MS Mincho, monospace"><font size="2" style="font-size: 10pt">t1.delay(1000);</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">
- <font face="FreeMono, MS Mincho, monospace"><font size="2" style="font-size: 10pt">}</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">
- <font face="FreeMono, MS Mincho, monospace"><font size="2" style="font-size: 10pt">void
- callback2() {</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">
- <font face="FreeMono, MS Mincho, monospace"><font size="2" style="font-size: 10pt">...
- more stuff</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">
- <font face="FreeMono, MS Mincho, monospace"><font size="2" style="font-size: 10pt">t1.setCallback(&callback1);</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">
- <font face="FreeMono, MS Mincho, monospace"><font size="2" style="font-size: 10pt">}</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">b)
- Same goes to <font face="FreeMono, MS Mincho, monospace"><font size="2" style="font-size: 10pt"><b>pulseIn</b></font></font><font face="FreeMono, MS Mincho, monospace"><font size="2" style="font-size: 10pt">()</font></font>
- function. If you have to use it, set the timeout parameter such that
- it is not a default 1 second. PulseIn functionality could be achieved
- via pin interrupts, and that solution is non-blocking.</p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">c)
- Do don run long loops (for or do/while) in you callback methods. Make
- the main arduino loop be the loop driver for you:</p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">instead
- of:</p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">
- <font face="FreeMono, MS Mincho, monospace"><font size="2" style="font-size: 10pt">void
- callback() {</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">
-
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">
- <font face="FreeMono, MS Mincho, monospace"><font size="2" style="font-size: 10pt">for(int
- i=0; i<1000; i++) {</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">
- <font face="FreeMono, MS Mincho, monospace"><font size="2" style="font-size: 10pt">...
- stuff // one loop action</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">
- <font face="FreeMono, MS Mincho, monospace"><font size="2" style="font-size: 10pt">}</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">
- <font face="FreeMono, MS Mincho, monospace"><font size="2" style="font-size: 10pt">}</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">do
- this:</p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">
- <font face="FreeMono, MS Mincho, monospace"><font size="2" style="font-size: 10pt">Task
- t1(TASK_IMMEDIATE, 1000, &callback);</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">
-
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">
- <font face="FreeMono, MS Mincho, monospace"><font size="2" style="font-size: 10pt">void
- callback() {</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">
- <font face="FreeMono, MS Mincho, monospace"><font size="2" style="font-size: 10pt">int
- i = t1.getRunCounter() -1;</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">
- <font face="FreeMono, MS Mincho, monospace"><font size="2" style="font-size: 10pt">...
- stuff // one loop action</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">
- <font face="FreeMono, MS Mincho, monospace"><font size="2" style="font-size: 10pt">}</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">or
- this:</p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">
- <font face="FreeMono, MS Mincho, monospace"><font size="2" style="font-size: 10pt">Task
- t1(TASK_IMMEDIATE, 1000, &callback, true, &t1On);</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">
-
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">
- <font face="FreeMono, MS Mincho, monospace"><font size="2" style="font-size: 10pt">int
- i;</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">
- <font face="FreeMono, MS Mincho, monospace"><font size="2" style="font-size: 10pt">bool
- t1On() {</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">
- <font face="FreeMono, MS Mincho, monospace"><font size="2" style="font-size: 10pt">i
- = 0;</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">
- <font face="FreeMono, MS Mincho, monospace"><font size="2" style="font-size: 10pt">return
- true;</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">
- <font face="FreeMono, MS Mincho, monospace"><font size="2" style="font-size: 10pt">}</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">
-
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">
- <font face="FreeMono, MS Mincho, monospace"><font size="2" style="font-size: 10pt">void
- callback() {</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">
- <font face="FreeMono, MS Mincho, monospace"><font size="2" style="font-size: 10pt">...
- stuff // one loop action</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">
- <font face="FreeMono, MS Mincho, monospace"><font size="2" style="font-size: 10pt">i++;</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">
- <font face="FreeMono, MS Mincho, monospace"><font size="2" style="font-size: 10pt">}</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" align="center" style="margin-left: 0.49in; margin-bottom: 0in">
- <b>REMEMBER: you are already inside the loop - take advantage of it. </b>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">d)
- Break long running callback methods into several shorter ones, and
- pass control from one to the other via <font face="FreeMono, MS Mincho, monospace"><font size="2" style="font-size: 10pt"><b>setCallback</b></font></font><font face="FreeMono, MS Mincho, monospace"><font size="2" style="font-size: 10pt">()
- </font></font>method:</p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">
- <font face="FreeMono, MS Mincho, monospace"><font size="2" style="font-size: 10pt">Task
- t1(TASK_IMMEDIATE, TASK_FAREVER, &callback);</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">
-
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">
- <font face="FreeMono, MS Mincho, monospace"><font size="2" style="font-size: 10pt">void
- callback() {</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">
- <font face="FreeMono, MS Mincho, monospace"><font size="2" style="font-size: 10pt">...
- do some stuff</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">
- <font face="FreeMono, MS Mincho, monospace"><font size="2" style="font-size: 10pt">t1.setCallback(&callback_step2);</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">
- <font face="FreeMono, MS Mincho, monospace"><font size="2" style="font-size: 10pt">}</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">
- <font face="FreeMono, MS Mincho, monospace"><font size="2" style="font-size: 10pt">void
- callback_step2() {</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">
- <font face="FreeMono, MS Mincho, monospace"><font size="2" style="font-size: 10pt">...
- do more stuff</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">
- <font face="FreeMono, MS Mincho, monospace"><font size="2" style="font-size: 10pt">t1.setCallback(&callback_step3);</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">
- <font face="FreeMono, MS Mincho, monospace"><font size="2" style="font-size: 10pt">}</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">
- <font face="FreeMono, MS Mincho, monospace"><font size="2" style="font-size: 10pt">void
- callback_step3() {</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">
- <font face="FreeMono, MS Mincho, monospace"><font size="2" style="font-size: 10pt">...
- do last part of the stuff</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">
- <font face="FreeMono, MS Mincho, monospace"><font size="2" style="font-size: 10pt">t1.setCallback(&callback);</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">
- <font face="FreeMono, MS Mincho, monospace"><font size="2" style="font-size: 10pt">t1.delay(1000);</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">
- <font face="FreeMono, MS Mincho, monospace"><font size="2" style="font-size: 10pt">}</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">This
- will execute all parts of the callback function in three successive
- steps, scheduled immediately, but allowing other tasks in the chain
- to run. Notice that task is scheduled to run immediately, and 1
- second period is achieved by delaying the task for 1000 millis at the
- last step.
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">Alternatively
- you could schedule the task to run every 1000 millis and use
- <font face="FreeMono, MS Mincho, monospace"><font size="2" style="font-size: 10pt">forceNextIteration()</font></font>
- method in steps 1 and 2 (but not 3!)</p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">
- <font face="FreeMono, MS Mincho, monospace"><font size="2" style="font-size: 10pt">Task
- t1(1000, TASK_FOREVER, &callback);</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">
-
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">
- <font face="FreeMono, MS Mincho, monospace"><font size="2" style="font-size: 10pt">void
- callback() {</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">
- <font face="FreeMono, MS Mincho, monospace"><font size="2" style="font-size: 10pt">...
- do some stuff</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">
- <font face="FreeMono, MS Mincho, monospace"><font size="2" style="font-size: 10pt">t1.setCallback(&callback_step2);</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">
- <font face="FreeMono, MS Mincho, monospace"><font size="2" style="font-size: 10pt">t1.forceNextIteration();</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">
- <font face="FreeMono, MS Mincho, monospace"><font size="2" style="font-size: 10pt">}</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">
- <font face="FreeMono, MS Mincho, monospace"><font size="2" style="font-size: 10pt">void
- callback_step2() {</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">
- <font face="FreeMono, MS Mincho, monospace"><font size="2" style="font-size: 10pt">...
- do more stuff</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">
- <font face="FreeMono, MS Mincho, monospace"><font size="2" style="font-size: 10pt">t1.setCallback(&callback_step3);</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">
- <font face="FreeMono, MS Mincho, monospace"><font size="2" style="font-size: 10pt">t1.forceNextIteration();</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">
- <font face="FreeMono, MS Mincho, monospace"><font size="2" style="font-size: 10pt">}</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">
- <font face="FreeMono, MS Mincho, monospace"><font size="2" style="font-size: 10pt">void
- callback_step3() {</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">
- <font face="FreeMono, MS Mincho, monospace"><font size="2" style="font-size: 10pt">...
- do last part of the stuff</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">
- <font face="FreeMono, MS Mincho, monospace"><font size="2" style="font-size: 10pt">t1.setCallback(&callback);</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">
- <font face="FreeMono, MS Mincho, monospace"><font size="2" style="font-size: 10pt">}</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">e)
- Compile the library with <font face="FreeMono, MS Mincho, monospace"><font size="2" style="font-size: 10pt"><b>_TASK_TIMECRITICAL</b></font></font>
- enabled and check if your tasks are falling behind schedule. If they
- are - you need to optimize your code further (or maybe re-evaluate
- your schedule). If they are not - all is well and you don't need to
- do anything. E.g., I have a spider robot which needs to measure
- distance, control motors, and keep track of the angle via querying
- gyroscope and accelerometer every 10 ms. The idea was to flash
- onboard LED if any of the tasks fall behind. At 10 ms interval for
- the gyro the LED does not flash, which means none of the tasks are
- blocking the others from starting on time.
- </p>
- <p class="western" style="margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-bottom: 0in; page-break-after: avoid">
- <font size="4" style="font-size: 14pt"><b>API DOCUMENTATION:</b></font></p>
- <p class="western" style="margin-bottom: 0in; page-break-after: avoid">
- <br>
- </p>
- <p class="western" style="margin-bottom: 0in; page-break-after: avoid">
- <font size="4" style="font-size: 14pt"><b>TASKS:</b></font></p>
- <p class="western" style="margin-bottom: 0in; page-break-after: avoid">
- <br>
- </p>
- <p class="western" style="margin-bottom: 0in">CREATION:</p>
- <p class="western" style="margin-bottom: 0in"><b>Task();</b></p>
- <p class="western" style="margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">Default
- constructor.
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">Takes
- no parameters and creates a task that could be scheduled to run at
- every scheduling pass indefinitely, but does not have a callback
- method defined, so no code execution will actually take place.
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">All
- tasks are created <b>disabled</b> by default.</p>
- <p class="western" style="margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-bottom: 0in; page-break-after: avoid">
- <b>Task(unsigned long aInterval, long aIterations, void
- (*aCallback)(), Scheduler* aScheduler, bool aEnable, bool
- (*aOnEnable)(), void (*aOnDisable)())</b></p>
- <p class="western" style="margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">Constructor
- with parameters.
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">Creates
- a task that is scheduled to run every <aInterval> milliseconds,
- <aIterations> times, executing <aCallback> method on
- every pass.
- </p>
- <ol>
- <li><p class="western" style="margin-bottom: 0in">aInterval is in
- milliseconds (or microseconds) (<b>default = 0)</b></p>
- <li><p class="western" style="margin-bottom: 0in">aIteration in
- number of times, -1 for indefinite execution (<b>default = -1)</b><br><b>Note:
- </b>Tasks do not remember the number of iteration set initially.
- After the iterations are done, internal iteration counter is 0. If
- you need to perform another set of iterations, you need to set the
- number of iterations again. <br><b>Note: </b>Tasks which performed
- all their iterations remain active.
- </p>
- <li><p class="western" style="margin-bottom: 0in">aCallback is a
- pointer to a void callback method without parameters (<b>default =
- NULL)</b></p>
- <li><p class="western" style="margin-bottom: 0in">aScheduler –
- <b>optional</b> reference to existing scheduler. If supplied (not
- NULL) this task will be appended to the task chain of the current
- scheduler). (<b>default = NULL)</b></p>
- <li><p class="western" style="margin-bottom: 0in">aEnable –
- <b>optional</b>. Value of <b>true </b>will create task enabled.
- (<b>default = false)</b></p>
- <li><p class="western" style="margin-bottom: 0in">aOnEnable is a
- pointer to a bool callback method without parameters, invoked when
- task is enabled. If OnEnable method returns <b>true</b>, task is
- enabled. If <b>OnEnable</b> method return <b>false</b>, task remains
- disabled (<b>default = NULL)</b></p>
- <li><p class="western" style="margin-bottom: 0in">aOnDisable is a
- pointer to a void callback method without parameters, invoked when
- task is disabled (<b>default = NULL)</b></p>
- </ol>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">All
- tasks are created <b>disabled</b> by default (unless <b>aEnable</b> =
- true). You have to explicitly enable the task for execution.</p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><b>NOTE:
- </b>OnEnable callback method is called immediately when task is
- enabled, which could be well ahead of the scheduled execution time of
- the task. Please bear that in mind – other tasks, hardware, serial
- interface may not even be initialized yet. It is always advisable to
- explicitly enable tasks with OnEnable methods after all
- initialization methods completed (e.g., at the end of <b>setup</b>()
- method)
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">Enabled
- task is scheduled for execution as soon as the Scheduler's <b>execute</b>()
- methods gets control. In order to delay first run of the task, use
- <b>enableDelayed</b> or <b>delay</b> method (for enabled tasks)
- method.</p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-bottom: 0in; page-break-after: avoid">
- <b>Task(void (*aCallback)(), Scheduler* aScheduler, bool
- (*aOnEnable)(), void (*aOnDisable)())</b></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">If
- compiled with support for Status Request objects, this constructor
- creates a Task for activation on event (since such tasks must run
- <b>waitFor() </b>method, their <i>interval</i>, <i>iteration</i> and
- <i>enabled</i> status will be set by that method (<i>to 0, 1 and
- false</i> respectively).</p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-bottom: 0in"><b>INFORMATION</b></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">The
- following 3 “getter” methods return task status
- (enabled/disabled), execution interval in milliseconds, number of
- <i><b>remaining</b></i> iterations.
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><b>bool
- isEnabled() </b>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><b>unsigned
- long getInterval()</b></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><b>long
- getIterations() </b>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-bottom: 0in"><b>long getStartDelay()</b></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">If
- library is compiled with <font face="Courier New, monospace">_TASK_TIMECRITICAL</font>
- enabled, you can assess how much later the callback method was
- invoked against when it was scheduled to be invoked. The return value
- of <b>getStartDelay () </b>method provides this information in
- milliseconds (or microseconds).
- </p>
- <p class="western" style="margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-bottom: 0in"><b>long getOverrun()</b></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">If
- library is compiled with <font face="Courier New, monospace">_TASK_TIMECRITICAL</font>
- enabled, tasks are monitored for “long running” scenario. A “long
- running” task is a task that does not finish processing its
- callback methods quickly, and thus creates a situation for itself and
- other tasks where they don't run on a scheduled interval, but rather
- “catch up” and are behind. When task scheduler sets the next
- execution target time, it adds Task's execution interval to the
- previously scheduled execution time:</p>
- <p class="western" align="center" style="margin-left: 0.49in; margin-bottom: 0in">
- <b>next execution time = current execution scheduled time + task
- execution interval</b></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">If
- <b>next execution time</b> happens to be already in the past (<b>next
- execution time</b> < <b>millis()</b>), then task is considered
- <i><b>overrun</b></i>. <b>GetOverrun</b> method returns number of
- milliseconds between next execution time and current time. If the
- <b>value is negative</b>, the task has overrun (cut into the) next
- execution interval by that many milliseconds.
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">Positive
- value indicate number of milliseconds (or microseconds) of slack this
- task has for execution purposes.
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-bottom: 0in"><b>unsigned long
- getRunCounter()</b></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">Returns
- the number of the current run. “Current run” is the number of
- times a callback method has been invoked since the last time a task
- was enabled. <br><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><b>NOTE:
- </b>The <b>runCounter</b> value is incremented <i>before</i> callback
- method is invoked. If a task is checking the <b>runCounter</b> value
- within its callback method, then the first run value is 1.
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">If
- task T1 is checking the <b>runCounter</b> value of another task (T2)
- , then value = 0 indicates that T2 has not been invoked yet, and
- value = 1 indicates that T2 has run once.
- </p>
- <p class="western" style="margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-bottom: 0in"><b>bool
- isFirstIteration()</b></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">Indicates
- whether current pass is (or will be) a first iteration of the task.
- </p>
- <p class="western" style="margin-bottom: 0in"><b>bool
- isLastIteration()</b></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">For
- tasks with a l<i>imited number of iterations only</i>, indicates
- whether current pass is the last iteration.
- </p>
- <p class="western" style="margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-bottom: 0in; page-break-after: avoid">
- <b>CONTROL:</b></p>
- <p class="western" style="margin-bottom: 0in; page-break-after: avoid">
- <br>
- </p>
- <p class="western" style="margin-bottom: 0in"><b>void enable();</b></p>
- <p class="western" style="margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">Enables
- the task, and schedules it for immediate execution (without delay) at
- this or next scheduling pass depending on when the task was enabled.
- Scheduler will execute the next pass without any delay because there
- is a task which was enabled and requires execution.
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><b>NOTE:
- </b>if task being enabled is not assigned to a scheduler and is not
- part of execution chain, then task <b>will not</b> be enabled.</p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><b>NOTE:
- </b>enable() invokes task’s <b>OnEnable</b> method (if not NULL)
- <b>immediately</b>, which can prepare task for execution. <b>OnEnable</b>
- must return a value of <b>true</b> for task to be enabled. If
- <b>OnEnable</b> returns <b>false</b>, task remains disabled.
- <b>OnEnable</b> is invoked every time <b>enable</b> is called,
- regardless if task is already enabled or not. Alignment to current
- millis() is performed after <b>OnEnable</b> exits, so any changes to
- the interval inside <b>OnEnable</b> is taken into consideration.</p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">TaskScheduler
- allows tasks to be added to the a Scheduler and enabled at the time
- of creation. <b>Be very careful</b> with such tasks – the <b>OnEnable
- </b>method will be executed immediately, while certain objects (i.e.,
- other Tasks, libraries) are not yet ready (e.g., <b>Wire.begin()</b>
- was not yet called), or hardware not yet activated (pins not set to
- INPUT or OUTPUT).
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">It
- is very much recommended to to enable all tasks at the end of <b>setup()</b>
- method after all initializations are done.
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">If
- you require immediate execution of already enabled task, use
- <b>forceNextIteratoin</b>() method instead of <b>enable</b>(): it
- achieves the result, but does not call <b>OnEnable</b> method.
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><b>NOTE:</b>
- in the event <b>enable</b>() method is called inside the <b>OnEnable</b>
- callback method (thus basically creating indefinte loop),
- TaskScheduler will only call <b>OnEnable</b> once (thus protecting
- the Task against <b>OnEnable</b> infinite loop).
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><b>NOTE:
- </b>internal StatusRequest object will be set waiting for an event
- when Task is enabled (if TaskScheduler is compiled with support for
- StatusRequests). StatusRequest object is set waiting <b>after </b>the
- call to onEnable() method of the Task (if defined). Consequently, any
- Task#2 that is expected to wait on this Task’s internal
- StatusRequest should do it only <b>after </b>this task is enabled.
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-bottom: 0in; page-break-after: avoid">
- <b>bool enableIfNot();</b></p>
- <p class="western" style="margin-bottom: 0in; page-break-after: avoid">
- <br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">Enables
- the task only if it was previously disabled. Returns previous enable
- state: <b>true</b> if task was already enabled, and <b>false</b> if
- task was disabled. Since <b>enable() </b>schedules Task for execution
- immediately, this method provides a way to activate tasks and
- schedule them for immediate execution only if they are not active
- already.</p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">All
- <b>NOTES</b> from the enable() method apply.</p>
- <p class="western" style="margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-bottom: 0in"><b>void delay();</b></p>
- <p class="western" style="margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">Schedules
- the task for execution after a delay (aInterval), but does not change
- the enabled/disabled status of the task.
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><b>NOTE:
- </b>a delay of 0 (zero) will delay task for current execution
- interval. Use <b>forceNextIteration() </b>method to force execution
- of the task’s callback during immediate next scheduling pass.
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-bottom: 0in"><b>void
- </b><b>forceNextIteration</b><b>();</b></p>
- <p class="western" style="margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">Schedules
- the task for execution during immediate next scheduling pass.</p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">The
- Task must be already <i>enabled</i> prior to this method.
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><b>Note:
- </b>Task’s schedule is adjusted to run from this moment in time.
- For instance: if a task was running every 10 seconds: 10, 20, 30, ..,
- calling <b>forceNextIteration </b>at 44th second of task execution
- will make subsequent schedule look like: 44, 54, 64, 74, ..</p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-bottom: 0in"><b>void
- enableDelayed();</b></p>
- <p class="western" style="margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">Enables
- the task, and schedules it for execution after task's current
- scheduling interval (aInterval).
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-bottom: 0in"><b>void enableDelayed
- (unsigned long aDelay);</b></p>
- <p class="western" style="margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">Enables
- the task, and schedules it for execution after a specific delay
- (aDelay, which may be different from aInterval).
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-bottom: 0in"><b>void restart();</b></p>
- <p class="western" style="margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">For
- tasks with limited number of iterations only, <b>restart</b> method
- will re-enable the task, set the number of iterations back to last
- set value, and schedule task for execution as soon as possible.</p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-bottom: 0in"><b>void restartDelayed
- (unsigned long aDelay);</b></p>
- <p class="western" style="margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">Same
- as <b>restart()</b> method, with the only difference being that Task
- is scheduled to run first iteration after a delay = <b>aDelay</b>
- milliseconds (or microseconds).</p>
- <p class="western" style="margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-bottom: 0in"><b>bool disable();</b></p>
- <p class="western" style="margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">Disables
- the task. Scheduler will not execute this task any longer, even if it
- remains in the chain. Task <b>can</b> be later re-enabled for
- execution.
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">Return
- previous enabled state: <b>true</b> if task was enabled prior to
- calling disable, and <b>false</b> otherwise.</p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">If
- not NULL, task’s <b>OnDisable</b> method is invoked <b>immediately</b>.
- <b>OnDisable</b> is invoked only if task was in enabled state.
- Calling <b>disable</b> 3 times for instance will invoke <b>OnDisable</b>
- only once.</p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><b>NOTE:
- </b>internal StatusRequest object will signal completion of an event
- when Task is disabled (if TaskScheduler is compiled with support for
- StatusRequests). StatusRequest object is set complete <b>after </b>the
- call to onDisable() method of the Task (if defined). Consequently,
- the task which has to signal its completion to other Tasks could not
- restart itself. Do so will not ever set the internal StatusRequest
- object to a complete status, since the Task is never really disabled.
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-bottom: 0in"><b>void set(unsigned
- long aInterval, long aIterations, void (*aCallback)() , bool
- (*aOnEnable)() , void (*aOnDisable)());</b></p>
- <p class="western" style="margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">Allows
- dynamic control of task execution parameters in one method call.
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><b>Note</b><b>:
- </b>OnEnable and OnDisable parameters can be omitted. In that case
- they will be assigned to <b>NULL</b> and respective methods will no
- longer be called. Therefore it is advisable to use either all five
- parameters explicitly, or employ individual “setter” methods
- below instead.
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-bottom: 0in; page-break-after: avoid">
- Next five “setter” methods allow changes of individual task
- execution control parameters.
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><b>void
- setInterval (unsigned long aInterval) </b>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><b>void
- setIterations (long aIterations) </b>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><b>void
- setCallback (void (*aCallback)()) </b>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><b>void
- setOnEnable (bool (*aCallback)()) </b>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><b>void
- setOnDisable (void (*aCallback)()) </b>
- </p>
- <p class="western" style="margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-bottom: 0in"><b>NOTE: </b>Next
- execution time calculation takes place <b>after</b> the callback
- method is called, so new interval will be used immediately by the
- scheduler. For the situations when one task is changing the interval
- parameter for the other, <b>setInterval</b> method calls <b>delay
- </b>explicitly to guarantee schedule change, however it <b>does not
- </b>enable the task if task is disabled.</p>
- <p class="western" style="margin-bottom: 0in"><b>NOTE: </b>Tasks that
- ran through all their allocated iterations are disabled.
- <b>SetIterations()</b> method <b>DOES NOT</b> enable the task. Either
- <b>enable</b> explicitly, or use <b>restart</b> methods.
- </p>
- <p class="western" style="margin-bottom: 0in">Please note that as a
- result execution of the taks is <b>delayed</b> by the provided
- interval. If immediate invocation is required, call
- <b>forceNextIteration</b>() method after setting a new interval.
- </p>
- <p class="western" style="margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-bottom: 0in"><b>void yield(void
- (*aCallback)())</b></p>
- <p class="western" style="margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-bottom: 0in">This method could be
- used to break up long callback methods. A long callback method should
- be broken up into several shorter methods. Yield method just gives
- control back to scheduler, while ensuring that next iteration of the
- Task is executed immediately with the next callback method. Basically
- “yield(&callBack2)” is equivalent to setting new callback
- method, and forcing next iteration to be immediate. Please not that
- original interval and number of iterations are preserved. Even the
- runcounter of the callback2 after yielding will remain the same.
- Typically a call to yield() method is the last line of the method
- yielding.</p>
- <p class="western" style="margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-bottom: 0in"><b>void yield</b><font face="Times New Roman, serif"><b>Once</b></font><b>(void
- (*aCallback)())</b></p>
- <p class="western" style="margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-bottom: 0in">This method is
- equivalent to <b>yield(),</b> only execution of the target <i><b>a</b></i><font face="Times New Roman, serif"><span lang="ru-RU"><i><b>С</b></i></span></font><i><b>allback</b></i>
- method is set to happen only once, after which the Task will be
- disabled.</p>
- <p class="western" style="margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-bottom: 0in; page-break-after: avoid">
- <b>STATUS REQUEST METHODS:</b></p>
- <p class="western" style="margin-bottom: 0in; page-break-after: avoid">
- <br>
- </p>
- <p class="western" style="margin-bottom: 0in; page-break-after: avoid">
- <b>void waitFor(StatusRequest* aStatusRequest, unsigned long
- aInterval = 0, long aIterations = 1)</b></p>
- <p class="western" style="margin-bottom: 0in; page-break-after: avoid">
- <b>void waitForDelayed(StatusRequest* aStatusRequest, unsigned long
- aInterval = 0, long aIterations = 1)</b></p>
- <p class="western" style="margin-bottom: 0in; page-break-after: avoid">
- <br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">If
- compiled with support for Status Requests, these methods make task
- wait for the completion of <b>aStatusRequest</b> event.
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">By
- default <b>waitFor() </b>sets tasks interval to <b>0 (zero)</b> for
- immediate execution when event happens, and also sets the number of
- <b>iterations to 1</b>. However, you can specify different interval
- and number of iterations.
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">By
- default <b>waitForDelayed() </b>sets tasks interval to a supplied
- value or (if omitted or zero) keeps the current interval, so delayed
- execution will take place when the event happens. It also sets the
- number of <b>iterations to 1</b> by default if not supplied.
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">When
- Status Request object completes, all tasks waiting on it are executed
- during next scheduling pass. Tasks waiting via <b>waitFor</b>()
- method are executed immediately. Tasks waiting via <b>waitForDelayed</b>()
- method are activated, but executed after current or supplied interval
- delay.
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><b>Note:
- aStatusRequest</b> should be “activated” by calling <b>setWaiting()
- </b>method before making a task wait on it. Otherwise, the task will
- execute immediately.
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">The
- sequence of events to use Status Request object is as follows:</p>
- <ol>
- <li><p class="western" style="margin-bottom: 0in">Create a status
- request object</p>
- <li><p class="western" style="margin-bottom: 0in">Activate status
- request object (calling its <b>setWaiting</b>() method)</p>
- <li><p class="western" style="margin-bottom: 0in">Set up tasks to
- wait of the event completion</p>
- <li><p class="western" style="margin-bottom: 0in">Signal completion
- of event(s)</p>
- </ol>
- <p class="western" style="margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-bottom: 0in"><b>StatusRequest*
- getStatusRequest()</b></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">Returns
- a pointer to StatusReqeust object this Task was waiting on.
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-bottom: 0in"><b>StatusRequest*
- getInternalStatusRequest()</b></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">Returns
- a pointer to an internal StatusReqeust object associated with this
- Task. Internal StatusRequest object is:</p>
- <ol>
- <li><p class="western" style="margin-bottom: 0in">Always waits on 1
- event – completion of this task</p>
- <li><p class="western" style="margin-bottom: 0in">Is activated (set
- to “waiting” status) after Task is enabled</p>
- <li><p class="western" style="margin-bottom: 0in">Is completed after
- Task is disabled (either explicitly, or by running out of
- iterations)</p>
- </ol>
- <p class="western" style="margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><b>NOTE:
- </b>Please remember that a task is deactivated at the next scheduling
- pass after the last iteration, which means that other Tasks in the
- chain will have a chance to run before Task StatusRequest signaling
- completion of the internal StatusRequest. However, there is no
- further delay – deactivation will take place at the next scheduling
- pass.</p>
- <p class="western" style="margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-bottom: 0in; page-break-after: avoid">
- <b>TASK ID, CONTROL POINTS METHODS:</b></p>
- <p class="western" style="margin-bottom: 0in; page-break-after: avoid">
- <br>
- </p>
- <p class="western" style="margin-bottom: 0in; page-break-after: avoid">
- <b>void setId(unsigned int aID);</b></p>
- <p class="western" style="margin-bottom: 0in; page-break-after: avoid">
- <br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">If
- compiled with support for Task IDs, this method will set the task ID
- explicitly.
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">Calling
- this method is not necessary as task IDs are assigned automatically
- during task creation: 1, 2, 3, …</p>
- <p class="western" style="margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-bottom: 0in; page-break-after: avoid">
- <b>unsigned int getId();</b></p>
- <p class="western" style="margin-bottom: 0in; page-break-after: avoid">
- <br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">If
- compiled with support for Task IDs, this method return current task’s
- ID.</p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-bottom: 0in; page-break-after: avoid">
- <b>void setControlPoint (unsigned int aPoint);</b></p>
- <p class="western" style="margin-bottom: 0in; page-break-after: avoid">
- <br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">If
- compiled with support for Task IDs, this method will set a control
- point in the task’s code. Control points are similar to “try…catch”
- blocks, with control point ID specifying where in the code the “try”
- part started, and a mechanism like watchdog timer providing the
- “catch” functionality.</p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-bottom: 0in; page-break-after: avoid">
- <b>unsigned int getControlPoint()</b></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in; page-break-after: avoid">
- <br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in; page-break-after: avoid">
- If compiled with support for Task IDs, this method will return
- currently set control point for this task.</p>
- <p class="western" style="margin-bottom: 0in; page-break-after: avoid">
- <br>
- </p>
- <p class="western" style="margin-bottom: 0in; page-break-after: avoid">
- <br>
- </p>
- <p class="western" style="margin-bottom: 0in"><b>LOCAL TASK STORAGE
- METHODS:</b></p>
- <p class="western" style="margin-bottom: 0in; page-break-after: avoid">
- <br>
- </p>
- <p class="western" style="margin-bottom: 0in; page-break-after: avoid">
- <b>void setLtsPointer(void *aPtr);</b></p>
- <p class="western" style="margin-bottom: 0in; page-break-after: avoid">
- <br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">If
- compiled with support for LTS, this method will set the task's local
- storage pointer.</p>
- <p class="western" style="margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-bottom: 0in; page-break-after: avoid">
- <b>void *getLtsPointer();</b></p>
- <p class="western" style="margin-bottom: 0in; page-break-after: avoid">
- <br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">If
- compiled with support for LTS, this method will return reference to
- the task's local storage.</p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><b>Note:
- </b>the value returned has type (void *), and needs to be re-cast
- into appropriate pointer type. Please refer to example sketches for
- implementation options.
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-bottom: 0in; page-break-after: avoid">
- <b>STATUS REQUEST:</b></p>
- <p class="western" style="margin-bottom: 0in; page-break-after: avoid">
- <br>
- </p>
- <p class="western" style="margin-bottom: 0in; page-break-after: avoid">
- <b>CREATION:</b></p>
- <p class="western" style="margin-bottom: 0in; page-break-after: avoid">
- <br>
- </p>
- <p class="western" style="margin-bottom: 0in"><b>StatusRequest()</b><br><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">Default
- constructor.
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">Takes
- no parameters. Creates Status Request object, which is assigned a
- status of “completed” on creation.
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-bottom: 0in"><b>void
- setWaiting(unsigned int aCount = 1)</b></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">Activates
- Status Request object. By default each object is set to wait on one
- event only, however, if <b>aCount</b> is supplied, Status Request can
- wait on multiple events. For instance, <b>setWaiting(3)</b> will wait
- on three signals. An example could be waiting for completion of
- measurements from 3 sensors.
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-bottom: 0in"><b>bool signal(int
- aStatus)</b></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">Signals
- completion of the event to the Status Request object, and passes a
- completion code, which could be interrogated later.
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><b>Note:
- </b> passing a <b>negative</b> status code to the status request
- object is considered reporting an error condition, and will complete
- the status request regardless of how many outstanding signals it is
- still waiting for.
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><b>Note</b>:
- only the latest status code is kept.</p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-bottom: 0in"><b>bool signalComplete
- (int aStatus)</b></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">Signals
- completion of <b>ALL</b> events to the Status Request object, and
- passes a completion code, which could be interrogated later. The
- status request completes regardless of how many events it is still
- waiting on.
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-bottom: 0in"><b>bool pending() </b>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">Returns
- <b>true</b> if status request is still waiting for event or events to
- happen.</p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-bottom: 0in"><b>bool completed () </b>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">Returns
- <b>true</b> if status request event has completed.</p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-bottom: 0in"><b>int getStatus()</b></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">Returns
- the status code passed to the status request object by the <b>signal()
- </b>and <b>signalComplete() </b>methods.
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">Any
- <b>positive</b> number is considered a successful completion status.</p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">A
- 0 (zero) is considered a default successful completion status.</p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">Any
- <b>negative</b> number is considered an error code and unsuccessful
- completion of a request.</p>
- <p class="western" style="margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-bottom: 0in"><b>int getCount()</b></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">Returns
- the count of events not yet completed. Typically by default a
- StatusRequest object only waits on 1 event. However, in the
- situations where a StatusRequest object is waiting on multiple
- events, a number of events <b>not yet completed </b>is returned by
- this method.
- </p>
- <p class="western" style="margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-bottom: 0in; page-break-after: avoid">
- <br>
- </p>
- <p class="western" style="margin-bottom: 0in; page-break-inside: avoid; page-break-after: avoid">
- <font size="4" style="font-size: 14pt"><b>TASK SCHEDULER:</b></font></p>
- <p class="western" style="margin-bottom: 0in; page-break-inside: avoid; page-break-after: avoid">
- <br>
- </p>
- <p class="western" style="margin-bottom: 0in; page-break-inside: avoid; page-break-after: avoid">
- <b>CREATION:</b></p>
- <p class="western" style="margin-bottom: 0in; page-break-inside: avoid; page-break-after: avoid">
- <br>
- </p>
- <p class="western" style="margin-bottom: 0in"><b>Scheduler()</b><br><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">Default
- constructor.
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">Takes
- no parameters. Creates task scheduler with default parameters and an
- empty task queue.
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-bottom: 0in"><b>void init()</b></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">Initializes
- the task queue and scheduler parameters, Executed as part of
- constructor, so don't need to be explicitly called after creation.</p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><b>Note:
- </b>be default (if compiled with <font face="Courier New, monospace">_TASK_TIMECRITICAL</font>
- enabled) scheduler is allowed to put processor to IDLE sleep mode. If
- this behavior was changed via <b>allowSleep()</b> method, <b>inti()
- </b>will <b>NOT</b> reset allow sleep particular parameter.
- </p>
- <p class="western" style="margin-bottom: 0in"><br><b>void
- addTask(Task& aTask)</b></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">Adds
- task aTask to the execution queue (or chain) of tasks by appending it
- to the end of the chain. If two tasks are scheduled for execution,
- the sequence will match the order in which tasks were appended to the
- chain. However, in reality, due to different timing of task
- execution, the actual order may be different.
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><b>Note:
- </b>Currently, changing the execution sequence in a chain dynamically
- is not supported.
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">If
- you need to reorder the chain sequence – initialize the scheduler
- and re-add the tasks in a different order.
- </p>
- <p class="western" style="margin-bottom: 0in"><br><b>void
- deleteTask(Task& aTask)</b></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">Deletes
- task aTask from the execution chain. The chain of remaining tasks is
- linked together (i.e</p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">if
- original task chain is 1 → 2 → 3 → 4, deleting 3 will result in
- 1 → 2 → 4).</p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><b>Note:
- </b>it is not required to delete a task from the chain. A disabled
- task will not be executed anyway, but you save a few microseconds per
- scheduling pass by deleting it, since it is not even considered for
- execution.
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">An
- example of proper use of this method would be running some sort of
- <b>initialize</b> task in the chain, and then deleting it from the
- chain since it only needs to run once.
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-bottom: 0in"><b>void allowSleep(bool
- aState) </b>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">Available
- in API only if compiled with <font face="Courier New, monospace">_TASK_TIMECRITICAL</font>
- enabled. Controls whether scheduler is allowed (<b>aState =true</b>),
- or not (<b>aState =false</b>) to put processor into IDLE sleep mode
- in case not tasks are scheduled to run.</p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">The
- <b>default</b> behavior of scheduler upon creation is to allow sleep
- mode.
- </p>
- <p class="western" style="margin-bottom: 0in"><br><b>void
- enableAll(bool aRecursive= true)</b></p>
- <p class="western" style="margin-bottom: 0in"><b>void disableAll(bool
- aRecursive= true)</b></p>
- <p class="western" style="margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">enables
- and disables (respectively) all tasks in the chain. Convenient if
- your need to enable/disable majority of the tasks (i.e. disable all
- and then enable one).
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">If
- support for layered task priority is enabled, supplying <b>aRecursive</b>
- parameter will enable/disable higher priority tasks as well (<b>true</b>,
- default), or tasks only on this priority layer (<b>false</b>).
- </p>
- <p class="western" style="margin-bottom: 0in; page-break-after: avoid">
- <br><b>Task& currentTask()<br></b><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">Returns
- reference to the task, currently executing via <b>execute()</b> loop
- <b>OR </b>for OnEnable and OnDisable methods, reference to the task
- being enabled or disabled.
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">This
- distinction is important because one task can activate the other, and
- OnEnable should be referring to the task being enabled, not being
- executed.
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">Could
- be used by callback methods to identify which Task actually invoked
- this callback method.</p>
- <p class="western" style="margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-bottom: 0in; page-break-after: avoid">
- <b>void* currentLts()<br></b><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">Returns
- pointer to Local Task Storage of the task, currently executing via
- <b>execute()</b> loop <b>OR </b>for OnEnable and OnDisable methods,
- task being enabled or disabled.
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-bottom: 0in"><b>void startNow (bool
- aRecursive= true)</b></p>
- <p class="western" style="margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">Sets
- <b>ALL active tasks</b> in the execution chain to start execution
- immediately. Should be placed at the end of <b>setup()</b> method to
- prevent task execution race due to long running setup tasks (hardware
- initialization, etc.) following task activation.
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">If
- support for layered task priority is enabled, supplying <b>aRecursive</b>
- parameter will set immediate execution for higher priority tasks as
- well (<b>true</b>, default), or tasks only on this priority layer
- (<b>false</b>).
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><b>NOTE:
- </b>if <b>setup()</b> method does not contain long running tasks, use
- of <b>startNow()</b> method is not necessary. Alternatively, all
- tasks could be enabled <b>after </b>long-running <b>setup()</b>
- processes, thus eliminating the need to use <b>startNow()</b> method.
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><b>NOTE:
- </b>Any tasks which should execute after a <i><b>delay</b></i>,
- should be explicitly delayed after call to <b>startNow()</b> method.
- </p>
- <p class="western" style="margin-bottom: 0in"><br><b>bool execute()</b></p>
- <p class="western" style="margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">Executes
- one scheduling pass, including (in case of the base priority
- scheduler) end-of-pass sleep. This method should be placed inside the
- <b>loop()</b> method of the sketch. Since <b>execute</b> exits after
- every pass, you can put additional statements after <b>execute</b>
- inside the <b>loop().</b></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><b>If
- layered task prioritization is enabled, all higher priority tasks
- will be evaluated and invoked by the base </b><font face="Courier New, monospace"><b>execute()</b></font><b>
- method. There is no need to call </b><font face="Courier New, monospace"><b>execute()</b></font><b>
- of the higher priority schedulers explicitly. </b>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">Generally,
- base priority execute will perform the following steps:</p>
- <ol>
- <li><p class="western" style="margin-bottom: 0in">Call higher
- priority scheduler’s execute method, if provided.</p>
- <li><p class="western" style="margin-bottom: 0in">Ignore task
- completely if it is disabled.</p>
- <li><p class="western" style="margin-bottom: 0in">Disable task if it
- ran out of iterations (calling OnDisable, if necessary).</p>
- <li><p class="western" style="margin-bottom: 0in">Check if task is
- waiting on a StatusRequest object, and make appropriate scheduling
- arrangements</p>
- <li><p class="western" style="margin-bottom: 0in">Perform necessary
- timing calculations</p>
- <li><p class="western" style="margin-bottom: 0in">Invoke task's
- callback method, if it is time to do so, and one is provided.
- </p>
- <li><p class="western" style="margin-bottom: 0in">Put
- microcontroller to sleep (if requested and supported) if none of the
- tasks were invoked.
- </p>
- </ol>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><b>Please
- NOTE:</b> schedule-related calculations are performed prior to task's
- callback method invocation. This allows tasks to manipulate their
- runtime parameters (like execution interval) directly.</p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-bottom: 0in"><b>bool isOverrun()</b></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">If
- library is compiled with <font face="Courier New, monospace">_TASK_TIMECRITICAL</font>
- enabled, this method returns <b>true</b> if currently invoked task
- has overrun its scheduled start time when it was invoked. Returns
- <b>false</b> if task has been invoked according to schedule.</p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-bottom: 0in; page-break-after: avoid">
- <br>
- </p>
- <p class="western" style="margin-bottom: 0in; page-break-after: avoid">
- <b>TASK PRIORITY:</b></p>
- <p class="western" style="margin-bottom: 0in; page-break-after: avoid">
- <br>
- </p>
- <p class="western" style="margin-bottom: 0in"><b>void
- setHighPriorityScheduler(Scheduler* aScheduler);</b><br><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">If
- library is compiled with <font face="Courier New, monospace">_TASK_PRIORITY
- </font>enabled, this method associates current scheduler with a
- higher priority scheduler.
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><b>NOTE:
- </b>Only one <b>execute() </b>method needs to be explicitly called in
- the main <b>loop(). </b>That is the execute method of <b>base</b>
- priority scheduler. All higher priority schedulers are called by the
- base priority scheduler.</p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-bottom: 0in"><b>static Scheduler&
- currentScheduler()</b></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">If
- library is compiled with <font face="Courier New, monospace">_TASK_PRIORITY
- </font>enabled, this method returns reference to a scheduler, which
- invoked current task.
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><b>NOTE:
- Please refer to examples 11 and 12 for illustration of Task Priority
- functionality</b></p>
- <p class="western" style="margin-bottom: 0in; page-break-after: avoid">
- <br>
- </p>
- <p class="western" style="margin-bottom: 0in; page-break-after: avoid">
- <br>
- </p>
- <p class="western" style="margin-bottom: 0in; page-break-after: avoid">
- <br>
- </p>
- <p class="western" style="margin-bottom: 0in; page-break-after: avoid">
- <b>CONSTANTS:</b></p>
- <p class="western" style="margin-bottom: 0in; page-break-after: avoid">
- <br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in; page-break-after: avoid">
- <b>TASK_SECOND (1000 millis or 1000000 micros)</b></p>
- <p class="western" style="margin-left: 0.98in; margin-bottom: 0in">Task
- interval of 1 second</p>
- <p class="western" style="margin-left: 0.98in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in; page-break-after: avoid">
- <b>TASK_MINUTE (60000 millis or 60000000 micros)</b></p>
- <p class="western" style="margin-left: 0.98in; margin-bottom: 0in">Task
- interval of 1 minute</p>
- <p class="western" style="margin-left: 0.98in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in; page-break-after: avoid">
- <b>TASK_HOUR (3600000 millis or 3600000000 micros)</b></p>
- <p class="western" style="margin-left: 0.98in; margin-bottom: 0in">Task
- interval of 1 hour</p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in; page-break-after: avoid">
- <b>TASK_FOREVER (-1)</b></p>
- <p class="western" style="margin-left: 0.98in; margin-bottom: 0in">Task
- number of iterations for infinite number of iterations</p>
- <p class="western" style="margin-left: 0.98in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in; page-break-after: avoid">
- <b>TASK_ONCE (1)</b></p>
- <p class="western" style="margin-left: 0.98in; margin-bottom: 0in">Task
- single iteration</p>
- <p class="western" style="margin-left: 0.98in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in; page-break-after: avoid">
- <b>TASK_IMMEDIATE (0)</b></p>
- <p class="western" style="margin-left: 0.98in; margin-bottom: 0in">Task
- interval for immediate execution</p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-bottom: 0in; page-break-before: always; page-break-after: avoid">
- <b>IMPLEMENTATION SCENARIOS AND IDEAS:</b></p>
- <p class="western" style="margin-bottom: 0in; page-break-after: avoid">
- <br>
- </p>
- <ol>
- <li><p class="western" style="margin-bottom: 0in; page-break-after: avoid">
- <b>EVENT DRIVEN PROGRAMMING</b></p>
- </ol>
- <p class="western" style="margin-bottom: 0in; page-break-after: avoid">
- <br>
- </p>
- <p class="western" style="margin-bottom: 0in">Each of the processes
- of your application becomes a separate and distinct programming area,
- which may or may not interact and control each other.
- </p>
- <p class="western" style="margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-bottom: 0in">Example:
- </p>
- <p class="western" style="margin-bottom: 0in">In a plant watering
- system you need to measure soil humidity, control pump and display
- the results</p>
- <p class="western" style="margin-bottom: 0in">Each of the areas
- becomes a task:</p>
- <p class="western" style="margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><font face="Courier New, monospace"><font size="2" style="font-size: 10pt">Task
- </font></font><font face="Courier New, monospace"><font size="2" style="font-size: 10pt"><b>tMeasure</b></font></font><font face="Courier New, monospace"><font size="2" style="font-size: 10pt">
- (TMEASURE_INTERVAL*SECOND, TASK_FOREVER, &measureCallback);<br>Task
- </font></font><font face="Courier New, monospace"><font size="2" style="font-size: 10pt"><b>tWater</b></font></font><font face="Courier New, monospace"><font size="2" style="font-size: 10pt">
- (TWATER_INTERVAL*SECOND, RETRIES, &waterCallback);<br>Task
- </font></font><font face="Courier New, monospace"><font size="2" style="font-size: 10pt"><b>tDisplay</b></font></font><font face="Courier New, monospace"><font size="2" style="font-size: 10pt">
- (TDISPLAY_INTERVAL*SECOND, TASK_FOREVER, &displayCallback); <br></font></font><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><font face="Courier New, monospace"><font size="2" style="font-size: 10pt">Scheduler
- </font></font><font face="Courier New, monospace"><font size="2" style="font-size: 10pt"><b>taskManager</b></font></font><font face="Courier New, monospace"><font size="2" style="font-size: 10pt">;</font></font><br><br>
- </p>
- <p class="western" style="margin-bottom: 0in">Further, once you turn
- on the pump, you keep it running for TWATER_INTERVAL interval and
- then turn it off. Turning off a pump is also a task which only needs
- to run once for every time the pump is turned on:</p>
- <p class="western" style="margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><font face="Courier New, monospace"><font size="2" style="font-size: 10pt">Task
- </font></font><font face="Courier New, monospace"><font size="2" style="font-size: 10pt"><b>tWaterOff</b></font></font><font face="Courier New, monospace"><font size="2" style="font-size: 10pt">
- (WATERTIME*SECOND, TASK_ONCE,</font></font><font face="Courier New, monospace">
- &waterOffCallback);</font><br><br>
- </p>
- <p class="western" style="margin-bottom: 0in">Example of the callback
- method:</p>
- <p class="western" style="margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><font face="Courier New, monospace"><font size="2" style="font-size: 10pt">void
- waterOffCallback() {<br> motorOff();<br>
- tWater.enableDelayed();<br>}</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><font face="Courier New, monospace"><font size="2" style="font-size: 10pt">or</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><font face="Courier New, monospace"><font size="2" style="font-size: 10pt">void
- waterCallback() {<br> if (tWater.getIterations()) {</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><font face="Courier New, monospace"><font size="2" style="font-size: 10pt">//
- If this is not the last iteration = turn the pump on<br>
- motorOn();<br> tWaterOff.set(parameters.watertime * TASK_SECOND,
- TASK_ONCE, &waterOffCallback);<br>
- tWaterOff.enableDelayed();<br> return;<br> }</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><font face="Courier New, monospace"><font size="2" style="font-size: 10pt">//
- We could not reach target humidity – something is wrong<br>
- motorOff;<br> taskManager.disableAll();<br> tError.enable();<br>}</font></font></p>
- <p class="western" style="margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-bottom: 0in"><font face="Times New Roman, serif">Your
- sample </font><font face="Times New Roman, serif"><b>setup</b></font><font face="Times New Roman, serif">()
- and </font><font face="Times New Roman, serif"><b>loop</b></font><font face="Times New Roman, serif">()
- (partially) are as follows. </font>
- </p>
- <p class="western" style="margin-bottom: 0in"><font face="Times New Roman, serif"><b>Note:
- </b></font><font face="Times New Roman, serif">please note that
- tWater is </font><font face="Times New Roman, serif"><b>not</b></font><font face="Times New Roman, serif">
- activated during setup(). It is activated by tMeasure callback once
- the watering conditions are met. </font>
- </p>
- <p class="western" style="margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-bottom: 0in"><font face="Times New Roman, serif"><font size="2" style="font-size: 10pt"> void
- </font></font><font face="Courier New, monospace"><font size="2" style="font-size: 10pt">setup()</font></font></p>
- <p class="western" style="margin-bottom: 0in"><font face="Courier New, monospace"><font size="2" style="font-size: 10pt">
- ...</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">
- <font face="Courier New, monospace"><font size="2" style="font-size: 10pt">tWater.setIterations(parameters.retries);<br>
- tWaterOff.setInterval(parameters.watertime * SECOND);<br><br><br>
- taskManager.init();<br> taskManager.addTask(tMeasure);<br>
- taskManager.addTask(tDisplay);<br> taskManager.addTask(tWater);<br>
- taskManager.addTask(tWaterOff);<br> <br> tMeasure.enable();<br>
- tDisplay.enable();<br><br> currentHumidity =
- measureHumidity();<br>}<br><br><br>void loop ()<br>{<br>
- taskManager.execute();<br>}</font></font><font face="Times New Roman, serif"><font size="2" style="font-size: 10pt"><br></font></font><br>
- </p>
- <ol start="2">
- <li><p class="western" style="margin-bottom: 0in; page-break-after: avoid">
- “<font face="Times New Roman, serif"><b>NATIVE” SUPPORT FOR
- FINITE STATE MACHINE</b></font></p>
- </ol>
- <p class="western" style="margin-bottom: 0in; page-break-after: avoid">
- <br>
- </p>
- <p class="western" style="margin-bottom: 0in"><font face="Times New Roman, serif">Define
- “states” as callback method or methods. Each callback method
- executes activities specific to a “state” and then “transitions”
- to the next state by assigning next callback method to the task. </font>
- </p>
- <p class="western" style="margin-bottom: 0in"><font face="Times New Roman, serif">Transition
- from one state to the next is achieved by setting next callback
- method at the end of preceding one. </font>
- </p>
- <p class="western" style="margin-bottom: 0in"><font face="Times New Roman, serif"><b>Note:
- </b></font><font face="Times New Roman, serif">do not call the next
- callback method explicitly. Yield to the scheduler, and let the
- scheduler take care of next iteration during the next pass. (Thus
- giving other tasks change to run their callback methods). </font>
- </p>
- <p class="western" style="margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-bottom: 0in"><font face="Times New Roman, serif">Example:
- Blinking LED 2 times a second could be achieved this way</font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><font face="Courier New, monospace"><font size="2" style="font-size: 10pt">Scheduler
- ts;</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><font face="Courier New, monospace"><font size="2" style="font-size: 10pt">Task
- tLedBlinker (500, TASK_FOREVER, &ledOnCallback, &ts, true);</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><font face="Courier New, monospace"><font size="2" style="font-size: 10pt">void
- ledOnCallback() {</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><font face="Courier New, monospace"><font size="2" style="font-size: 10pt"> turnLedOn();</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><font face="Courier New, monospace"><font size="2" style="font-size: 10pt"> tLedBlinker.setCallback(&ledOffCallback);</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><font face="Courier New, monospace"><font size="2" style="font-size: 10pt">}</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><font face="Courier New, monospace"><font size="2" style="font-size: 10pt">void
- ledOffCallback() {</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><font face="Courier New, monospace"><font size="2" style="font-size: 10pt"> turnLedOff();</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><font face="Courier New, monospace"><font size="2" style="font-size: 10pt"> tLedBlinker.setCallback(&ledOnCallback);</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><font face="Courier New, monospace"><font size="2" style="font-size: 10pt">}</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><font face="Courier New, monospace"><font size="2" style="font-size: 10pt">setup()
- {</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><font face="Courier New, monospace"><font size="2" style="font-size: 10pt">}</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><font face="Courier New, monospace"><font size="2" style="font-size: 10pt">loop
- () {</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><font face="Courier New, monospace"><font size="2" style="font-size: 10pt"> ts.execute();</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><font face="Courier New, monospace"><font size="2" style="font-size: 10pt">}</font></font><font face="Times New Roman, serif"><br></font><br>
- </p>
- <p class="western" style="margin-bottom: 0in"><font face="Times New Roman, serif">Obviously
- the example is simple, but gives the idea of how the tasks could be
- used to go through states.</font></p>
- <p class="western" style="margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-bottom: 0in"><br>
- </p>
- <ol start="3">
- <li><p class="western" style="margin-bottom: 0in; page-break-after: avoid">
- <font face="Times New Roman, serif"><b>MULTIPLE POSSIBLE CALLBACKS
- FOR TASK</b></font></p>
- </ol>
- <p class="western" style="margin-bottom: 0in; page-break-after: avoid">
- <br>
- </p>
- <p class="western" style="margin-bottom: 0in"><font face="Times New Roman, serif">There
- may be a need to select an option for callback method based on
- certain criteria, or randomly. </font>
- </p>
- <p class="western" style="margin-bottom: 0in"><font face="Times New Roman, serif">You
- can achieve that by defining an array of callback method pointers and
- selecting one based on the criteria you need. </font>
- </p>
- <p class="western" style="margin-bottom: 0in"><font face="Times New Roman, serif">Example:
- when a robot detects an obstacle, it may go left, right backwards,
- etc. Each of the “directions” or “behaviors” are represented
- by a different callback methods. </font>
- </p>
- <p class="western" style="margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-bottom: 0in"><font face="Times New Roman, serif">Another
- example of using multiple callbacks:</font></p>
- <p class="western" style="margin-bottom: 0in"><font face="Times New Roman, serif">You
- may need to “initialize” variables for a particular task.</font></p>
- <p class="western" style="margin-bottom: 0in"><font face="Times New Roman, serif">In
- this case, define a tasks with two callbacks:</font></p>
- <p class="western" style="margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><font face="Courier New, monospace"><font size="2" style="font-size: 10pt">Task
- </font></font><font face="Courier New, monospace"><font size="2" style="font-size: 10pt"><b>tWork</b></font></font><font face="Courier New, monospace"><font size="2" style="font-size: 10pt">
- (T_INTERVAL, TASK_FOREVER, &workCallbackInit);</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">…</p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><font face="Courier New, monospace"><font size="2" style="font-size: 10pt">void
- workCallbackInit() {</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><font face="Courier New, monospace"><font size="2" style="font-size: 10pt"> //
- do your initializationstuff here</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><font face="Courier New, monospace"><font size="2" style="font-size: 10pt"> </font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><font face="Courier New, monospace"><font size="2" style="font-size: 10pt"> //
- finally assigne the main callback method </font></font>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><font face="Courier New, monospace"><font size="2" style="font-size: 10pt"> tWork.setCallback(&workCallback);</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><font face="Courier New, monospace"><font size="2" style="font-size: 10pt">}</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><font face="Courier New, monospace"><font size="2" style="font-size: 10pt">void
- workCallback() {</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><font face="Courier New, monospace"><font size="2" style="font-size: 10pt"> //
- main callback method</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><font face="Courier New, monospace"><font size="2" style="font-size: 10pt"> …</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><font face="Courier New, monospace"><font size="2" style="font-size: 10pt">}</font></font></p>
- <p class="western" style="margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-bottom: 0in"><font face="Times New Roman, serif">The
- task will initialize during first execution pass and switch to
- “regular” callback execution starting with second pass. There is
- a delay between first and second passes of the task (scheduling
- period, if defined). In order to execute the second pass immediately
- after initialization first pass, change the above code like this:</font></p>
- <p class="western" style="margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><font face="Courier New, monospace"><font size="2" style="font-size: 10pt">void
- workCallbackInit() {</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><font face="Courier New, monospace"><font size="2" style="font-size: 10pt"> //
- do your initializationstuff here</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><font face="Courier New, monospace"><font size="2" style="font-size: 10pt"> </font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><font face="Courier New, monospace"><font size="2" style="font-size: 10pt"> //
- finally assigne the main callback method </font></font>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><font face="Courier New, monospace"><font size="2" style="font-size: 10pt"> tWork.setCallback(&workCallback);</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><font face="Courier New, monospace"><font size="2" style="font-size: 10pt"> tWork.enable();</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><font face="Courier New, monospace"><font size="2" style="font-size: 10pt">}</font></font></p>
- <p class="western" style="margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-bottom: 0in"><font face="Times New Roman, serif">The
- task will run initialization first, then immediately second pass, and
- then switch to processing at regular intervals starting with a third
- pass. </font>
- </p>
- <p class="western" style="margin-bottom: 0in"><br>
- </p>
- <ol start="3">
- <li><p class="western" style="margin-bottom: 0in; page-break-after: avoid">
- <font face="Times New Roman, serif"><b>INTERRUP-DRIVEN EXECUTION
- SUPPORT </b></font>
- </p>
- </ol>
- <p class="western" style="margin-bottom: 0in; page-break-after: avoid">
- <br>
- </p>
- <p class="western" style="margin-bottom: 0in"><font face="Times New Roman, serif">In
- case of interrupt-driven program flow, tasks could be scheduled to
- run once to request asynchronous execution (request), and then
- re-enabled (restarted) again with a different callback method to
- process the results. </font>
- </p>
- <p class="western" style="margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-bottom: 0in"><font face="Times New Roman, serif"><b>Example</b></font><font face="Times New Roman, serif">:
- event driven distance calculation for ultrasonic pulses. EchoPin #6
- triggers pin change interrupts on rising and falling edges to
- determine the length of ultrasonic pulse.</font></p>
- <p class="western" style="margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><font face="Courier New, monospace"><font size="2" style="font-size: 10pt">#include
- <DirectIO.h><br>#include <TaskScheduler.h><br>#include
- <PinChangeInt.h><br><br><br>#define TRIGGERPIN 5<br>#define
- ECHOPIN 6<br><br>Output<TRIGGERPIN>
- pTrigger;<br>Input<ECHOPIN> pEcho;<br><br>Scheduler
- r;<br><br>Task tMeasure(TASK_SECOND, TASK_FOREVER, &measureCallback,
- &r, true);<br>Task tDisplay(TASK_SECOND, TASK_FOREVER,
- &displayCallback, &r, true);<br>Task tPing(TASK_IMMEDIATE,
- TASK_ONCE, &pingCalcCallback, &r, false);<br><br><br>volatile
- bool pulseBusy = false;<br>volatile bool pulseTimeout =
- false;<br>volatile unsigned long pulseStart = 0;<br>volatile unsigned
- long pulseStop = 0;<br>volatile unsigned long pingDistance =
- 0;<br><br><br>void pingTrigger(unsigned long aTimeout) {<br> if
- (pulseBusy) return; // do not trigger if in the middle of a pulse<br>
- if (pEcho == HIGH) return; // do not trigger if ECHO pin is high<br>
- <br> pulseBusy = true;<br> pulseTimeout = false;</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><font face="Courier New, monospace"><font size="2" style="font-size: 10pt"><br>
- pTrigger = LOW;<br> delayMicroseconds(4);<br> pTrigger = HIGH;<br><br>
- tPing.setInterval (aTimeout);<br><br> delayMicroseconds(10);<br>
- pTrigger = LOW; <br></font></font><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">
- <font face="Courier New, monospace"><font size="2" style="font-size: 10pt">tPing.restartDelayed();
- // timeout countdown starts now<br></font></font><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><font face="Courier New, monospace"><font size="2" style="font-size: 10pt">//
- will start the pulse clock on the rising edge of ECHO pin</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">
- <font face="Courier New, monospace"><font size="2" style="font-size: 10pt">PCintPort::attachInterrupt(ECHOPIN,
- &pingStartClock, RISING); <br>}<br><br></font></font><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><font face="Courier New, monospace"><font size="2" style="font-size: 10pt">//
- Start clock on the </font></font><font face="Courier New, monospace"><font size="2" style="font-size: 10pt"><b>rising</b></font></font><font face="Courier New, monospace"><font size="2" style="font-size: 10pt">
- edge of the ultrasonic pulse<br>void pingStartClock() {<br>
- pulseStart = micros();<br> PCintPort::detachInterrupt(ECHOPIN); //
- not sure this is necessary<br> PCintPort::attachInterrupt(ECHOPIN,
- &pingStopClock, FALLING); <br> tPing.restartDelayed();<br>}<br><br>//
- Stop clock on the </font></font><font face="Courier New, monospace"><font size="2" style="font-size: 10pt"><b>falling</b></font></font><font face="Courier New, monospace"><font size="2" style="font-size: 10pt">
- edge of the ultrasonic pulse<br>void pingStopClock() {<br> pulseStop
- = micros();<br> PcintPort::detachInterrupt(ECHOPIN);</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">
- <font face="Courier New, monospace"><font size="2" style="font-size: 10pt">pingDistance
- = pulseStop - pulseStart;<br> pulseBusy = false;<br>
- tPing.disable(); // disable timeout<br>}<br></font></font><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><font face="Courier New, monospace"><font size="2" style="font-size: 10pt">//
- Stop clock because of the timeout – the wave did not return<br>void
- pingCalcCallback() {<br> if (pulseBusy) {<br> pingStopClock();<br>
- }<br> pulseTimeout = true;<br>}<br><br><br><br>// Initial measure
- callback sets the trigger<br>void measureCallback() {<br> if
- (pulseBusy) { // already measuring, try again<br>
- tMeasure.enable();<br> return;<br> }<br> pingTrigger(30); // 30
- milliseconds or max range of ~5.1 meters<br>
- tMeasure.setCallback(&measureCallbackWait);<br>}<br></font></font><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><font face="Courier New, monospace"><font size="2" style="font-size: 10pt">//
- Wait for the measurement to <br>void measureCallbackWait() {<br> if
- (pulseBusy) return;<br> tMeasure.setCallback(&measureCallback);
- <br>}<br><br><br>bool state = true;<br><br>void displayCallback() {<br>
- char d[256];<br> <br> unsigned long cm = pingDistance * 17 / 100;
- // cm<br> <br> snprintf(d, 256, "pulseStart =
- %8lu\tpulseStop=%8lu\tdistance, cm=%8lu", pulseStart, pulseStop,
- cm);<br> Serial.println(d);<br> <br>}<br><br>void setup() {<br> //
- put your setup code here, to run once:<br> <br>
- Serial.begin(115200);<br> <br><br> pTrigger = LOW;<br> pEcho =
- LOW;<br> <br>}<br><br>void loop() {<br> // put your main code here,
- to run repeatedly:<br> r.execute();<br>}<br></font></font><br>
- </p>
- <ol start="3">
- <li><p class="western" style="margin-bottom: 0in; page-break-after: avoid">
- <font face="Times New Roman, serif"><b>USING ONENABLE AND ONDISBALE
- METHODS </b></font>
- </p>
- </ol>
- <p class="western" style="margin-bottom: 0in; page-break-after: avoid">
- <br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><font face="Times New Roman, serif">Consider
- a task to flash onboard LED for 5 seconds with random frequency. Task
- should be repeated every 30 seconds indefinitely. Since frequency is
- random, there are two challenges:</font></p>
- <ol start="3">
- <ol>
- <li><p class="western" style="margin-bottom: 0in"><font face="Times New Roman, serif">We
- need to make sure LED is turned OFF at the last iteration</font></p>
- <li><p class="western" style="margin-bottom: 0in"><font face="Times New Roman, serif">We
- need to calculate random frequency every time</font></p>
- </ol>
- </ol>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><font face="Times New Roman, serif">Below
- is the implementation using TaskScheduler </font>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><font face="Courier New, monospace"><font size="2" style="font-size: 10pt"><br></font></font><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><font face="Courier New, monospace"><font size="2" style="font-size: 10pt">#define
- _TASK_SLEEP_ON_IDLE_RUN</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><font face="Courier New, monospace"><font size="2" style="font-size: 10pt">#include
- <TaskScheduler.h></font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><font face="Courier New, monospace"><font size="2" style="font-size: 10pt">#define
- LEDPIN 13</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><font face="Courier New, monospace"><font size="2" style="font-size: 10pt">Scheduler
- ts;</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><font face="Courier New, monospace"><font size="2" style="font-size: 10pt">Task
- tWrapper(30000, TASK_FOREVER, &WrapperCallback, &ts, true);</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><font face="Courier New, monospace"><font size="2" style="font-size: 10pt">Task
- tBlink(5000, TASK_ONCE, NULL, &ts, false, &BlinkOnEnable,
- &BlinkOnDisable);</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><font face="Courier New, monospace"><font size="2" style="font-size: 10pt">Task
- tLED(TASK_IMMEDIATE, TASK_FOREVER, NULL, &ts, false, NULL,
- &LEDOff);</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><font face="Courier New, monospace"><font size="2" style="font-size: 10pt">void
- WrapperCallback() {</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">
- <font face="Courier New, monospace"><font size="2" style="font-size: 10pt">Serial.println("In
- WrapperCallback");</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">
- <font face="Courier New, monospace"><font size="2" style="font-size: 10pt">tBlink.restartDelayed();
- // LED blinking is initiated </font></font>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">
- <font face="Courier New, monospace"><font size="2" style="font-size: 10pt">//every
- 30 seconds for 5 seconds</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><font face="Courier New, monospace"><font size="2" style="font-size: 10pt">}</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><font face="Courier New, monospace"><font size="2" style="font-size: 10pt">//
- Upon being enabled, tBlink will define the parameters</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><font face="Courier New, monospace"><font size="2" style="font-size: 10pt">//
- and enable LED blinking task, which actually controls</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><font face="Courier New, monospace"><font size="2" style="font-size: 10pt">//
- the hardware (LED in this example)</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><font face="Courier New, monospace"><font size="2" style="font-size: 10pt">bool
- BlinkOnEnable() {</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">
- <font face="Courier New, monospace"><font size="2" style="font-size: 10pt">Serial.println("In
- BlinkOnEnable");</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">
- <font face="Courier New, monospace"><font size="2" style="font-size: 10pt">tLED.setInterval(
- 500 + random(501) );</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">
- <font face="Courier New, monospace"><font size="2" style="font-size: 10pt">tLED.setCallback(
- &LEDOn);</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">
- <font face="Courier New, monospace"><font size="2" style="font-size: 10pt">tLED.enable();</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">
- <font face="Courier New, monospace"><font size="2" style="font-size: 10pt">return
- true; // Task should be enabled</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><font face="Courier New, monospace"><font size="2" style="font-size: 10pt">}</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><font face="Courier New, monospace"><font size="2" style="font-size: 10pt">//
- tBlink does not really need a callback method</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><font face="Courier New, monospace"><font size="2" style="font-size: 10pt">//
- since it just waits for 5 seconds for the first </font></font>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><font face="Courier New, monospace"><font size="2" style="font-size: 10pt">//
- and only iteration to occur. Once the iteration</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><font face="Courier New, monospace"><font size="2" style="font-size: 10pt">//
- takes place, tBlink is disabled by the Scheduler, </font></font>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><font face="Courier New, monospace"><font size="2" style="font-size: 10pt">//
- thus executing its OnDisable method below.</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><font face="Courier New, monospace"><font size="2" style="font-size: 10pt">void
- BlinkOnDisable() {</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">
- <font face="Courier New, monospace"><font size="2" style="font-size: 10pt">Serial.println("In
- BlinkOnDisable");</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">
- <font face="Courier New, monospace"><font size="2" style="font-size: 10pt">tLED.disable();</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><font face="Courier New, monospace"><font size="2" style="font-size: 10pt">}</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><font face="Courier New, monospace"><font size="2" style="font-size: 10pt">void
- LEDOn () {</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">
- <font face="Courier New, monospace"><font size="2" style="font-size: 10pt">Serial.println("In
- LEDOn");</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">
- <font face="Courier New, monospace"><font size="2" style="font-size: 10pt">digitalWrite(LEDPIN,
- HIGH);</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">
- <font face="Courier New, monospace"><font size="2" style="font-size: 10pt">tLED.setCallback(
- &LEDOff);</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><font face="Courier New, monospace"><font size="2" style="font-size: 10pt">}</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><font face="Courier New, monospace"><font size="2" style="font-size: 10pt">void
- LEDOff () {</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">
- <font face="Courier New, monospace"><font size="2" style="font-size: 10pt">Serial.println("In
- LEDOff");</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">
- <font face="Courier New, monospace"><font size="2" style="font-size: 10pt">digitalWrite(LEDPIN,
- LOW);</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">
- <font face="Courier New, monospace"><font size="2" style="font-size: 10pt">tLED.setCallback(
- &LEDOn);</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><font face="Courier New, monospace"><font size="2" style="font-size: 10pt">}</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><font face="Courier New, monospace"><font size="2" style="font-size: 10pt">//
- Note that LEDOff method serves as OnDisable method</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><font face="Courier New, monospace"><font size="2" style="font-size: 10pt">//
- to make sure the LED is turned off when the tBlink</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><font face="Courier New, monospace"><font size="2" style="font-size: 10pt">//
- task finishes (or disabled ahead of time)</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><font face="Courier New, monospace"><font size="2" style="font-size: 10pt">void
- setup() {</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">
- <font face="Courier New, monospace"><font size="2" style="font-size: 10pt">Serial.begin(115200);
- </font></font>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">
- <font face="Courier New, monospace"><font size="2" style="font-size: 10pt">pinMode(LEDPIN,
- OUTPUT); </font></font>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><font face="Courier New, monospace"><font size="2" style="font-size: 10pt">}</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><font face="Courier New, monospace"><font size="2" style="font-size: 10pt">void
- loop() {</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">
- <font face="Courier New, monospace"><font size="2" style="font-size: 10pt">//
- put your main code here, to run repeatedly:</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">
- <font face="Courier New, monospace"><font size="2" style="font-size: 10pt">ts.execute();</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><font face="Courier New, monospace"><font size="2" style="font-size: 10pt">}</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <ol start="3">
- <li><p class="western" style="margin-bottom: 0in; page-break-after: avoid">
- <font face="Times New Roman, serif"><b>USING STATUS REQUEST OBJECTS
- </b></font>
- </p>
- </ol>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in; page-break-after: avoid">
- <br>
- </p>
- <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
- test emulates querying 3 sensors once every 10 seconds, each could
- respond with a different delay (ultrasonic sensors for instance) and
- printing a min value of the three when all three have reported their
- values.</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <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
- overall timeout of 1 second is setup as well.</font></font></p>
- <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
- error message needs to be printed if a timeout occurred instead of a
- value.</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><font face="Courier New, monospace"><font size="2" style="font-size: 10pt">#define
- _TASK_SLEEP_ON_IDLE_RUN</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><font face="Courier New, monospace"><font size="2" style="font-size: 10pt">#define
- _TASK_STATUS_REQUEST</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><font face="Courier New, monospace"><font size="2" style="font-size: 10pt">#include
- <TaskScheduler.h></font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><font face="Courier New, monospace"><font size="2" style="font-size: 10pt">StatusRequest
- measure;</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><font face="Courier New, monospace"><font size="2" style="font-size: 10pt">Scheduler
- ts; </font></font>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><font face="Courier New, monospace"><font size="2" style="font-size: 10pt">Task
- tCycle(10000, TASK_FOREVER, &CycleCallback, &ts, true);</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><font face="Courier New, monospace"><font size="2" style="font-size: 10pt">Task
- tMeasure(TASK_SECOND, TASK_ONCE, &MeasureCallback, &ts,
- false, &MeasureEnable, &MeasureDisable);</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><font face="Courier New, monospace"><font size="2" style="font-size: 10pt">Task
- tCalculate(&CalcCallback, &ts);</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><font face="Courier New, monospace"><font size="2" style="font-size: 10pt">Task
- tSensor1(TASK_IMMEDIATE, TASK_ONCE, &S1Callback, &ts, false,
- &S1Enable);</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><font face="Courier New, monospace"><font size="2" style="font-size: 10pt">Task
- tSensor2(TASK_IMMEDIATE, TASK_ONCE, &S2Callback, &ts, false,
- &S2Enable);</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><font face="Courier New, monospace"><font size="2" style="font-size: 10pt">Task
- tSensor3(TASK_IMMEDIATE, TASK_ONCE, &S3Callback, &ts, false,
- &S3Enable);</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><font face="Courier New, monospace"><font size="2" style="font-size: 10pt">long
- distance, d1, d2, d3;</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><font face="Courier New, monospace"><font size="2" style="font-size: 10pt">void
- CycleCallback() {</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">
- <font face="Courier New, monospace"><font size="2" style="font-size: 10pt">Serial.println("CycleCallback:
- Initiating measurement cycle every 10 seconds");</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">
- <font face="Courier New, monospace"><font size="2" style="font-size: 10pt">tMeasure.restartDelayed();</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><font face="Courier New, monospace"><font size="2" style="font-size: 10pt">}</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><font face="Courier New, monospace"><font size="2" style="font-size: 10pt">bool
- MeasureEnable() {</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">
- <font face="Courier New, monospace"><font size="2" style="font-size: 10pt">Serial.println("MeasureEnable:
- Activating sensors"); </font></font>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">
- <font face="Courier New, monospace"><font size="2" style="font-size: 10pt">distance
- = 0;</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">
- <font face="Courier New, monospace"><font size="2" style="font-size: 10pt">measure.setWaiting(3);
- // Set the StatusRequest to wait for 3 signals. </font></font>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">
- <font face="Courier New, monospace"><font size="2" style="font-size: 10pt">tCalculate.waitFor(&measure);</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">
- <font face="Courier New, monospace"><font size="2" style="font-size: 10pt">tSensor1.restart();</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">
- <font face="Courier New, monospace"><font size="2" style="font-size: 10pt">tSensor2.restart();</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">
- <font face="Courier New, monospace"><font size="2" style="font-size: 10pt">tSensor3.restart();</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">
- <font face="Courier New, monospace"><font size="2" style="font-size: 10pt">return
- true;</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><font face="Courier New, monospace"><font size="2" style="font-size: 10pt">}</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><font face="Courier New, monospace"><font size="2" style="font-size: 10pt">void
- MeasureCallback() {</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">
- <font face="Courier New, monospace"><font size="2" style="font-size: 10pt">Serial.println("MeasureCallback:
- Invoked by calculate task or one second later"); </font></font>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">
- <font face="Courier New, monospace"><font size="2" style="font-size: 10pt">if
- (measure.pending()) {</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">
- <font face="Courier New, monospace"><font size="2" style="font-size: 10pt">tCalculate.disable();</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">
- <font face="Courier New, monospace"><font size="2" style="font-size: 10pt">measure.signalComplete(-1);
- // signal error</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">
- <font face="Courier New, monospace"><font size="2" style="font-size: 10pt">Serial.println("MeasureCallback:
- Timeout!");</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">
- <font face="Courier New, monospace"><font size="2" style="font-size: 10pt">}</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">
- <font face="Courier New, monospace"><font size="2" style="font-size: 10pt">else
- {</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">
- <font face="Courier New, monospace"><font size="2" style="font-size: 10pt">Serial.print("MeasureCallback:
- Min distance=");Serial.println(distance);</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">
- <font face="Courier New, monospace"><font size="2" style="font-size: 10pt">}</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><font face="Courier New, monospace"><font size="2" style="font-size: 10pt">}</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><font face="Courier New, monospace"><font size="2" style="font-size: 10pt">void
- MeasureDisable() {</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">
- <font face="Courier New, monospace"><font size="2" style="font-size: 10pt">Serial.println("MeasureDisable:
- Cleaning up"); </font></font>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">
- <font face="Courier New, monospace"><font size="2" style="font-size: 10pt">tSensor1.disable();</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">
- <font face="Courier New, monospace"><font size="2" style="font-size: 10pt">tSensor2.disable();</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">
- <font face="Courier New, monospace"><font size="2" style="font-size: 10pt">tSensor3.disable();</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><font face="Courier New, monospace"><font size="2" style="font-size: 10pt">}</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><font face="Courier New, monospace"><font size="2" style="font-size: 10pt">void
- CalcCallback() {</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">
- <font face="Courier New, monospace"><font size="2" style="font-size: 10pt">Serial.println("CalcCallback:
- calculating"); </font></font>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">
- <font face="Courier New, monospace"><font size="2" style="font-size: 10pt">distance
- = -1;</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">
- <font face="Courier New, monospace"><font size="2" style="font-size: 10pt">if
- ( measure.getStatus() >= 0) { // only calculate if statusrequest
- ended successfully</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">
- <font face="Courier New, monospace"><font size="2" style="font-size: 10pt">distance
- = d1 < d2 ? d1 : d2;</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">
- <font face="Courier New, monospace"><font size="2" style="font-size: 10pt">distance
- = d3 < distance ? d3 : distance;</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">
- <font face="Courier New, monospace"><font size="2" style="font-size: 10pt">tMeasure.forceNextIteration();</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">
- <font face="Courier New, monospace"><font size="2" style="font-size: 10pt">}</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><font face="Courier New, monospace"><font size="2" style="font-size: 10pt">}</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><font face="Courier New, monospace"><font size="2" style="font-size: 10pt">/**
- Simulation code for sensor 1</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"> <font face="Courier New, monospace"><font size="2" style="font-size: 10pt">*
- ----------------------------</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">
- <font face="Courier New, monospace"><font size="2" style="font-size: 10pt">*/</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><font face="Courier New, monospace"><font size="2" style="font-size: 10pt">bool
- S1Enable() {</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">
- <font face="Courier New, monospace"><font size="2" style="font-size: 10pt">Serial.print("S1Enable:
- Triggering sensor1. Delay="); </font></font>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">
- <font face="Courier New, monospace"><font size="2" style="font-size: 10pt">tSensor1.setInterval(
- random(1200) ); // Simulating sensor delay, which could go over 1
- second and cause timeout</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">
- <font face="Courier New, monospace"><font size="2" style="font-size: 10pt">d1
- = 0;</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">
- <font face="Courier New, monospace"><font size="2" style="font-size: 10pt">Serial.println(
- tSensor1.getInterval() );</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">
- <font face="Courier New, monospace"><font size="2" style="font-size: 10pt">return
- true;</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><font face="Courier New, monospace"><font size="2" style="font-size: 10pt">}</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><font face="Courier New, monospace"><font size="2" style="font-size: 10pt">void
- S1Callback() {</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">
- <font face="Courier New, monospace"><font size="2" style="font-size: 10pt">Serial.print("S1Callback:
- Emulating measurement. d1="); </font></font>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">
- <font face="Courier New, monospace"><font size="2" style="font-size: 10pt">d1
- = random(501); // pick a value from 0 to 500 "centimeters"
- simulating a measurement </font></font>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">
- <font face="Courier New, monospace"><font size="2" style="font-size: 10pt">measure.signal();</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">
- <font face="Courier New, monospace"><font size="2" style="font-size: 10pt">Serial.println(d1);
- </font></font>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><font face="Courier New, monospace"><font size="2" style="font-size: 10pt">}</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><font face="Courier New, monospace"><font size="2" style="font-size: 10pt">/**
- Simulation code for sensor 2</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"> <font face="Courier New, monospace"><font size="2" style="font-size: 10pt">*
- ----------------------------</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">
- <font face="Courier New, monospace"><font size="2" style="font-size: 10pt">*/</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><font face="Courier New, monospace"><font size="2" style="font-size: 10pt">bool
- S2Enable() {</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">
- <font face="Courier New, monospace"><font size="2" style="font-size: 10pt">Serial.print("S2Enable:
- Triggering sensor2. Delay="); </font></font>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">
- <font face="Courier New, monospace"><font size="2" style="font-size: 10pt">tSensor2.setInterval(
- random(1200) ); // Simulating sensor delay, which could go over 1
- second and cause timeout</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">
- <font face="Courier New, monospace"><font size="2" style="font-size: 10pt">d2
- = 0;</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">
- <font face="Courier New, monospace"><font size="2" style="font-size: 10pt">Serial.println(
- tSensor2.getInterval() );</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">
- <font face="Courier New, monospace"><font size="2" style="font-size: 10pt">return
- true;</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><font face="Courier New, monospace"><font size="2" style="font-size: 10pt">}</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><font face="Courier New, monospace"><font size="2" style="font-size: 10pt">void
- S2Callback() {</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">
- <font face="Courier New, monospace"><font size="2" style="font-size: 10pt">Serial.print("S2Callback:
- Emulating measurement. d2="); </font></font>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">
- <font face="Courier New, monospace"><font size="2" style="font-size: 10pt">d2
- = random(501); // pick a value from 0 to 500 "centimeters"
- simulating a measurement</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">
- <font face="Courier New, monospace"><font size="2" style="font-size: 10pt">measure.signal();</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">
- <font face="Courier New, monospace"><font size="2" style="font-size: 10pt">Serial.println(d2);
- </font></font>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><font face="Courier New, monospace"><font size="2" style="font-size: 10pt">}</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><font face="Courier New, monospace"><font size="2" style="font-size: 10pt">/**
- Simulation code for sensor 3</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"> <font face="Courier New, monospace"><font size="2" style="font-size: 10pt">*
- ----------------------------</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">
- <font face="Courier New, monospace"><font size="2" style="font-size: 10pt">*/</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><font face="Courier New, monospace"><font size="2" style="font-size: 10pt">bool
- S3Enable() {</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">
- <font face="Courier New, monospace"><font size="2" style="font-size: 10pt">Serial.print("S3Enable:
- Triggering sensor3. Delay="); </font></font>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">
- <font face="Courier New, monospace"><font size="2" style="font-size: 10pt">tSensor3.setInterval(
- random(1200) ); // Simulating sensor delay, which could go over 1
- second and cause timeout</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">
- <font face="Courier New, monospace"><font size="2" style="font-size: 10pt">d3
- = 0;</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">
- <font face="Courier New, monospace"><font size="2" style="font-size: 10pt">Serial.println(
- tSensor3.getInterval() );</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">
- <font face="Courier New, monospace"><font size="2" style="font-size: 10pt">return
- true;</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><font face="Courier New, monospace"><font size="2" style="font-size: 10pt">}</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><font face="Courier New, monospace"><font size="2" style="font-size: 10pt">void
- S3Callback() {</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">
- <font face="Courier New, monospace"><font size="2" style="font-size: 10pt">Serial.print("S3Callback:
- Emulating measurement. d3="); </font></font>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">
- <font face="Courier New, monospace"><font size="2" style="font-size: 10pt">d3
- = random(501); // pick a value from 0 to 500 "centimeters"
- simulating a measurement</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">
- <font face="Courier New, monospace"><font size="2" style="font-size: 10pt">measure.signal();</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">
- <font face="Courier New, monospace"><font size="2" style="font-size: 10pt">Serial.println(d3);
- </font></font>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><font face="Courier New, monospace"><font size="2" style="font-size: 10pt">}</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><font face="Courier New, monospace"><font size="2" style="font-size: 10pt">/**
- Main Arduino code</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"> <font face="Courier New, monospace"><font size="2" style="font-size: 10pt">*
- Not much is left here - everything is taken care of by the framework</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">
- <font face="Courier New, monospace"><font size="2" style="font-size: 10pt">*/</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><font face="Courier New, monospace"><font size="2" style="font-size: 10pt">void
- setup() {</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">
- <font face="Courier New, monospace"><font size="2" style="font-size: 10pt">Serial.begin(115200);</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">
- <font face="Courier New, monospace"><font size="2" style="font-size: 10pt">Serial.println("TaskScheduler
- StatusRequest Sensor Emulation Test. Complex Test."); </font></font>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">
- <font face="Courier New, monospace"><font size="2" style="font-size: 10pt">randomSeed(analogRead(A1)+millis());</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><font face="Courier New, monospace"><font size="2" style="font-size: 10pt">}</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><font face="Courier New, monospace"><font size="2" style="font-size: 10pt">void
- loop() {</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in">
- <font face="Courier New, monospace"><font size="2" style="font-size: 10pt">ts.execute();</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><font face="Courier New, monospace"><font size="2" style="font-size: 10pt">}</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <ol start="3">
- <li><p class="western" style="margin-bottom: 0in; page-break-after: avoid">
- <font face="Times New Roman, serif"><b>USING LOCAL TASK STORAGE
- POINTER </b></font>
- </p>
- </ol>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in; page-break-after: avoid">
- <br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><font face="Times New Roman, serif"><font size="2" style="font-size: 11pt">Tasks
- can store a pointer to specific variable, structure or array, which
- represents variables specific for a particular task. This may be
- needed if you plan to use same callback method for multiple tasks.</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><font face="Times New Roman, serif"><font size="2" style="font-size: 11pt">Consider
- a scenario where you have several sensors of the same type. The
- actual process of triggering measurement and collecting information
- is identical. The only difference is the sensor address and a
- variable for storing the results. </font></font>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><font face="Times New Roman, serif"><font size="2" style="font-size: 11pt">In
- this case each of the tasks, which performs measurement will utilize
- the same callback methods. The only difference will be the variables
- (specific for each of the sensor). </font></font>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><font face="Times New Roman, serif"><font size="2" style="font-size: 11pt">Let's
- define a sensor data structure and declare a couple of variables (for
- 2 sensors for instance)</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p lang="en-US" class="western" style="margin-left: 0.98in; margin-bottom: 0in">
- <font face="Courier New, monospace"><font size="2" style="font-size: 10pt">typedef
- struct {</font></font></p>
- <p lang="en-US" class="western" style="margin-left: 0.98in; margin-bottom: 0in">
- <font face="Courier New, monospace"><font size="2" style="font-size: 10pt"> unsigned
- int address;</font></font></p>
- <p lang="en-US" class="western" style="margin-left: 0.98in; margin-bottom: 0in">
- <font face="Courier New, monospace"><font size="2" style="font-size: 10pt"> unsigned
- long distance;</font></font></p>
- <p lang="en-US" class="western" style="margin-left: 0.98in; margin-bottom: 0in">
- <font face="Courier New, monospace"><font size="2" style="font-size: 10pt">}
- sensor_data;</font></font></p>
- <p lang="en-US" class="western" style="margin-left: 0.98in; margin-bottom: 0in">
- <br>
- </p>
- <p lang="en-US" class="western" style="margin-left: 0.98in; margin-bottom: 0in">
- <font face="Courier New, monospace"><font size="2" style="font-size: 10pt">sensor_data
- s1, s2; </font></font>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><font face="Times New Roman, serif"><font size="2" style="font-size: 11pt">Two
- separate tasks are running to collect sensor data.</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><font face="Times New Roman, serif"><font size="2" style="font-size: 11pt">(Note
- that both tasks refer to the same callback methods)</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p lang="en-US" class="western" style="margin-left: 0.98in; margin-bottom: 0in">
- <font face="Courier New, monospace"><font size="2" style="font-size: 10pt">Scheduler
- ts;</font></font></p>
- <p class="western" style="margin-left: 0.98in; margin-bottom: 0in"><font face="Courier New, monospace"><font size="2" style="font-size: 10pt"><span lang="en-US">Task
- t1(100, </span></font></font><font face="Courier New, monospace"><font size="2" style="font-size: 10pt">TASK_FOREVER</font></font><font face="Courier New, monospace"><font size="2" style="font-size: 10pt"><span lang="en-US">,
- &Measure, &ts, false, &MeasureOn); </span></font></font>
- </p>
- <p class="western" style="margin-left: 0.98in; margin-bottom: 0in"><font face="Courier New, monospace"><font size="2" style="font-size: 10pt"><span lang="en-US">Task
- t2(100, </span></font></font><font face="Courier New, monospace"><font size="2" style="font-size: 10pt">TASK_FOREVER</font></font><font face="Courier New, monospace"><font size="2" style="font-size: 10pt"><span lang="en-US">,
- &Measure, &ts, false, &MeasureOn); </span></font></font>
- </p>
- <p class="western" style="margin-left: 0.98in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><font face="Times New Roman, serif"><font size="2" style="font-size: 11pt">Assign
- pointers to the respective variables in the </font></font><font face="Times New Roman, serif"><font size="2" style="font-size: 11pt"><b>setup</b></font></font><font face="Times New Roman, serif"><font size="2" style="font-size: 11pt">()
- method:</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.98in; margin-bottom: 0in"><font face="Courier New, monospace"><font size="2" style="font-size: 10pt">void
- setup() {</font></font></p>
- <p class="western" style="margin-left: 0.98in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 1.48in; margin-bottom: 0in">…</p>
- <p class="western" style="margin-left: 1.48in; margin-bottom: 0in"><font face="Courier New, monospace"><font size="2" style="font-size: 10pt">t1.setLtsPointer(&s1);</font></font></p>
- <p class="western" style="margin-left: 1.48in; margin-bottom: 0in"><font face="Courier New, monospace"><font size="2" style="font-size: 10pt">t2.setLtsPointer(&s2);</font></font></p>
- <p class="western" style="margin-left: 1.48in; margin-bottom: 0in">…</p>
- <p class="western" style="margin-left: 0.98in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.98in; margin-bottom: 0in"><font face="Courier New, monospace"><font size="2" style="font-size: 10pt">}</font></font></p>
- <p class="western" style="margin-left: 0.98in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><font face="Times New Roman, serif"><font size="2" style="font-size: 11pt">Obtain
- reference to specific </font></font><font face="Times New Roman, serif"><font size="2" style="font-size: 11pt"><b>sensor_data</b></font></font><font face="Times New Roman, serif"><font size="2" style="font-size: 11pt">
- structure inside the common callback method:</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.98in; margin-bottom: 0in"><font face="Courier New, monospace"><font size="2" style="font-size: 10pt">void
- Measure() {</font></font></p>
- <p class="western" style="margin-left: 0.98in; margin-bottom: 0in"><font face="Courier New, monospace"><font size="2" style="font-size: 10pt"> Task&
- T = ts.currentTask(); </font></font>
- </p>
- <p class="western" style="margin-left: 0.98in; margin-bottom: 0in"><font face="Courier New, monospace"><font size="2" style="font-size: 10pt"> Sensor_data&
- V = *((sensor_data*) T.getLtsPointer());</font></font></p>
- <p class="western" style="margin-left: 0.98in; margin-bottom: 0in"><font face="Courier New, monospace"><font size="2" style="font-size: 10pt">//
- For t1, V will be pointing at s1</font></font></p>
- <p class="western" style="margin-left: 0.98in; margin-bottom: 0in"><font face="Courier New, monospace"><font size="2" style="font-size: 10pt">//
- For t2, V will be pointing at s2</font></font></p>
- <p class="western" style="margin-left: 0.98in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.98in; margin-bottom: 0in"><font face="Courier New, monospace"><font size="2" style="font-size: 10pt">//
- Alternatively use the Scheduler method:</font></font></p>
- <p class="western" style="margin-left: 0.98in; margin-bottom: 0in"><font face="Courier New, monospace"><font size="2" style="font-size: 10pt"> Sensor_data&
- V1 = *((sensor_data*) ts.currentLts());</font></font></p>
- <p class="western" style="margin-left: 0.98in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.98in; text-indent: 0.49in; margin-bottom: 0in">
- …</p>
- <p class="western" style="margin-left: 0.98in; margin-bottom: 0in"><font face="Courier New, monospace"><font size="2" style="font-size: 10pt"> V.distance
- = <calculate your values here>;</font></font></p>
- <p class="western" style="margin-left: 0.98in; margin-bottom: 0in"><font face="Courier New, monospace"><font size="2" style="font-size: 10pt">}</font></font></p>
- <p class="western" style="margin-left: 0.98in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <ol start="3">
- <li><p class="western" style="margin-bottom: 0in; page-break-after: avoid">
- <font face="Times New Roman, serif"><b>ENABLING TASK PRIORITIZATION
- </b></font>
- </p>
- </ol>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in; page-break-after: avoid">
- <br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><font face="Times New Roman, serif"><font size="2" style="font-size: 11pt">In
- certain cases you want a task to be invoked before others in case of
- scheduling collision (tasks ready to be invoked at the same time). In
- a flat execution chain scenario tasks are evaluated for execution in
- the order they were added to the chain. Therefore a single task has
- to wait for the rest of the chain to be evaluated to get a chance
- again. </font></font>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><font face="Times New Roman, serif"><font size="2" style="font-size: 11pt">Consider
- a scenario where a task taking gyroscope measurements has to be
- invoked as close to the actual scheduling time as possible. That is
- when task prioritization comes to help. </font></font>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><font face="Times New Roman, serif"><font size="2" style="font-size: 11pt">Let’s
- say tasks t4 and t5 are taking measurements from gyroscope and
- accelerometer, and tasks t1, t2 and t3 are doing something less
- important.</font></font></p>
- <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
- is how such setup is coded:</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.98in; margin-bottom: 0in"><font face="Courier New, monospace"><font size="2" style="font-size: 10pt">#define
- _TASK_PRIORITY</font></font></p>
- <p class="western" style="margin-left: 0.98in; margin-bottom: 0in"><font face="Courier New, monospace"><font size="2" style="font-size: 10pt">#include
- <TaskScheduler.h></font></font></p>
- <p class="western" style="margin-left: 0.98in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.98in; margin-bottom: 0in"><font face="Courier New, monospace"><font size="2" style="font-size: 10pt">Scheduler
- r, hpr;</font></font></p>
- <p class="western" style="margin-left: 0.98in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.98in; margin-bottom: 0in"><font face="Courier New, monospace"><font size="2" style="font-size: 10pt">//
- Tasks</font></font></p>
- <p class="western" style="margin-left: 0.98in; margin-bottom: 0in"><font face="Courier New, monospace"><font size="2" style="font-size: 10pt">Task
- t1(1000, TASK_FOREVER, &tCallback, &r); //base priority</font></font></p>
- <p class="western" style="margin-left: 0.98in; margin-bottom: 0in"><font face="Courier New, monospace"><font size="2" style="font-size: 10pt">Task
- t2(2000, TASK_FOREVER, &tCallback, &r);</font></font></p>
- <p class="western" style="margin-left: 0.98in; margin-bottom: 0in"><font face="Courier New, monospace"><font size="2" style="font-size: 10pt">Task
- t3(3000, TASK_FOREVER, &tCallback, &r);</font></font></p>
- <p class="western" style="margin-left: 0.98in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.98in; margin-bottom: 0in"><font face="Courier New, monospace"><font size="2" style="font-size: 10pt">Task
- t4(10, TASK_FOREVER, &tCallback, &hpr); // higher priority</font></font></p>
- <p class="western" style="margin-left: 0.98in; margin-bottom: 0in"><font face="Courier New, monospace"><font size="2" style="font-size: 10pt">Task
- t5(100, TASK_FOREVER, &tCallback, &hpr); //higher priority</font></font></p>
- <p class="western" style="margin-left: 0.98in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.98in; margin-bottom: 0in">…</p>
- <p class="western" style="margin-left: 0.98in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.98in; margin-bottom: 0in"><font face="Courier New, monospace"><font size="2" style="font-size: 10pt">void
- setup () {</font></font></p>
- <p class="western" style="margin-left: 0.98in; margin-bottom: 0in">
- </p>
- <p class="western" style="margin-left: 0.98in; margin-bottom: 0in">
- …</p>
- <p class="western" style="margin-left: 0.98in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.98in; margin-bottom: 0in">
- <font face="Courier New, monospace"><font size="2" style="font-size: 10pt">r.setHighPriorityScheduler(&hpr);
- </font></font>
- </p>
- <p class="western" style="margin-left: 0.98in; margin-bottom: 0in">
- <font face="Courier New, monospace"><font size="2" style="font-size: 10pt">r.enableAll(true);
- // this will recursively enable the higher priority tasks as well</font></font></p>
- <p class="western" style="margin-left: 0.98in; margin-bottom: 0in"><font face="Courier New, monospace"><font size="2" style="font-size: 10pt">}</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <ol start="3">
- <li><p class="western" style="margin-bottom: 0in"><font face="Times New Roman, serif"><b>FUTHER
- INFROMATION</b></font></p>
- </ol>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><font face="Courier New, monospace"><font size="2" style="font-size: 10pt">Please
- refer to examples, provided with TaskScheduler package for further
- information and implementation options.</font></font></p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><br>
- </p>
- <p class="western" style="margin-left: 0.49in; margin-bottom: 0in"><font face="Courier New, monospace"><font size="2" style="font-size: 10pt">Real
- time examples of TaskScheduler are available here:</font></font></p>
- <ol>
- <li><p class="western" style="margin-bottom: 0in"><font color="#0000ff"><u><a href="http://www.instructables.com/id/APIS-Automated-Plant-Irrigation-System/"><font face="Courier New, monospace">http://www.instructables.com/id/APIS-Automated-Plant-Irrigation-System/</font></a></u></font></p>
- <li><p class="western" style="margin-bottom: 0in"><font color="#0000ff"><u><a href="http://www.instructables.com/id/Wave-your-hand-to-control-OWI-Robotic-Arm-no-strin/"><font face="Courier New, monospace">http://www.instructables.com/id/Wave-your-hand-to-control-OWI-Robotic-Arm-no-strin/</font></a></u></font></p>
- <li><p class="western" style="margin-bottom: 0in"><font color="#0000ff"><u><a href="http://www.instructables.com/id/Arduino-Nano-based-Hexbug-Scarab-Robotic-Spider"><font face="Courier New, monospace">http://www.instructables.com/id/Arduino-Nano-based-Hexbug-Scarab-Robotic-Spider</font></a></u></font></p>
- </ol>
- <p class="western" style="margin-bottom: 0in"><br>
- </p>
- <div title="footer">
- <p style="margin-top: 0.35in; margin-bottom: 0in"> <sdfield type=PAGE subtype=RANDOM format=ARABIC>34</sdfield></p>
- </div>
- </body>
- </html>
|