Arduino Basics (verzia pre Platform IO)

základy programovania dosky Arduino UNO, digitálne a analógové piny, digitálne vstupy a výstupy, sériová linka, PWM

About

Na tomto cvičení si osvojíme základy programovania dosky Arduino UNO. Pomocou elektronických komponentov, ktoré sme použili na minulom cvičení, vytvoríme jednoduchú lampu, ktorú budeme vedieť tlačítkom zapnúť a vypnúť, a ktorej budeme vedieť nastaviť jas pomocou potenciometra.

Objectives

  1. Osvojiť si základy práce s prototypovacou doskou Arduino UNO.
  2. Pripraviť svoje prostredie na prácu s doskou Arduino UNO.
  3. Naučiť sa pracovať s digitálnymi vstupno-výstupnými pinmi.
  4. Naučiť sa pracovať s analógovými vstupmi.
  5. Naučiť sa pracovať s PWM.

Hardware Required

  • prototypovacia doska Arduino UNO
  • 10k Ohm potenciometer
  • 1x zelená LED dióda
  • 1x 220 Ohm rezistor, 1x 10k rezitor (v prípade zapojenia externého Pull-Up rezistora)
  • tlačidlo

Content

Get Ready

Ešte predtým, ako sa pustíme do práce, si overíme, či máme nainštalované všetko potrebné a či doska Arduino UNO pracuje správne. Toto overenie vykonáme pomocou príkladu Blink.

Úloha

Pripojte prototypovaciu dosku Arduino Uno k počítaču.

Na pripojenie použite vhodný USB kábel.

Úloha

Spustite vývojové prostredie.

Úloha

Vytvore nový projekt s názvom blink a vložte do neho výpis z úlohy.

Z domovskej obrazovky PlatformIO kliknite na tlačidlo + New Project.

PlatformIO: Home

V sprievodcovi pre vytvorenie nového projektu zadajte:

  • názov projektu - blink,
  • zo zoznamu dosiek vyberte dosku Arduino UNO, a
  • rámec sa nastaví automaticky na Arduino.
PlatformIO: Sprievodca vytvorením nového projektu

Po potvrdení sa začne projekt vytvárať. Ak vytvárate projekt pre Arduino prvýkrát, nainštalujú sa aj potrebné závislosti.

Po vytvorení projektu sa otvorí súbor s nastaveniami platformio.ini. Zdrojové súbory projektu sa nachádzajú v priečinku src/. Aktuálne sa v ňom nachádza súbor main.cpp, ktorý prepíšte nasledujúcim fragmentom kódu:

#include <Arduino.h>

int main(){
  // setup
  init();
  pinMode(LED_BUILTIN, OUTPUT);

  // loop
  while(true){
    digitalWrite(LED_BUILTIN, HIGH);
    delay(1000);
    digitalWrite(LED_BUILTIN, LOW);
    delay(1000);
  }
}

Úloha

Nastavte pripojenie vašej dosky v prostredí.

Prostredie Platform IO pri nahrávaní kódu do dosky vyberie port automaticky. To však môžete zmeniť napríklad týmito spôsobmi:

  • nastaviť port môžete ručne kliknutím na tlačidlo Set upload/monitor/test port v stavovom riadku na dolnej časti okna, alebo

  • môžete do konfiguračného súboru projektu platform.ini pridať riadok:

    upload_port = /dev/ttyUSB0

Úloha

Program nahrajte na dosku Arduino UNO.

Program nahráte na dosku:

  • pomocou tlačidla Upload v stavovom riadku, alebo
  • pomocou úloh Upload alebo Upload and Monitor v bočnom menu Platform IO s názvom Project Tasks.

Ak ste postupovali správne, na doske začne v 1s intervaloch blikať zabudovaná LED dióda.

Doska Arduino UNO s blikajúcou LED diódou

Adding External Light

Aby mala výsledná lampa lepšie svetlo, miesto zabudovanej LED diódy použijeme externú LED diódu. Túto LED diódu pripojíme k pin-u číslo 6.

Úloha

Pripojte externú LED diódu na pin číslo 6.

