Arduino Basics

sériová komunikácia, digitálne piny, analógové vstupy, pull-up a pull-down rezistory, stavový diagram

Annoucements

  • (slide) Uterákový deň
    • spomienkový deň na Douglasa Addamsa autora Stopárovho sprievodcu po galaxii
    • v tento deň každý správny stopár má so sebou na viditeľnom mieste svoj uterák ;)

Night Light Project

  • (slides) Dnes vytvoríme jednoduché zariadenie, na ktorom budeme demonštrovať prácu s prototypovacou doskou Arduino UNO. Urobíme si jednoduché nočné osvetlenie. Ale nie také, ktoré bežne kúpite v obchode, ktoré len zasvieti svetlo, keď intenzita vonkajšieho svetla poklesne pod istú úroveň. My k nemu pridáme aj pohybový senzor. Takže svetlo sa rozsvieti len vtedy, keď niekto naozaj prejde okolo.

  • Samozrejme s nápadom sa dá pracovať ďalej a je možné vymýšľať veci ako:

    • svetlo sa bude rozsvecovať a zhasínať postupne a nie naraz
    • pre trvalú inštaláciu pridáme ešte aj vypínač, ktorým funkcionalitu budeme vedieť zapnúť resp. vypnúť
    • svetlo môže jemne svietiť aj bez toho, aby šiel niekto okolo
    • miesto LED diódy je možné pripojiť aj normálnu žiarovku na 220V, ktorú od Arduina oddelíme relé; to ale nebudeme robiť kvôli nebezpečiu úrazu elektrickým prúdom
    • zariadenie nemusí pracovať ako nočné svetlo so senzorom pohybu, ale napr. ako automatické svetlo, ktoré sa rozsvieti po otvorení dverí (do špajze alebo pivnice) v prípade, že je noc
  • Okrem toho si ukážeme aj iný prístup k návrhu a implementácii, s akým sa môžete stretnúť vo väčšine kníh a návodov, kde sa častokrát riešia len drobné projekty. Budeme sa snažiť čo najlepšie pracovať s pamäťou a budeme sa snažiť o čo najlepšiu organizáciu kódu.

The Ingredients

  • Ako som už spomínal, budeme potrebovať:
    • LED diódu, ktorá bude fungovať ako zdroj svetla,
    • PIR senzor, ktorý bude detegovať pohyb,
    • LDR senzor, ktorým budeme detegovať intenzitu svetla, a
    • prípadne aj tlačidlo, ktorým to všetko budeme vedieť zapnúť alebo vypnúť

State Diagram

  • Ešte predtým, ako sa pustíme do samotnej implementácie, sa pokúsime v rámci návrhu toto zariadenie modelovať pomocou tzv. stavového diagramu. Ten sa používa na modelovanie systémov, ktoré je možné reprezentovať pomocou stavov. Takéto systémy obecne nazývame stavovými strojmi.

  • Vo vytváranom zariadení vieme identifikovať tieto stavy:

    • DAY - Počiatočný stav, do ktorého sa zariadenie dostane vtedy, keď sa zapne. V tomto stave LED dióda nesvieti.
    • NIGHT - Stav reprezentujúci nočný režim. Do tohto stavu sa zariadenie dostane zo stavu DAY vtedy, keď úroveň svetla poklesne pod istú hranicu. V tomto stave síce LED dióda nesvieti, ale v rámci rozšírenia môžeme uvažovať o istej forme nočného svetla, kedy zariadenie bude svietiť svetlom s nízkou intenzitou.
    • LIGHT - Stav reprezentujúci pohyb v okolí zariadenia. Do tohto stavu prejde zariadenie zo stavu NIGHT, keď senzor pohybu deteguje pohyb. V tom momente sa svetlo rozsvieti a bude svietiť dovtedy, kým senzor pohybu bude pohyb hlásiť. Zapnutie ako aj vypnutie svetla nemusí byť náhle, ale pre zvýšenie efektu sa môže rozsvecovať a zhasínať postupne. Tým pádom vieme aj prípadne stojaceho alebo nečinného človeka upozorniť, že za krátky čas dôjde k zhasnutiu svetla.
  • Stavový diagram má samozrejme grafickú podobu, ktorá je súčasťou grafického jazyka UML. Notácia diagramu je veľmi jednoduchá, pretože sa skladá v princípe z dvoch grafických prvkov:

    • stavov (z angl. state), a
    • prechodov medzi stavmi (z angl. transition).
  • Výsledný stavový diagram reprezentujúci toto zariadenie sa nachádza na nasledujúcom obrázku:

    Night Light: State Diagram

