# Arduino

Arduino je otvorená hardvérová a softvérová platforma určená na tvorbu elektronických projektov. Skladá sa z **mikroprocesorovej dosky** (napr. Arduino Nano) a **vývojového prostredia** (Arduino IDE).

Arduino je chránená značka, názov Arduino a logo sú registrované ochranné známky. Avšak Arduino je open source a open hardware. Okrem dostupných kódov sú tak k dispozícii aj schémy zapojenia, návrhy dosiek a technické špecifikácie, čo umožňuje vznik rovnakých produktov (lacnejších a často aj horšej kvality).

**Mikroprocesorová doska** je kompletný modul, ktorý obsahuje mikrokontrolér, spolu s ďalšími komponentmi, ako sú napájacie obvody, vstupno-výstupné piny, a často aj komunikačné rozhrania. Tieto dosky sú určené na jednoduché pripojenie a vývoj projektov bez potreby navrhovať vlastný hardvér.

**Mikrokontrolér** je samotný čip na tejto doske, ktorý spája procesor, pamäť a vstupno-výstupné periférie. Je navrhnutý tak, aby vykonával špecifické úlohy (vykonával naprogramované inštrukcie, ovládal pripojené komponenty a komunikoval so zariadeniami) s minimálnou spotrebou energie.

Okrem hľadiska spotreby energie je dobré pri vývoji myslieť na to, že zariadenia majú obmedzený výpočtový výkon. Vyjadrené v číslach: bežný procesor ATmega328P má frekvenciu **16 MHz**. Pamäť je iba v kB, konkrétne **2 kB SRAM** (operačnej pamäte), **32 kB flash pamäte** (pre uloženie programu) a **1 kB EEPROM** (trvalej pamäte).

```{figure} ../img/arduino/nano-original.jpg
---
width: 350px
name: arduino original
--- 
Originál model Arduino Nano. Originál je možné rozoznať vďaka oficiálnemu logu Arduino (väčšinou na spodnej strane).
```

## Arduino zblízka

Pozrime sa detailne na konkrétny model **Arduino Nano**, ktorý sme používali v experimentoch s jednosmerným prúdom.

### Pohľad zhora

```{figure} ../img/arduino/arduino-front.png
---
width: 450px
name: arduino front
--- 
Arduino Nano - horná strana 
```

Na vrchnej strane Arduino Nano môžeme vidieť:

* **A)** **Mini USB port** slúži na napájanie Arduina a na programovanie mikrokontroléra. Umožňuje tiež sériovú komunikáciu so zariadením.
* **B)** **Mikrokontrolér** (ATmega328P) je hlavnou časťou celej dosky. Vykonáva kód.
* **C)** **Kryštálový oscilátor** poskytuje mikrokontroléru signál hodín na časované vykonávanie operácií. Oscilátor po napojení generuje oscilujúci signál vybráciou kryštálu so špecifickou frekvenciou (Arduino Nano má typicky 16MHz).
* **D)** **Reset button** je tlačidlo, ktorým je možné reštartovať vykonávanie kódu. Typicky má kód inicializačnú časť a ďalšiu časť, ktorá sa opakuje v slučke. Stlačením tlačidla dosiahneme rovnaký efekt ako odpojením Arduina a pripojením nanovo.
* **E)** **SMD Rezistory**, ktoré sú priamo na doske (*SMD - surface mount device*). Slúžia pre LED. Na základe číselného kódu je možné zistiť odpor rezistora.
* **F)** **LED** indikujú rôzne veci. Prvé dve LED indikujú prenos dát cez USB (resp. sériovú komunikáciu) - odosielané **RX** (received) a posielané **TX** (transmitted). Tieto LED blikajú napr. pri nahrávaní kódu na Arduino. **POW** svieti ak je Arduino napájané. Posledná LED označená **L** je určená na testovacie použitie a je priamo napojená na pin **D13**.
* **G)** **ICSP Header** (*In-Circuit Serial Programming*) je hlavička so šiestimi pinmi, ktoré sú priamo napojené na mikrokontrolér. Umožňujú priamy prístup bez nutnosti využitia USB na nízkoúrovňové debugovanie, resp. ak je bootloader poškodený, tak aj na jeho preprogramovanie. **Bootloader** je malý program, ktorý umožňuje nahrávať kód na mikrokontrolér cez USB.
* **H)** a **I)** sú piny, ktoré si vysvetlíme neskôr. Tento model na obrázku má napájkované nožičky na jednoduchšie pripojenie na breadboard alebo priamo s použitím dupont káblov. K dispozícii je aj verzia bez týchto nožičiek, namiesto nich obsahuje iba dierky. 