Nezabudnite k LED dióde pripojiť aj vhodný rezistor s hodnotou 220 alebo 330 ohmov.

Úloha

Vytvorte hlavičkový súbor config.h a definujte v ňom makro LED_PIN, ktorého hodnotou bude číslo pinu, na ktorý je pripojená LED dióda.

Hlavičkový súbor config.h umiestnite do priečinku include/.

Úloha

Aktualizujte súbor main.cpp tak, aby namiesto pevne zadanej hodnoty pin-u používal makro LED_PIN definované v hlavičkovom súbore config.h.

Úloha

Výsledný upravený program nahrajte na dosku Arduino UNO.

Ak ste postupovali správne, namiesto zabudovanej LED diódy bude teraz blikať externá LED dióda pripojená na pin definovaný pomocou makra LED_PIN.

Controlling Light with Button

Naše svetlo budeme vedieť rozsvecovať a zhasínať pomocou tlačidla. Každým jeho stlačením budeme vedieť prepnúť aktuálny stav lampy:

  • ak je lampa zhasnutá, stlačením tlačidla sa rozsvieti
  • ak lampa svieti, stlačením tlačidla sa zhasne.

V tomto kroku pripojíme k doske tlačidlo a rozšírime funkcionalitu zariadenia o toto správanie.

Úloha

Pripojte k doske tlačidlo k pin-u číslo 5.

Tlačidlo zapoíme s pull-up rezistorom. Pre toto zapojenie bude platiť:

  • ak tlačidlo nebude stlačené, tak sa na vstupnom pin-e bude nachádzať hodnota HIGH
  • ak tlačidlo bude stlačené, tak sa na vstupnom pin-e bude nachádzať hodnota LOW
Pull-up a pull-down zapojenie tlačidla.

Úloha

Upravte kód tak, aby LED dióda svietila len vtedy, keď bude tlačidlo stlačené.

Úloha

Vytvorte pomocnú funkciu is_button_pressed(), ktorá vráti hodnotu true vtedy, ak je tlačidlo stlačené.

Keďže používame zapojenie s pull-up rezistorom, je správanie tlačidla opačné. Bežne by sme očakávali, že po jeho stlačení prečítame hodnotu true a nie false, ako v tomto prípade. Nesmieme teda zabudnúť pri akomkoľvek použití či už čítania alebo prečítanej hodnoty, akú hodnotu fukcia vráti alebo akú hodnotu premenná obsahuje.

Kvôli tomu vytvoríme funkciu is_button_pressed(), ktorá skutočné správanie tlačidla zaobalí a odpovie len na otázku, či je tlačidlo stlačené.

Úloha

Overte správnosť svojho programu.

Ak ste postupovali správne, tak po spustení programu bude LED dióda zhasnutá. Ak však stlačíte tlačidlo, LED dióda bude svietiť.

Switiching the Light State

Aktuálne sa svetlo ovláda priamo pomocou tlačidla – keď ho držíme, LED dióda svieti, po uvoľnení zhasne. To znamená, že tlačidlo musíme držať stlačené počas celej doby svietenia.

Takéto správanie sme už dosiahli aj bez programovania na predchádzajúcom cvičení. Teraz však využijeme programovanie na zmenu správania: tlačidlo nebude LED diódu ovládať priamo, ale bude prepínať jej stav.

Po úprave bude platiť:

  • jedno stlačenie tlačidla LED diódu rozsvieti
  • ďalšie stlačenie tlačidla LED diódu zhasne

Tlačidlo teda bude fungovať ako prepínač (zap/vyp).

Úloha

Vytvorte premennú lamp_on, ktorá bude uchovávať aktuálny stav svietenia LED diódy (zapnuté / vypnuté).

Premenná lamp_on bude typu bool a bude nadobúdať len dve hodnoty:

  • true – svetlo svieti
  • false – svetlo nesvieti

Po zapnutí zariadenia bude svetlo zhasnuté. To znamená, že počiatočná hodnota premennej lamp_on bude false.

Úloha

Upravte váš kód tak, aby zabezpečil požadovanú funkcionalitu.