1. Lightning the LED

  • V prvom kroku bude zapojená LED dióda, ktorá bude reprezentovať nočné svetlo. Tá sa pripojí k GPIO pin-u č. 6. Okrem samotnej LED diódy sa k nej do série zapojí aj odpor, ktorý ju ochráni. Tento odpor by mal byť malý, aby spotreboval malé množstvo napätia.

  • Ak chceme vypočítať veľkosť tohto odporu, vystačíme si s Ohmovým zákonom. Potrebujeme však vedieť:

    • úbytok napätia na LED dióde (tzv. forward voltage)
    • veľkosť prúdu, ktorý bude v slučke prechádzať
  • Maximálny prúd, ktorý môže pinom na doske Arduino prechádzať je 40mA. Pre LED diódu však môžeme rátať s prúdom o veľkosti 20mA.

  • Úbytok napätia na LED dióde záleží od jej typu, resp. farby. Rátajme teda s hodnotou 1.7V.

  • Potrebujeme teda odpor, ktorý pri prúde 20mA bude mať úbytok napätia 3.3V. Po dosadení týchto údajov do Ohmovho zákona dostaneme nasledovné:

    \[ R = \frac{U}{I} = \frac{5V - 1.7V}{20mA} = \frac{3.3V}{20mA} = 165\Omega \]

  • Postačujúci odpor je teda 165 Ohmov. Najbližší odpor, ktorý sa zvykne vyrábať, má hodnotu 220 Ohmov.

  • (slide) Schéma zapojenia bude vyzerať takto:

    Nočného svetla (LED dióda)

GPIO Pins

  • (slide) Arduino UNO obsahuje spolu 20 vstupno-výstupných digitálnych pinov, ktoré sa zvyknú označovať aj skratkou GPIO (z angl. General Purpose Input/Output pins). Sú očíslované od 0 po 13. V režime digitálnych pinov vedia rovnako pracovať aj analógové piny, ktoré sú označené A0A5.

    Arduino UNO
  • Digitálne piny pracujú len s dvoma hodnotami:

    • HIGH - logická 1 (true), úroveň napätia je 5V
    • LOW - logická 0 (false), úroveň napätia je 0V
  • V našom projekte budeme mať PIR senzor, ku ktorému budeme pristupovať cez vstupný GPIO pin, a LED diódu, ktorú budeme ovládať cez výstupný GPIO pin. V prípade, že k zariadeniu bude pripojené aj tlačidlo, to bude rovnako pripojené na vstupný GPIO pin.

Setting Up Output GPIO Pin

  • Prácu s výstupným GPIO pin-om si ukážeme pomocou LED diódy, ktorá je pripojená na pin 6.

  • Predtým, ako začneme ktorýkoľvek GPIO pin používať, je potrebné ho nastaviť buď ako vstupný alebo výstupný. To sa robí vo funkcii setup() pomocou volania funkcie pinMode(), ktorá má dva parametre:

    • pin - číslo GPIO pin-u
    • mode - režim práce pin-u, ktorý môže byť INPUT, OUTPUT (alebo aj ako INPUT_PULLUP)
  • LED dióda je výstupným akčným členom a je pripojená na GPIO pin 6. Jej nastavenie bude vyzerať nasledovne:

    void setup(){
        pinMode(6, OUTPUT); // set GPIO pin 6 as output pin
    }
  • V programe však nie je dobré pracovať s bulharskými konštantami a preto miesto čísla pin-u vytvoríme makro, ktoré použijeme všade tam, kde sa bude číslo pin-u používať:

    #define LIGHT_PIN 6
    
    void setup(){
        pinMode(LIGTH_PIN, OUTPUT);
    }

Lightning the LED

  • (slide) Pre zapísanie logickej hodnoty na digitálny pin sa používa funkcia digitalWrite(). Má dva parametre:

    • pin - číslo GPIO pin-u
    • value - hodnota, ktorá je buď logická 0 (LOW) alebo logická 1 (HIGH)
  • Rozsvietiť LED diódu pripojenú na pin-e 6 je teda možné takto:

    void setup(){
        pinMode(LIGTH_PIN, OUTPUT);
        digitalWrite(LIGHT_PIN, HIGH);
    }
  • Zhasnúť tú istú LED diódu je možné takto:

    void setup(){
        pinMode(LIGTH_PIN, OUTPUT);
        digitalWrite(LIGHT_PIN, LOW);
    }

