Ako súčasne vykonávať viacero úloh alebo procesov (Multitasking) s Arduino

Povedzme, že máte projekt Arduino, v ktorom chcete vykonávať niekoľko akcií súčasne:

Napríklad – čítať údaje z používateľského vstupu, rozblikať niektoré LED-pin diódy, monitorovať potenciometer atď. Takže v podstate chcete robiť s Arduinom nejaký multitasking.

arduino-multitasking

A to je miesto, kde sa veci trochu skomplikujú, najmä ak ste už zvyknutí vytvárať nové vlákna vždy, keď potrebujete spustiť nový paralelný program. Skutočné multithreading na Arduine nie je možné robiť.

Skutočné-multithreading-na Arduine-nie-je-možné-robiť.

Ale mám pre vás dobrú správu:

S Arduinom môžete stále vykonávať multitasking. Všetko, čo potrebujete, je trochu pochopenia, aby veci fungovali hladko! Predtým, ako vám vysvetlím, ako robiť multitasking s Arduinom, pozrime sa, prečo nemôžete robiť „štandardné“ paralelné programovanie.

ako-na-arduino

Rozdiel medzi počítačom, ako je laptop alebo webový server, a elektronickou doskou s mikrokontrolérom (Arduino) :

„Mozgom“ dosky Arduino je mikrokontrolér (ATmega328 pre Arduino Uno). Mikrokontrolér má iba jedno jadro a je schopný naraz vykonávať iba jednu inštrukciu. Takže, ak sa rozhodnete urobiť pauzu vo funkcii, potom sa celý váš program zasekne a čaká. Vždy, keď niečo napíšete, musíte myslieť na to, aký to bude mať dopad na celý kód.

Ak budete robiť malé akcie a robiť ich veľmi rýchlo, jednu po druhej, získate pocit multitaskingu. To je princíp multitaskingu s Arduino. Ukážme si to na optickej ilúzii.

arduino-multitasking-ako-to-urobiť?

Ak si vezmete jeden modrý papier a jeden červený papier a veľmi rýchlo ich striedate pred vašimi očami (aspoň 10-krát za sekundu), uvidíte fialovú farbu. Pretože zmena medzi farbami prebieha tak rýchlo, získate ilúziu, že všetky farby sú zmiešané do inej farby. To je zhruba to, čo je multitasking s Arduino, ale s oveľa vyššou frekvenciou.

Ak chcete vykonávať multitasking s Arduino, postupujte podľa týchto tipov:

  • Udržujte čas vykonania všetkých vašich funkcií veľmi krátky. Nehovorím, že vaše funkcie by mali mať maximálne (x) riadkov kódu. Hovorím, že by ste mali sledovať čas vykonania a uistiť sa, že je dosť krátky.
  • Nepoužívajte funkciu delay(). Táto funkcia úplne zablokuje váš program. Ako uvidíme nižšie na príklade kódu, existujú aj iné spôsoby, ako dosiahnuť rovnaké správanie ako pri funkcii delay().
  • Ak váš program počúva vstup používateľa, napríklad textovú správu cez sériovú komunikáciu, potom to znamená, že nemáte kontrolu nad tým, kedy sa táto udalosť stane, pretože je z externého zdroja. Najjednoduchší spôsob, ako získať vstup od používateľa, je počkať naň a potom pokračovať v vykonávaní programu, keď získate údaje.
  • Na dlhšie procesy použite niečo ako stavový automat. Povedzme, že máte proces, ktorý skutočne vyžaduje veľa rôznych akcií a určitý čas na čakanie medzi dvoma akciami. V takom prípade by ste mali tento proces rozdeliť na niekoľko malých funkcií (pozri prvý bod vyššie) a vytvoriť stavový automat vo svojom hlavnom programe, aby ste ich v prípade potreby mohli volať jeden po druhom. To vám umožní vypočítať aj akúkoľvek inú časť programu medzi 2 krokmi procesu.

Schéma

Zapojenie, ktoré budeme ovládať

miltitasking-arduino-uno-schéma

Čo všetko tu mame

  • 4 LED-pindiódy pripojené k 4 digitálnym pinom (ako výstup). Odpory sú 220 ohmov.
  • 1 tlačidlo pripojené k 1 digitálnemu kolíku (ako vstup). Rezistor je 10 kOhm.
  • 1 potenciometer pripojený k 1 analógovému kolíku (ako vstup).
  • A ešte (nezobrazuje sa) jedna sériová komunikácia cez USB kábel s počítačom.

Čo chceme robiť:

  • Každú sekundu blikne LED-pin 1.
  • Prečítať si vstup používateľa cez seriál port (hodnota potenciometru) (číslo medzi 0 a 255) a zapísať údaje do LED-pin číslo 2.
  • Zapnúť LED-pin 3, ak je stlačené tlačidlo.
  • Zapnúť LED-pin 4, ak je hodnota potenciometra väčšia ako 512.
  • Zobraziť hodnotu potenciometra cez seriál port každé 2 sekundy.

Jednoducho rozdelíme kód na malé kúsky kódu, ktoré sa veľmi rýchlo vykonávajú. Jeden malý kúsok kódu pre jednu úlohu.

Rozoberme si kód krok za krokom, aby ste pochopili, o čom to je

Nastavenie :

Len pre prehľadnosť som použil niektoré #define na použitie mien namiesto čísel pre všetky hardvérové ​​piny. Tiež som deklaroval niektoré premenné na sledovanie času.

Ako viete, funkcia setup() sa na Arduine volá najskôr. Tu iba inicializujeme sériovú komunikáciu a nastavíme správny režim pre digitálne kolíky (analógové kolíky nevyžadujú nastavenie, pretože sú automaticky nastavené ako vstupné kolíky).

