Lekce 9 - Funkce a knihovny
V předchozí lekci, Pole a konstanty, jsme se zaměřili na pole. Probrali si jejich plnění i přístup k obsahu a poté se podívali na konstanty.
V tomto tutoriálu programovacího jazyka pro Arduino se zaměříme na funkce. Vysvětlíme si, jak se funkce tvoří, co to znamená void, parametr funkce, a co je návratová hodnota. Nakonec si povíme, co jsou to statické knihovny.
Funkce
V každém programu pro Arduino máme dvě základní funkce -
setup()
a loop()
. Jak již víme, setup()
se vykoná jen jednou, zatímco loop()
se pak vykonává v
nekonečné smyčce. Náš programovací jazyk nám ale umožňuje vytvářet si
i funkce vlastní. Jako příklad si vezměme opět situaci, kdy chceme zablikat
diodou. Můžeme ve všech případech vypisovat:
... digitalWrite(13, HIGH); // zabliká delay(500); digitalWrite(13, LOW); delay(500); digitalWrite(13, HIGH); delay(500); digitalWrite(13, HIGH); // zabliká delay(500); digitalWrite(13, LOW); delay(500); digitalWrite(13, HIGH); delay(500); ...
Můžeme také využít cyklu for
a pole, jak jsme se to
naučili v předchozí lekci. Pokud ale budeme potřebovat blikání v různých
částech kódu a navíc například s různým počtem pinů a jinou prodlevou,
museli bychom cyklus kopírovat a vkládat na různá místa programu. A navíc
i měnit jeho parametry. To je nepohodlné. Jednodušším řešením je
vytvořit vlastní funkci.
Každá funkce má datový typ podle typu dat, který vrací. Pokud žádná
data nevrací, má speciální datový typ void
. Uvnitř funkce
můžeme používat všechny proměnné, které jsme si definovali na začátku
programu. Naopak to ale neplatí. Proměnné, definované uvnitř funkce, nejsou
pro zbytek programu viditelné. Z hlediska umístění nezáleží na tom, kde
funkci v programu definujeme, tedy jestli před nebo za funkcemi
setup()
a loop()
. Jen ji nesmíme definovat uvnitř.
Pokud se funkce dokončí, vrátí se kód na místo, kde jsme funkci zavolali,
a pokračuje dál.
Funkce bez návratové hodnoty
Funkce je tedy blok příkazů, které se po jejím zavolání provedou.
Ukažme si nyní jednoduchý příklad funkce, která nemá návratový typ (je
typu void
):
... void blikniPin13() { digitalWrite(13, HIGH); delay(500); digitalWrite(13, LOW); delay(500); digitalWrite(13, HIGH); delay(500); digitalWrite(13, LOW); } void loop() { ... blikniPin13(); // zabliká ... }
Void funkce s parametry
Pokud se rozhodneme, že LEDka nebude blikat po půl sekundě, ale po jedné sekundě, nemusíme vytvářet novou funkci s jinou délkou prodlevy. Co kdybychom to potřebovali změnit třeba pětkrát a použít pokaždé jiné piny? Nebudeme kvůli tomu přeci vytvářet stále nové jednoúčelové funkce. Vytvoříme si takovou, kterou bude možné našim potřebám jednoduše přizpůsobit. Přidáme funkci vstupní parametry:
... void blik(int pin, int prodleva) { digitalWrite(pin, HIGH); delay(prodleva); digitalWrite(pin, LOW); delay(prodleva); } void loop() { ... blikni(13, 500); // zabliká na pinu 13 blikni(10, 500); // zabliká na pinu 10 ... }
V hlavičce funkce void blik()
se nám v závorce objevily nové
proměnné pin
a prodleva
, obě datového typu
int
. V kódu funkce loop()
pak funkci
blikni()
voláme tak, že jí do závorky vložíme konkrétní
čísla, která uvnitř ní chceme využít jako číslo pinu a délku
prodlevy.
Funkce s návratovou hodnotou
Pokud má naše funkce vracet nějakou hodnotu, například výsledek
výpočtu, musí mít jiný datový typ než void
. Návratový
datový typ musí logicky odpovídat obsahu, který funkce vrací. Pro vrácení
výsledné hodnoty se používá příkaz return
. Ukažme si
jednoduchý příklad:
int sectiCisla(int cisloA, int cisloB) { int soucet = cisloA + cisloB; return soucet; } void setup() { Serial.begin(9600); Serial.println(sectiCisla(10,11)); } void loop() { }
Vidíme, že namísto typu void
nyní máme typ
int
. To překladači říká, že příkaz return
vrátí číselnou hodnotu v rozsahu typu celé číslo. Správně definované
funkce můžeme potom použít na libovolném místě programu jako jakýkoliv
jiný příkaz. Tedy i uvnitř jiných funkcí.
Arduino knihovny
Důležitou součástí programovacího jazyka Arduina jsou knihovny. Název
je v tomto případě velmi popisný. Jedná se o katalogy předpřipravených
funkcí. Některé už dobře známe. Například naše funkce
delay()
, která přijímá číselnou hodnotu v milisekundách. Pro
Arduino existuje velké množství předpřipravených knihoven, například pro
matematické funkce (asi nikomu se nechce vytvářet vlastní algoritmus pro
druhou odmocninu). Kromě těchto již hotových knihoven si ale můžeme napsat
i své vlastní.
Použití knihoven
Výhodou knihoven je to, že nás jako uživatele vůbec nemusí zajímat, co obsahují, nebo dokonce v jakém jazyku jsou naprogramované. Stačí nám znát jméno funkce a případně parametr(y) a návratovou hodnotu. O všechno ostatní se pak postará knihovna sama. Knihovny jsou jednou z největších deviz Arduina. Tisíce a tisíce programátorů píší své knihovny, které často publikují na internetu. Nic nám pak nebrání si je stáhnout a přidat do IDE. Zjistíme, že velké množství problémů už někdo dříve vyřešil, či případně budeme schopni podobné řešení upravit sobě na míru. Setkat se můžeme se dvěma typy knihoven, statickými a dynamickými.
Vždy je nutné si důkladně prostudovat dokumentaci ke knihovně, v praxi to ušetří mnoho času.
Statické knihovny
Funkce statických knihoven voláme společně se jménem knihovny. Už jsme to používali v praxi a nyní si vysvětlíme, jak knihovny fungují na známém příkladu:
void setup() { Serial.begin(9600); Serial.println(sectiCisla(10,11)); } ...
Zaměřme se nyní na řádek Serial.begin(9600);
. Právě slovo
Serial
je jméno této statické knihovny, která v sobě obsahuje
množství různých funkcí. My jsme zatím používali dvě, a to
begin()
a println()
. Důležitá je tečka mezi slovy
serial a begin. Překladači řádek říká: "Z knihovny
Serial
vezmi funkci begin()
a do parametru jí vlož
hodnotu 9600
." Pokud tedy chceme volat funkce statické knihovny,
stačí napsat její jméno, znak tečky, název funkce a případně její
parametry.
O dynamických knihovnách si řekneme později. K jejich pochopení potřebujeme rozumět základům objektově orientovaného programování, na které se zaměříme příště.
V následujícím kvízu, Kvíz - Čtení vstupů, pole, konstanty a funkce v Arduinu, si vyzkoušíme nabyté zkušenosti z předchozích lekcí.