Switch Debouncing

Pri stláčaní tlačidla si môžeme všimnúť, že namiesto jednej čistej zmeny stavu dochádza k rýchlemu blikaniu. Niekedy sa dokonca stane, že po stlačení tlačidla sa stav svetla vôbec neprepne alebo sa prepne viackrát.

Tento jav je spôsobený tým, že tlačidlo pri stlačení a uvoľnení nevytvorí okamžite stabilný kontakt, ale krátko “kmitá”. Tento jav sa nazýva zákmit (z angl. bouncing).

Zákmit znamená, že mikrokontrolér na doske v skutočnosti nevidí jedno stlačenie, ale sériu veľmi rýchlych zapnutí a vypnutí. Preto môže program reagovať nečakane.

Ilustrácia procesu zákmytu

Tento problém sa dá riešiť dvoma spôsobmi:

  • hardvérovo – úpravou zapojenia
  • softvérovo – úpravou programu

V prípade hardvérového riešenia pri zapojení s pull-up rezistorom sa pridáva kondenzátor medzi pin a GND, čím sa signál vyhladí a krátke kmity sa potlačia.

Zákmit vieme riešiť aj v programe – napríklad krátkym oneskorením alebo sledovaním stability vstupu.

Existujú aj pokročilejšie prístupy, ako napríklad metóda Ultimate Debounce od Elliota Williamsa, ktorá využíva históriu stavov na spoľahlivé určenie stabilného signálu. Pre Arduino je dostupná aj ako knižnica.

V tomto kroku sa zameriame na jednoduché softvérové riešenie, ktoré je vhodné pre naše projekty.

Úloha

Vyriešte problém so zákmitom pomocou jednoduchého oneskorenia.

Po stlačení tlačidla je možné zákmit potlačiť krátkym oneskorením pomocou blokujúceho volania funkcie delay(). Tým dáme signálu čas na ustálenie a používateľovi čas tlačidlo uvoľniť.

Toto riešenie je síce veľmi jednoduché, no má svoje obmedzenia. Ak používateľ tlačidlo podrží dlhšie, môže dôjsť k nesprávnemu správaniu programu. Preto je vhodné po detekcii stlačenia počkať na uvoľnenie tlačidla, namiesto použitia pevného oneskorenia.

Týmto spôsobom vieme v našom prípade problém so zákmitom jednoducho a spoľahlivo vyriešiť.

Úloha

Overte správnosť vášho riešenia.

Ak ste postupovali správne, svetlo bude po stlačení tlačidla reagovať očakávaným spôsobom.

Adjusting the Light Intensity I.

Základná funkcionalita našej lampy je hotová. Teraz ju rozšírime o možnosť nastavovať intenzitu svetla pomocou potenciometra, aby LED dióda nemusela svietiť vždy na maximum.

Na dosiahnutie tejto funkcionality pripojíme potenciometer k analógovému pinu. Jeho hodnotu budeme čítať pomocou interného 10-bitového analógovo-digitálneho prevodníka funkciou analogRead().

Získanú hodnotu si zatiaľ budeme vypisovať do sériovej linky, aby sme videli, ako sa mení pri otáčaní potenciometra.

Úloha

Pripojte k doske Arduino UNO potenciometer na analógový vstup A0.

Potenciometer zapojte nasledovne:

  • dva krajné piny pripojte na VCC a GND (poradie nie je dôležité)
  • stredný pin (bežec) pripojte na analógový vstup A0

Úloha

Prečítajte hodnotu z analógového pinu.

Na rozdiel od digitálnych pinov nie je potrebné analógové piny nijako inicializovať. Hodnotu z nich vieme priamo prečítať pomocou funkcie analogRead().

Namiesto priameho použitia pinu A0 vytvorte makro POT_PIN a definujte ho v súbore config.h.

Mikrokontrolér ATmega328P, ktorý je srdcom dosky Arduino UNO, obsahuje 6-kanálový 10-bitový analógovo-digitálny prevodník. To znamená, že z analógových pinov vieme čítať celočíselné hodnoty v rozsahu od 0 po 1023 (t. j. 2^10 rôznych hodnôt).