### Pohľad zdola

```{figure} ../img/arduino/arduino-back.png
---
width: 450px
name: arduino back
---
Arduino Nano - spodná strana
```

Dolná strana Arduino Nano obsahuje viacero malých komponentov (napr. rezistory) a sú tam viditeľné prepojenia na doske. Medzi dôležité súčasti patrí:

* **J)** **Prevodník** (CH340C) medzi USB a sériovou komunikáciou. Je priamo napojený na USB port a prevádza komunikáciu z USB na formu, ktorá je kompatibilná s mikrokontrolérom (UART, TTL logika).
* **K)** **Regulátor napätia** (AMS1117) zaručuje stabilnú hodnotu operačného napätia (v tomto modeli 5V). Konvertuje vstupné napätie, ktoré môže byť z rozsahu od 7V do 12V ak je napojené priamo na pin VIN.

### USB

Aj na USB kábel sa môžeme pozrieť ako na komponent s vodičmi a pinmi. Štandard USB 2.0 obsahuje štyri vodiče, ktoré sú farebne odlíšené a bežný USB konektor poskytuje 4 piny. Dva z nich slúžia na napájanie a dva na prenos dát. 

S novšími štandardmi prichádza aj väčší počet vodičov. Napr. USB 3.0 obsahuje 9 vodičov. Štyri sú totožné s USB 2.0. Ďalšie dve dvojice slúžia na SuperSpeed transfer dát a jeden je na tienenie ako ochrana pred elektromagnetickým rušením.

```{figure} ../img/arduino/usb.jpg
---
width: 350px
name: usb
---
USB kábel pozostáva zo 4 vodičov. Červená farba (5V), čierna farba (GND), biela a zelená na prenos dát oboma smermi.
```



## Piny

Arduino poskytuje piny na pripojenie a komunikáciu. V zásade ide o piny dvoch typov:

* **GPIO** (*general-purpose input/output*), ktoré fungujú v dvoch režimoch:
  * **OUTPUT** - daný pin je nastaviteľný a funguje ako kladný pól batérie (5V) alebo záporný (0V).
  * **INPUT** - daný pin funguje ako *červený* merací hrot voltmetra, pričom druhý hrot by bol napojený na GND (teda meria napätie vzhľadom na potenciál GND).
* špeciálne pomocné piny, ktoré slúžia predovšetkým na napájanie a komunikáciu:
  * **5V** a **3V3** - poskytujú regulované výstupné napätie.
  * **GND** - slúžia na uzavretie elektrického obvodu. Väčšinou sa nachádzajú na doske viaceré GND piny (Arduino Nano má dve).
  * **RST** - resetuje sa ním vykonávanie kódu, podobne ako s tlačidlom RESET na hornej strane Arduina. Reset sa vykoná pri prepojení tohto pinu s GND.
  * **AREF** - poskytuje referenčnú hodnotu napätia pre ADC (analógovo digitálny prevodník). 
  * **TX** a **RX** (sú na digitálnych GPIO pinoch D0 a D1) - slúžia na sériovú komunikáciu. Odporúča sa ich nepoužívať a namiesto nich pripájať senzory a iné komponenty k ďalším dostupným pinom D3-D13 alebo A0-A7.
  * **SCL** a **SDA** (sú na GPIO pinoch A4 a A5) - slúžia na I2C komunikáciu, ktorej sa budeme venovať neskôr.

```{figure} ../img/arduino/pinout.png
---
width: 700px
name: pinout
---
Kompletný popis pinov pre Arduino Nano
```

## Kód pre Arduino

Za úspechom Arduina nie je iba samotný mikrokontrolér na doske vhodnej na prototypovanie, ale aj samotný softvér a spôsob programovania. 

Prostredie **Arduino IDE** poskytuje.