A… skočíme priamo do funkcie loop()! Táto funkcia sa bude volať znova a znova, kým bude trvať váš program. Prvá vec, ktorú tu urobíme, je získať aktuálny čas pomocou millis(). Toto je veľmi dôležité. Pri väčšine čiastkových úloh programu použijeme určité techniky sledovania času na spustenie akcie, čím sa vyhneme použitiu funkcie delay().

Úloha 1: Každú sekundu zablikajte LED-pin 1

Tu vypočítame trvanie medzi aktuálnym časom a posledným spustením LED-pin 1. Ak je trvanie dlhšie ako interval, ktorý sme predtým nastavili (tu 1 sekunda), môžeme skutočne vykonať akciu! Všimnite si, že keď vstúpime do bloku if, nastavíme predchádzajúci čas ako aktuálny.

Týmto spôsobom hovoríme programu: „nevracaj sa sem, kým neuplynie ďalší časový interval“. Používanie tejto štruktúry kódu je v Arduine celkom bežné. Ak to nepoznáte, nájdite si čas na napísanie kódu a vyskúšajte niekoľko príkladov sami. Keď pochopíte, ako to funguje, budete ho používať všade vo svojich programoch Arduino!

Úloha 2: Prečítajte si vstup používateľa zo sériového čísla (číslo medzi 0 a 255) a zapíšte údaje do LED-pin 2

Musíme počúvať seriál, aby sme mohli získať vstup od používateľa. Namiesto blokovania jednoducho zavoláme metódu Serial.available() zakaždým, keď sme vo funkcii main loop(). Keďže všetky ostatné bloky kódu sú dosť malé a rýchle, môžeme očakávať, že Serial bude monitorovaný pomerne často. Týmto spôsobom máme istotu, že nám pri vykonávaní akejkoľvek inej akcie na strane neuniknú žiadne údaje.

Úloha 3: Zapnite LED-pin 3, ak je stlačené tlačidlo

Len monitorujeme tlačidlo zakaždým, keď spustíme funkciu loop() (Všimnite si, že tento kód by sa dal vylepšiť funkciou debounce).

Úloha 4: Zapnite LED-pin 4, ak je hodnota potenciometra väčšia ako 512

Rovnako ako pri tlačidle, iba načítame hodnotu a aktualizujeme LED-pin v závislosti od tejto hodnoty. Všimnite si, že pre potenciometer používame analogRead() a získaná hodnota je medzi 0 a 1023 (analógový prevodník Arduino má rozlíšenie 10 bitov a 2^10 = 1024).

Úloha 5: Vytlačte hodnotu potenciometra cez sériové číslo každé 2 sekundy

Rovnako ako pri úlohe 1 vypočítame časový rozdiel (trvanie), aby sme skontrolovali, či môžeme akciu vykonať alebo nie. Toto je pekná alternatíva k funkcii delay(). A tu namiesto spustenia LED-pin len odošleme hodnotu so sériovou komunikáciou. Zdá sa, že celý kód beží veľmi rýchlo a ak skutočne zostavíte tento obvod a spustíte tento program, budete mať skutočný pocit multithreadingu.

Keď už viete, ako vytvoriť jeden malý blok kódu, aby bežal veľmi rýchlo (tento kód môžete vložiť aj do funkcie), všetko, čo musíte urobiť, je zopakovať túto štruktúru pre každý krok zložitého procesu, ktorý chcete urobiť.

Funkcie prerušenia

Niektoré piny Arduino podporujú hardvérové ​​prerušenie. V podstate vytvoríte funkciu, ktorá sa spustí tlačidlom alebo iným ovládačom na hardvérovom kolíku. Keď sa spustí prerušenie, program sa preruší a vaša funkcia sa vykoná. Po dokončení funkcie program pokračuje tam, kde bol. Vaša funkcia by samozrejme mala byť veľmi rýchla, takže nezastaví hlavné vykonávacie „vlákno“ príliš dlho.

To môže byť skvelé na vykonanie nejakého kódu v závislosti od niektorých externých vstupov a uistite sa, že vám neunikne žiadny vstup, ak je frekvencia prichádzajúceho signálu veľmi vysoká. Ako príklad si pozrite úlohu č.3 vyššie uvedeného príkladu kódu. Tlačidlo sledujeme veľmi rýchlym potiahnutím jeho stavu. Tu by sme mohli použiť aj prerušenia na spustenie LED-pin pri každom stlačení tlačidla.

Prerušenia Arduino sú ako upozornenia push. Môže sa to stať kedykoľvek. Ak sa rozhodnete nepoužívať prerušenia, budete musieť manuálne skontrolovať (vytiahnuť) vstup, aby ste zistili, či môžete spustiť akciu. Rozdiel je len v tom, že ak s Arduino „potiahnete“ o upozornenie a upozornenie sa stratí, neuvidíte ho. Nie je to však nevyhnutne zlá vec: ak nepotrebujete byť extra precízni, keď bol spustený špendlík, môžete jednoducho vytiahnuť stav, kedykoľvek budete chcieť. V tomto prípade máte úplnú kontrolu nad kontrolou vstupu.

Je čistá knižnica v jazyku C. Vyžaduje si to viac vedomostí a je zložitejšie na ovládanie pre začiatočníkov a programátorov strednej úrovne. S Protothreads môžete tiež „falšovať“ multithreading pre systémy riadené udalosťami, takže je to celkom užitočné pre zložitejšie programy Arduino. Upozorňujeme však, že používanie Protothreads nie je absolútne povinné. Môžete úplne napísať kompletný multitaskový program so základnými tipmi, ktoré som vám dal skôr v tomto príspevku.


Pridaj komentár

Vaša e-mailová adresa nebude zverejnená. Vyžadované polia sú označené *

Nemôžete kopírovať obsah tejto stránky