Superloop

  • Umiestnenie kódu do funkcie setup() však porušuje konvencie, ktoré Arduino SDK zaviedlo, a síce, že funkcia setup() sa používa len na inicializáciu. Samotný kód sa má nachádzať vo funkcii loop().

  • Ak však do tejto funkcie bude umiestnená funkcia nastavujúca logickú úroveň 1 a hneď za ňou funkcia, ktorá nastaví logickú úroveň 0, bude LED dióda svietiť polovične. V skutočnosti bude preblikávať, pretože doba jedného aj druhého stavu bude veľmi krátka.

    void loop(){
        digitalWrite(LIGHT_PIN, HIGH);
        digitalWrite(LIGHT_PIN, LOW);
    }
  • Kód teda upravíme tak, aby LED dióda svietila po dobu 2s a po dobu 0.5s bola zhasnutá. Spozdenie mikrokontroléra na uvedenú dobu zabezpečí funkcia delay(), ktorá pozastaví vykonávanie mikrokontroléra na uvedený čas:

    void loop(){
        digitalWrite(LIGHT_PIN, HIGH);
        delay(2000);
        digitalWrite(LIGHT_PIN, LOW);
        delay(500);
    }
  • Tým sme vlastne implementovali príklad Blink.

2. Reading the Movement from PIR Sensor

  • Na detekciu pohybu k doske Arduino UNO pripojíme PIR senzor. Ten bude generovať na výstupe logickú úroveň HIGH, keď zistí pohyb. V opačnom prípade sa na výstupe senzora bude nachádzať logická úroveň LOW.

  • (slide) PIR senzor má tri piny:

    • VCC - napájanie
    • GND - zem
    • OUT - digitálny výstup
    PIR Sensor: Pinout
  • Výstup z PIR senzoru bude pripojený k GPIO pinu č. 4, ktorý bude nastavený ako vstupný:

    #define LIGHT_PIN 6
    #define PIR_PIN 4
    
    void setup(){
        pinMode(LIGTH_PIN, OUTPUT);
        pinMode(PIR_PIN, OUTPUT);
    }
  • (slide) Pre prečítanie logickej hodnoty z digitálneho pin-u sa používa funkcia digitalRead(). Jej parametrom je len GPIO pin, z ktorého má byť hodnota prečítaná:

    • pin - číslo GPIO pin-u
  • Funkcia vracia buď hodnotu logickej úrovne HIGH alebo LOW.

  • Výstup zo senzoru sa bude čítať vo funkcii loop(). Prečítanú hodnotu vieme následne okamžite použiť na rozsvietenie alebo zhasnutie LED diódy:

    void loop(){
        bool is_movement = digitalRead(PIR_PIN);
        digitalWrite(LIGHT_PIN, is_movement);
    }
  • V princípe sme vytvorili časť riešenia, kedy sa LED dióda rozsvieti pri zistení pohybu. Rovnako tak sa vieme pozerať na vytvorené zariadenie aj ako na jednoduchý alarm.

  • Pre overenie správnosti by bolo dobré, ak by sa dala hodnota premennej is_movement overiť pomocou debuggera alebo aspoň výpisom na štandardný výstup. Ako to však zabezpečiť na prototypovacej doske Arduino UNO?