* **editor kódu** - vytváranie kódu pre Arduino alebo úpravu existujúcich vzorových kódov.
* **serial monitor** - na sledovanie výstupu zo sériovej komunikácie. Vhodné na debugovanie.
* **správcu knižníc** - možnosť inštalácie doplnkových knižníc.
* **správcu dosky a nahrávanie kódu** - možnosť výberu modelu Arduina, portu pripojenia a jednoduché nahrávanie kódu na zariadenie.

Programovať je možné aj v iných prostrediach, ale použitie Arduino IDE je pohodlné a vhodné hlavne pre začiatočníkov.

Arduino používa zjednodušenú verziu **C/C++**. Ide o osekané C++, ktoré je prispôsobené vývoju pre Arduino. Hlavná časť kódu vyzerá nasledovne:

```c++
void setup(){
    
}

void loop() {
    
}
```

čo zodpovedá kódu:

```c++
int main() {
    setup();
    while (true) {
        loop();
    }
}
```

Programovanie pre Arduino znamená napísanie **dvoch funkcií**. Jedna sa vykoná **na začiatku** pri prvom spustení (resp. použití RESET) a druhá funkcia sa vykonáva **opakovane** v nekonečnom cykle.

````{admonition} Experiment č. 1 - Blikanie LED
:class: tip
**Pomôcky**: Arduino Nano, voliteľne aj breadboard, káble, rezistor a LED

Naprogramujeme Arduino, aby vykonávalo **blikanie LED**. 

**Postup**:
1. Nainštalujeme a spustíme Arduino IDE.

2. Otvoríme si pripravený kód (`File - Examples - 01.Basics - Blink`) alebo napíšeme samostatne:
   ```c++
   void setup() {
       pinMode(13, OUTPUT);
   }
   
   void loop() {
       digitalWrite(13, HIGH);
       delay(1000);
       digitalWrite(13, LOW);
       delay(1000);
   }
   ```
   V pripravenom kóde je použitá konštanta `LED_BUILTIN`, ktorá je na väčšine Arduino dosiek asociovaná s hodnotou 13.
   
3. Nastavíme v menu hore dosku a port. Ak sa zobrazuje viacero portov, je vhodné odpojiť Arduino a znovu pripojiť. Sledujeme, ktorý port pribudne. Ak je problém s nahrávaním na Arduino Nano, môžeme skúsiť nastaviť starší bootloader (`Tools - Processor`).
4. Kód nahráme na Arduino (`Verify` a `Upload`). Zabudovaná LED by mala začať blikať. Vypnutie a zapnutie sa strieda s odstupom jednej sekundy. Kód si vysvetlíme neskôr.
5. Voliteľne si môžeme zapojiť obvod na breadboard s rezistorom a LED ako v predošlej kapitole o jednosmernom prúde. Pričom pripojíme LED a rezistor namiesto 5V k pinu **D13**. LED by mala blikať. Voliteľne môžeme vyskúšať pripojiť LED na iný pin (napr. D7) a v kóde nahradiť číslo `13` (alebo `LED_BUILTIN`) číslom `7`.
````

## Output režim

Piny v režime OUTPUT fungujú ako kladný alebo záporný pól batérie. Vieme ním nastavovať hodnotu operačného napätia Arduina (5V) alebo hodnotu reprezentovanú GND (0V).

Vo všeobecnosti môžeme rozlišovať signál:

* **analógový** - spojitý signál, kde hodnota môže byť ľubovoľná zo zadaného intervalu. Napríklad pri meraní napätia teplotného senzora v kontexte Arduina môžeme získať ľubovoľnú hodnotu medzi 0V a 5V.
* **digitálny** - diskrétny signál, ktorý nadobúda iba jednu z dvoch hodnôt: `HIGH (1)` alebo `LOW (0)`. Napríklad reprezentovanie hodnoty stlačenia tlačidla (stlačené - `HIGH`, nestlačené - `LOW`).

Na doplnenie by sme mohli hovoriť ešte o **diskrétnom** signáli, kde sú jednotlivé hodnoty dostupné len v určitých časových intervaloch. Ide o vzorkovaný signál. Ak by sme sa na to pozreli z pohľadu funkcií, tak definičný obor nie je spojitý. Obor hodnôt môže byť v analógovej, kvantovanej alebo digitálnej forme. 

