Czech English

XX. "Multitasking"

aneb více úloh současně

V první lekci Blikáme LEDkou jsem zadal úkol napsat program na současné blikání dvou LED různou frekvencí. Abyste to byli schopni zvládnout s dosavadními znalostmi, tak byly periody blikání zvoleny "hezky". Pokud to budou libovolné hodnoty, úloha se podstatně ztíží. Řešení nejen této úlohy je tématem dnešní lekce.



Motivace

  • Potřeba současného zpracovávání více úloh
  • Oddělení nezávislých částí programu
  • Vytvoření samostatných softwarových opakovatelně použitelných modulů


Vánoční stromeček - 7 "současně" běžících úloh

Přímočaré řešení

Vrátíme se tedy k původní úloze a ukážeme si "jednoduché" řešení. Úkolem je blikat současně dvěmi LED. Přičemž jedna bliká s periodu 1s (0,5s svítí a 0,5s je zhasnutá) a druhá s periodou 0,5s (0,25s svítí a 0,25s je zhasnutá).
Požadovaný průběh signálů na výstupech mikrokontroleru si můžeme znázornit v grafu:

Z obrázku vidíme, že:
    v čase 0s: zapneme obě LED
    v čase 0,25s: vypneme LED2
    v čase 0,5s: vypneme LED1 a zapneme LED2
    v čase 0,75s: vypneme LED2
    V čase 1s: zapneme obě LED (jako v čase 0s ... děj se začíná opakovat)
Musíme tedy popsat průběh jednoho cyklu (trvajícího 1s). Program by tedy mohl vypadat takto:

Nevýhody

  • Při změně hodnot period blikání, nutno program předělat.
  • Pokud budou požadované hodnoty period blikání nesoudělná čísla, pak „neřešitelné“.
  • Program nic rozumného nedělá.
    • - samotná operace rozsvícení nebo zhasnutí LED trvá několik mikrosekund a pak mikrokontroler 250 milisekund čeká (nic užitečného nedělá). Přitom by mohl vykonávat nějakou jinou úlohu.

Řešení

Od teď je

delay()

sprosté slovo!
A ta se ve slušné společnosti nepoužívají !!!

Polling (dotazování)

Jednou z jednoduchých a velmi elegantních metod je tzv. polling (dotazování). Program tak, jak jsme už zvyklí, probíhá ve smyčce. Testuje příznaky událostí (podmínky, kdy má něco nastat) a pokud je podmínka splněna, tak provede nějakou akci. Takto se může "současně" zpracovávat větší počet úloh, které jsou na sobě nezávislé.
Ukážeme si to příkladu našich dvou blikajících LED. Podmínkou pro změnu stavu výstupu řídicího LED je dosažení určitého času. Využijeme toho, že v arduinu "běží" čas (funkce millis() vrací počet ms od "spuštění" programu). Tzn. stačí porovnat aktuální čas s určenou hodnotou a víme, zda se má stav LED změnit.
Nejprve si to ukážeme pro jednu led:
1. vytvoříme si proměnnou (časovou značku), do které si uložíme čas, od kterého budeme čas měřit
2. ve smyčce Loop kontroluji, zda čas od nastavení časové značky už dosáhl požadované doby
3. pokud ano, provedu akci a posunu časovou značku o požadovanou periodu
Tento program, dělá to samé, co náš úplně první program. S tím rozdílem, že mikrokontroler nikde nečeká a tedy může dělat i jinou činnost.
Pro více současných akcí, uděláme pro každou událost vlastní časovou značku, jinak vše zůstane stejné.

Vyčlenění částí kódu do funkcí

  • Program pro Arduino je rozdělen na část nastavení (setup) a opakovaně prováděnou část (loop).
  • Z částí kódu jednotlivých úloh uděláme funkce, které provádějí odpovídající činnost .
  • Tím dojde k výraznému zpřehlednění programu.

Rozdělení úloh do souborů

Funkce jednotlivých úloh umístíme do samostatných souborů.
  • Program se zkrátí
  • Realizaci těchto úloh můžeme používat opakovaně (tj. vytvořit si vlastní knihovnu).
  • Vlastní kód je v souboru XXX.cpp
  • V hlavičkovém souboru XXX.h jsou definice, pro „přístup z hlavního programu“.

Zapouzdření do objektů

  • Problémem je, pokud potřebujeme realizovat dvě stejné úlohy na jiných datech (např. pinech).
  • Jedno z řešení je použití objektů.
  • Vytvoříme si odpovídající počet objektů daného typu. Použitím jejich metod se vždy přistupuje ke správným datům.

Zdrojové kódy jednotlivých příkladů

[1] led 1
[2] led 2
[3] led 3
[4] led 4
[5] led 5
[6] led 6
[7] led 7