Serial Line

  • Arduino má k dispozícii sériový port, pomocou ktorého je možné komunikovať buď s ďalšími zariadeniami alebo priamo s počítačom. To je veľmi výhodné pre ladenie programov.

  • Sériová komunikácia

    • je jednoduchá a lacná

    • na jej realizáciu stačia len dva káble (dokopy však treba štyri - komunikácia je obojsmerná (full duplex))

    • obyčajne sa prenáša 8b, ku ktorým sa na začiatku pripojí START bit a na konci STOP bit s paritným bitom (môže a nemusí byť)

      Serial Communication
  • Na prenos po sériovej linke je možné použiť dva základné typy funkcií:

    • funkcie na zapisovanie - napr. Serial.print(), Serial.println()
    • funkcie na čítanie - napr. Serial.read(), Serial.readString()
  • (slide) Predtým, ako sa začne používať sériová linka, je potrebné ju inicializovať vo funkcii setup() tak, že nastavíme rýchlosť komunikácie (tiež známy ako baudrate):

    Serial.begin(9600);
  • Ukážme si, ako to bude vyzerať v prípade, že sa obe strany na rýchlosti prenosu nezhodnú. Arduino IDE obsahuje jednoduchý monitor sériového portu, ktorý môžeme použiť ako na čítanie tak aj na zápis hodnôt do sériového portu. Na túto ukážku použijeme jemne modifikovanú predchádzajúcu verziu kódu:

    void setup() {
        Serial.begin(9600);
    }
    
    void loop() {
        Serial.println("Hello world");
    }
  • So sériovým portom je samozrejme možné komunikovať aj mimo Arduino IDE napr. priamo z OS Linux. K dispozícii existuje niekoľko nástrojov a jedným z nich je aj nástroj screen, ktorý je možné použiť nasledovne:

    screen /dev/ttyACM1 9600
  • Ako som už spomínal, sériová linka je obojsmerná, takže údaje je možné posielať (zapisovať), ale aj prijímať (čítať). Nasledujúca ukážka teda demonštruje nie len zapisovanie, ale aj čítanie zo sériového portu:

    void setup() {
        Serial.begin(9600);
    
        while (!Serial) {
            ; // waiting for serial port
        }
    
        Serial.print("Enter your name: ");
    }
    
    void loop() {
        if (Serial.available() > 0) {
            String text = Serial.readString();
    
            Serial.println("Hello, " + text);
        }
    }

Example

  • Poďme ale naspäť k nášmu príkladu. Pokúsime sa teda odčítať hodnotu potenciometra a zapísať ju do sériovej linky:

    void setup() {
        Serial.begin(9600);
    
        while (!Serial) {
            ; // waiting for serial port
        }
    }
    
    void loop() {
        int value = analogRead(0);
        Serial.println(value);
    }
  • Okrem textového monitoru sériovej linky má Arduino IDE k dispozícii aj tzv. Serial Plotter, kde vie graficky vizualizovať odsnímanú hodnotu.

Pull-Up and Pull-Down Resistors

  • asdf

3. Measuring Light Intensity with LDR Sensor

Analógový vstup

  • (slide) Na prevod analógového signálu na digitálny potrebujeme mať k dispozícii analógovo-digitálny prevodník (označovaný aj ako A/D prevodník). Jeho úlohou je odmerať veľkosť vstupného napätia (alebo prúdu) a previesť ho na číslo zodpovedajúce jeho veľkosti.

  • A/D prevodníky sa veľmi často používajú v zariadeniach, ktoré merajú napätie alebo prúd. Rovnako sa používa v zariadeniach, ktoré merajú inú fyzikálnu veličinu a tú prevádzajú na elektrickú (senzory), ako napr. teplota, tlak, svetlo a pod.

  • Prevodník je charakteristický svojim rozlíšením. Rozlíšenie prevodníku je číslo, ktoré je dané počtom rozlíšiteľných úrovní analógového signálu. Udáva sa v bitoch. Ak by bol prevodník napr. 3 bitový, vedel by dokopy rozlíšiť 8 úrovní vstupného analógového signálu (pretože 2^3 = 8)

  • Proces prevodu analógového signálu na digitálny sa volá vzorkovanie (sampling). V pravidelných intervaloch daných vzorkovacou frekvenciou dochádza k odčítaniu hodnoty vstupnej veličiny.

  • (slide) Mikrokontrolér Arduino obsahuje 10 bitový prevodník (môže nadobúdať hodnoty v rozsahu od 0 po 1023). Jeden “dielik” teda zodpovedá úrovni približne 4.88mV (5V/1024). Ak teda odčítame z analógového vstupu hodotu 567, tak je napätie na vstupe približne 2.77V (slide).

  • Tento prevodník obsahuje 6 kanálov, čomu zodpovedajú vstupy A0A5, nazývané tiež ako analógové vstupy (iné verzie dosiek Arduino môžu mať iný počet kanálov). Analógové vstupy však je možné rovnako použiť ako štandardné digitálne vstupy alebo výstupy.

  • (slide) Na odčítanie analógovej hodnoty pomocou mikrokontroléra Arduino používame funkciu analogRead(), ktorá vráti celé číslo v rozsahu 0 - 1023. Jej parametrom je číslo analógového portu, ktorý chceme odčítať. Je možné priamo využiť konštanty, takže miesto písania samotného čísla je možné písať A0A5. Teda použiť identické označenie, aké je priamo na doske.

Additonal Usages

  • senzor intenzity svetla
  • merač bateriek
  • bary na hudbu (ekvalizér)

Additional Resources