Signál, ktorý má určitý počet povolených hodnôt (viac ako 2) môžeme označiť ako **kvantovaný** signál. Ide o diskretizáciu oboru hodnôt.

### DigitalWrite

Na nastavenie pinu na digitálnu hodnotu (HIGH alebo LOW) je potrebné nasledovné:

* **nastavenie pinu na OUTPUT režim**: `pinMode(pin, OUTPUT)`, pričom `pin` označuje číslo pinu. 
* **digitálny zápis hodnoty**: `digitalWrite(pin, HIGH)` alebo `digitalWrite(pin, LOW)`, čím sa nastavuje hodnota (napätie) pinu.

V kóde, pri experimente s blikaním LED, sme videli použitie funkcie `digitalWrite`, kde sa v `setup()` nastavil pin na OUTPUT režim a v `loop()` sa menili hodnoty na pine.

Pri **adresovaní pinu** je potrebné pozerať sa na ich hodnotu z pohľadu digitálnych pinov. Pinout pre Arduino Nano (obrázok vyššie) má číslovanie pinov zobrazené fialovou farbou. 

* Piny označené na arduine písmenom **D** majú aj priradené číslo (`D2`-`D13`). V kóde ich stačí označiť číslom (napr. `D7` číslom `7`). 
* Piny označené písmenom **A** sú analógové, ale to súvisí iba s režimom INPUT. Pri OUTPUT režime sa dajú klasicky použiť ako piny na `digitalWrite` (s výnimkou `A6` a `A7`). Označenie v kóde je potrebné urobiť cez konštantu alebo v pinoute nájsť príslušné číslo digitálneho pinu (napr. pin `A3` v kóde napísať ako `A3` alebo `17`).

### AnalogWrite

Nastaviť akúkoľvek analógovú hodnotu Arduino nedokáže. Simulovať analógový výstup vie Arduino pomocou techniky **PWM (Pulse Width Modulation)**. V princípe ide o rýchle prepínanie medzi stavom `HIGH` a `LOW`. Pomer času v jednom a druhom stave definuje výsledné výstupné napätie (nazýva sa to *duty cycle* a je udávané v percentách).

Na nastavenie pinu na analógovú hodnotu je potrebné:

* **zavolať funkciu** `analogWrite(pin, value)` na pine, ktorý podporuje PWM (Arduino Nano má 6 takýchto pinov - D3, D5, D6, D9, D10 a D11). Hodnota je celé číslo z rozsahu od `0` (*vždy vypnuté*) do `255` (*vždy zapnuté*).

Nastavenie na OUTPUT režim nie je nutné, udeje sa to automaticky pri volaní `analogWrite`.

```{figure} ../img/arduino/pwm.png
---
width: 350px
name: pwm
---
PWM s rôznym pomerom `HIGH` vs. `LOW`
```

Rýchlosť prepínania medzi režimom `HIGH` a `LOW` je možné nízkoúrovňovo meniť. Arduino Nano obsahuje tri časovače, ktoré regulujú frekvenciu PWM. Časovač pre piny 5, 6 a pre piny 3, 11 je nastavený na `980 Hz`. Piny 9 a 10 majú nastavenú hodnotu `490 Hz`. 

Pri aplikáciach s audio výstupom alebo použitím motora, je vhodné nastaviť výrazne vyššie frekvencie.

````{admonition} Experiment č. 2 - AnalogWrite LED
:class: tip
**Pomôcky**: Arduino Nano, LED, breadboard, dupont káble
  
**Postup**:

1. Použijeme zapojenie z predošlej úlohy. Podľa pinoutu si skontrolujeme zapojenie LED na pin, ktorý podporuje PWM.

   ```{figure} ../img/arduino/led-schema.png
   ---
   width: 550px
   name: led
   ---
   Zapojenie LED na pin `D6`, ktorý podporuje PWM.
   ```
2. Na Arduino uploadneme nasledovný kód:

   ```c++
   const int pin = 6;
   
   void setup() {
   }
   
   void loop() {
   
     for (int i = 0; i < 256; i+=10) { 
       analogWrite(pin, i); 
       delay(50); 
     }
   
     for (int i = 255; i >= 0; i-=10) {
       analogWrite(pin, i);
       delay(50);
     }
     
   }
   ```
   