Hodnotu z analógového pinu budeme čítať opakovane v hlavnej slučke programu.

Úloha

Načítanú hodnotu z potenciometra vypíšte do sériovej linky.

Na komunikáciu medzi doskou Arduino UNO a počítačom sa používa sériová linka (z angl. Serial). Tá umožňuje posielať textové informácie z programu do počítača, kde si ich vieme zobraziť v nástroji Serial Monitor.

Pred prvým použitím je potrebné sériovú komunikáciu inicializovať. Urobíme to v inicializačnej časti programu pridaním riadku:

Serial.begin(9600);

Hodnota 9600 predstavuje prenosovú rýchlosť (baud rate). Rovnakú hodnotu je potrebné nastaviť aj pri čítaní (napr. v nástroji Serial Monitor), inak sa údaje nebudú zobrazovať správne.

V hlavnej slučke po prečítaní hodnoty z analógového vstupu vypíšte túto hodnotu pomocou funkcie [Serial.println()]:

Serial.println(raw);

Úloha

Spustite Serial Monitor a zobrazte komunikáciu zo sériovej linky.

Po nahratí programu do dosky Arduino UNO sa automaticky otvorí monitor sériovej linky (ručne ho viete spustiť kliknutím na tlačítko s ikonou zástrčky a s názvom PlatformIO: Serial Monitor v stavovom paneli IDE).

Overte, že sa v okne zobrazujú hodnoty odosielané programom. Pri otáčaní potenciometra by sa mali tieto hodnoty meniť.

Adjusting the Light Intensity II.

Prečítanú hodnotu z potenciometra potrebujeme premeniť na intenzitu svietenia LED diódy. Pomocou funkcie digitalWrite() však vieme nastavovať len dva stavy (HIGH / LOW), čo nám umožňuje LED diódu iba zapnúť alebo vypnúť.

Na plynulú reguláciu jasu preto použijeme piny, ktoré podporujú PWM (Pulse Width Modulation). Pomocou PWM vieme simulovať analógový výstup – rýchlym zapínaním a vypínaním LED diódy dosiahneme rôzne úrovne jasu.

PWM
PWM: Princíp fungovania

Na zápis hodnoty na PWM pin použijeme funkciu analogWrite(), ktorá umožňuje nastaviť hodnotu v rozsahu 0255, kde:

  • 0 znamená vypnutú LED diódu
  • 255 znamená maximálny jas

V tomto kroku prepojíme hodnotu z potenciometra s PWM výstupom a budeme tak ovládať intenzitu svetla.

Úloha

Preveďte hodnotu nameranú z potenciometra z rozsahu 0–1023 na rozsah 0–255, ktorý je možné použiť na riadenie jasu LED diódy.

Na tento účel môžete s výhodou použiť funkciu map() z Arduino SDK.

Úloha

Zapíšte premapovanú hodnotu intenzity na pin, ku ktorému je pripojená LED dióda, pomocou funkcie analogWrite().

Úloha

Overte správnosť vašej implementácie.

Ak je program správny, správanie lampy by malo byť nasledovné:

  • po zapnutí dosky Arduino UNO je lampa vypnutá
  • pri vypnutej lampe sa jas nemení ani pri otáčaní potenciometra
  • po stlačení tlačidla sa lampa zapne a jej jas sa mení podľa polohy potenciometra
  • po opätovnom stlačení tlačidla sa lampa vypne

Additional Tasks

  1. Upravte program tak, aby sa jas LED diódy zvyšoval pri otáčaní potenciometra opačným smerom.

  2. Upravte program tak, aby LED dióda nikdy úplne nezhasla, ale mala vždy minimálny jas.

  3. Upravte program tak, aby sa LED dióda zapla až vtedy, keď hodnota potenciometra prekročí určitú hranicu.

  4. Vypisujte do sériovej linky intenzitu svetla v percentách (0–100 %).

  5. Upravte program tak, aby sa LED dióda po zapnutí postupne rozsvietila (plynulé zvyšovanie jasu).

Additional Resources