3. Spustíme a sledujeme postupné zvyšovanie a znižovanie jasu svietenia LED.
````

## Input režim

Pri INPUT režime funguje daný pin ako hrot voltmetra. V princípe môžeme hodnotu čítať jedným z dvoch spôsobov - **digitálne** (`digitalRead`) alebo **analógovo** (`analogRead`). Každý z nich má svoje špecifiká.

### DigitalRead

Meranie sa vykonáva funkciou `digitalRead(pin)`. Funkcia vráti `HIGH` alebo `LOW`. Je potrebné predtým nastaviť pin na INPUT režim `pinMode(pin, INPUT)`. 

Arduino je založené na logike **TTL** (transistor-transistor logic), ktorá je v počítačoch a digitálnych obvodoch bežne používaná. TTL definuje úrovne napätia pre jednotlivé binárne stavy. Pri použití **5V TTL** sú definované nasledovne:

* `LOW (0)`  - v rozsahu od `0V` do `1.5V`.
* `HIGH (1)` - v rozsahu od `3V` do `5V`.
* nestabilná zóna - od `1.5V` do `3V`. Nie je zaručené stabilné meranie a môžu byť vrátené v podstate náhodné hodnoty.

V jednoduchom prípade môžeme pomocou `digitalRead` napríklad čítať hodnotu tlačidla (stlačené vs. nestlačené). 

Neskôr sa budeme venovať spôsobom komunikácie, ako vie Arduino čítať viacero jednotiek a núl a interpretovať tieto hodnoty.

### AnalogRead

Analógové čítanie funguje len na **analógových pinoch** (`A0` - `A7` pre Arduino Nano). Nie je potrebné žiadne nastavovanie pinu. Pomocou funkcie `analogRead` je načítaná hodnota z rozsahu od `0` do `1023`, čo zodpovedá 10-bitovému rozlíšeniu.

**Analógovo-digitálny prevodník (ADC)** je súčiastka, ktorá konvertuje analógovú hodnotu napätia na digitálnu hodnotu (v rozsahu `0-1023`), ktorá je potom softvérovo spracovávaná. Arduino Nano obsahuje jeden 10-bitový prevodník. ADC je v porovnaní s ostatnými komponentmi drahá súčiastka aj z pohľadu ceny, aj miesta. ADC sa nachádza priamo vo vnútri mikrokontroléra. Preto je tam len jeden prevodník a piny sú **multiplexované**. Analógový multiplexer umožňuje mikrokontroléru vybrať pin, z ktorého je čítaná hodnota. Je možné čítať v určitom čase hodnotu iba z jedného pinu. Každé meranie trvá istý čas (zhruba `100µs`), takže pri zapojení viacerých senzorov a potrebe rýchleho čítania, je potrebné myslieť na zdieľanie času merania.

Pri 10-bitovom prevodníku je presnosť merania zhruba `5mV`. Arduino berie ako maximálnu hodnotu `5V`. Túto hodnotu je možné nastaviť interne (na `1.1V` pomocou volania `analogReference(INTERNAL)`) alebo externe pomocou pinu `AREF`. Táto zmena je vhodná napríklad pri nízko napäťových senzoroch na zvýšenie presnosti merania.

````{admonition} Experiment č. 3 - AnalogRead
:class: tip
**Pomôcky**: Arduino Nano, voliteľne aj breadboard, káble, rezistor a LED

Cieľom je čítať analógové hodnoty a tie demonštrovať nastavením rozsvietenia LED.

**Postup**:

1. Zapojíme obvod podľa nasledovnej schémy. LED zapojíme na pin, ktorý podporuje PWM (`D6`). Potenciometer zapojíme prostredným terminálom na analógový pin (`A3`). 

   ```{figure} ../img/arduino/led-potenciometer-schema.png
   ---
   width: 550px
   name: led
   ---
   Zapojenie LED na pin `D6`, ktorý podporuje PWM.
   ```
2. Nahráme nasledovný kód. V princípe máme dva samostatné obvody. Jeden s LED, ktorý je obsluhovaný funkciou `analogWrite` a jeden s potenciometrom, ktorý poskytuje údaje získavané pomocou `analogRead`.
   ```c++
   const int pin = 6;
   const int analogPin = 3;
   int val = 0;
   
   void setup() {
   }
   
   void loop() {
       val = analogRead(analogPin); 
       analogWrite(pin, val /4);
   }
   ```
3. Doplníme výpis hodnoty, ktorú budeme sledovať. Ide o sériovú komunikáciu, ktorej sa budeme venovať v ďalšej kapitole. Nahráme nasledovný kód:

   ```c++
   const int pin = 6;
   const int analogPin = 3;
   int val = 0;
   
   void setup() {
       Serial.begin(9600);
   }
   
   void loop() {
       val = analogRead(analogPin); 
       analogWrite(pin, val /4);
       Serial.println(val);
   }
   ```

   V Arduino IDE si zapneme **Serial Monitor** (ikona vpravo hore, alebo nájdeme v menu) a sledujeme prichádzajúce hodnoty. Voliteľne si môžeme vyskúšať aj **Serial Plotter**.
   
   V prípade nahrávania kódu na Arduino, je potrebné mať vypnutý Serial Monitor (resp. Plotter), pretože fungujú na rovnakom komunikačnom kanáli ako nahrávanie kódu na mikrokontrolér. Dochádza k blokovaniu a nahratie kódu môže byť odmietnuté.
   
4. **Odpojíme** dupont kábel z prostredného terminálu potenciometra a sledujeme, čo sa zmení. Môžeme sa dotknúť prstom kábla pripojeného na analógový pin `A3`. Hodnoty by mali byť náhodné a citlivé na dotyk. Pozorujeme *floating input*, kde ADC meria elektromagnetický šum z prostredia.
````

## Floating input

Môžeme si všimnúť, že pri poslednom zapojení nie je potenciometer chránený rezistorom, ako bolo v prípade, keď reguloval LED priamo (v predošlej kapitole). 

Pin v režime INPUT je v tzv. **stave vysokej impedancie**. To znamená, že má vysoký odpor (často v megaohmoch). Preto nie je zdrojom elektrického prúdu a teda nie je tam riziko skratu. Navyše je pin extrémne citlivý na šum a externé vplyvy, čo sme mohli pozorovať pri nepripojenom pine, kde sa merané napätie správa nepredvídateľne a náhodne.

### Tlačidlo

V nasledovnom experimente budeme pracovať s **tlačidlom**. Ide o komponent, ktorý má štyri terminály (piny). Dve dvojice, ktoré sú vnútorne prepojené sa navzájom prepoja po stlačení tlačidla.

   ```{figure} ../img/arduino/button.jpg
   ---
   width: 250px
   name: button
   ---
   Tlačidlo. Pri jeho stlačení sú všetky terminály prepojené.
   ```

````{admonition} Experiment č. 4 - Tlačidlo a pull-up rezistor
:class: tip
**Pomôcky**: Arduino Nano, breadboard, káble, tlačidlo a rezistor (10kΩ)

Cieľom je pozorovať vstup pri stlačení tlačidla a pomocou rezistora riešiť floating input.

**Postup**:

1. Zapojíme tlačidlo na analógový pin (`A3`):
   ```{figure} ../img/arduino/button-schema.png
   ---
   width: 550px
   name: button schema
   ---
   Zapojenie tlačidla k Arduino Nano.
   ```
2. Nahráme nasledovný kód a cez **Serial Monitor** sledujeme prichádzajúce hodnoty.
   
   ```c++
   const int analogPin = 3;
   int val = 0;
   
   void setup() {
       Serial.begin(9600);
   }
   
   void loop() {
       val = analogRead(analogPin);
       Serial.println(val);
   }
   ```
   Ak je tlačidlo **stlačené**, tak je hodnota `0`, pretože je priamo prepojené s GND. Ak tlačidlo **nie je stlačené**, tak máme floating input, teda náhodné hodnoty. 
   
3. Voliteľne si môžeme vyskúšať rovnaké zapojenie s použitím `digitalRead`. Úpravu kódu si vykonajte samostatne.
   
4. Do obvodu pridáme rezistor pripojený medzi tlačidlo a 5V.
   
   ```{figure} ../img/arduino/button-rezistor-schema.png
   ---
   width: 550px
   name: button schema
   ---
   Tlačidlo a rezistor napojený na 5V.
   ```
   
   Ak je tlačidlo **stlačené**, tak sa nič nemení a hodnota je `0`, pretože sa prepája GND s pinom `A3`. Môžeme si to predstaviť aj tak, že v obvode `5V-rezistor-GND` je meranie vykonané za rezistorom a preto je tam hodnota `0`.
   
   Ak tlačidlo **nie je stlačené**, máme stále k dispozícii priame prepojenie pinu `A3` na `5V` (cez rezistor), teda meraná bude hodnota `1023` alebo `HIGH` pri digitálnom čítaní.
   
   Pin má stále pripojenie k známemu napätiu, preto nebude v stave *floating input*.
   
5. Schému vrátime do pôvodného stavu bez rezistora:

   ```{figure} ../img/arduino/button-schema.png
   ---
   width: 550px
   name: button schema
   ---
   Zapojenie tlačidla k Arduino Nano.
   ```
   
   Aktivujeme zabudovaný rezistor v Arduine nasledovným kódom (môžeme vyskúšať aj `analogRead`):

   ```c++
   const int pin = A3;
   int val = 0;
   
   void setup() {
       pinMode(pin, INPUT_PULLUP);
       Serial.begin(9600);
   }
   
   void loop() {
       val = digitalRead(pin); 
       Serial.println(val);
   }
   ```
   Sledujeme hodnoty pri stlačení a uvoľnení tlačidla.
````

### Pull-up rezistor

V predošlom experimente sme použili tzv. **pull-up rezistor**. V jednom prípade vlastný zapojený do obvodu (`10kΩ`), v druhom prípade sme použili zabudovaný rezistor (odpor niekde v rozsahu od `20kΩ` do `50kΩ`). Interný rezistor sa zapína pri nastavení `pinMode` s možnosťou `INPUT_PULLUP`, čo znamená, že nastavujeme pin na čítanie a zároveň aktivujeme pull-up rezistor.

Podľa spôsobu zapojenia rozlišujeme dva typy rezistorov. V kontexte tlačidla a Arduino Nano platí:

* **Pull-up** - predvolene má hodnotu `5V`, pri stlačení je `0V`. Môžeme využiť aj zabudované rezistory v Arduine. Častejšie sa používa tento rezistor.
* **Pull-down** - predvolene má hodnotu `0V` a pri stlačení `5V`. Je potrebné použiť externý rezistor. Využitie to má napríklad pri meraniach zo senzora, ktorý poskytuje `HIGH`, keď je aktívny (napr. na prítomnosť magnetického poľa - *Hall senzor* alebo *Reed Switch*).

```{figure} ../img/arduino/pullup.png
---
width: 500px
name: pullup
---
Pull-up (vľavo) a pull-down (vpravo) rezistor.
```

### Debouncing

Pri prepínaní tlačidla môže nastať efekt, ktorý sa nazýva **debouncing**. Ide o situáciu, keď sa pri zmene stavu môžu vyskytnúť nechcené rýchle zmeny v signáli, ktoré sú natoľko výrazné, že menia samotný stav medzi `HIGH` a `LOW`.

```{figure} ../img/arduino/debouncing.png
---
width: 400px
name: debouncing
---
Debouncing - kolísanie hodnoty pri prepnutí stavu tlačidla.
```

Prevencia pred týmto efektom je možná dvoma spôsobmi:

* **softvérovo** - najjednoduchšie je použiť krátky `delay` (napr. `delay(50)`). Konkrétne pri detekcii stlačenia počkať 50ms a potom overiť znovu, či je tlačidlo stlačené. V prípade, ak nechceme blokovať vykonávanie kódu cez `delay`, je možné overiť uplynutý čas medzi jednotlivými meraniami. 
* **hardvérovo** - použitím kapacitora (napr. `0.1µF`), ktorý zapojime paralelne s pull-up rezistorom. **Kapacitor** akumuluje elektrický náboj (energiu) a následne po odpojení ho uvoľňuje. Funguje ako dočasný zásobník energie, ktorý svojími vlastnosťami potláča nežiaduci efekt debouncingu.
