Nauč se s námi víc. Využij 50% zdarma na e-learningové kurzy.
discount week 50

Lekce 11 - Arduino - Jazyk

S desátým dílem jsem se ohlédl za tím, co vše jsem již napsal, a zjistil, že se mi poměrně dobře dařilo vyhýbat se vysvětlování jazyka. Ve 4. dílu to bylo takové vysvětlování-nevysvětlování a v ostatních se občas objevila nějaká ta poznámka a to bylo všechno. Většina z vás již toho mnoho pochytila z minulých dílů, nebo to zná z jiných jazyků, ale pro jistotu si to projdeme. Takže v tomto díle si projdeme jazyk a završíme to tvorbou vlastní knihovny.

Co je to vůbec za jazyk?

Několik lidí se mě na to ptalo a ačkoliv se Arduinem zabývám docela dlouho, tak ani po roce se mi nepovedlo najít jednoznačnou odpověď. Teď se pohybuji na tenkém ledě, když to řeknu, ale vím zhruba toto: Jazyk je odvozený z Wiringu, upravili si ho podle sebe a jmenuje se jednoduše Arduino Language.

Základní syntaxe

Při psaní kódu je třeba dbát na několik pravidel. Nejspíše jste je odchytily z minulých dílů, ale pro úplnost je zde připomenu.

  • Na konci každého řádku s voláním funkce nebo deklarací proměnné je ; (středník). Nedává se jen za řádky s if, else, void, atd a řádky, kde jsou jen závorky, které tyto části kódu ohraničují. A jelikož výjimka potvrzuje pravidlo a abychom to neměli tak jednoduché, tak víceřádková deklarace 2D pole má jen jeden středník za ukončením deklarace.
  • Ohraničování částí kódu s { a }. Vše, co pod něco spadá, tj. věci v setupu, loopu, námi definovaných funkcí, if, else atd. se musí dát mezi ty havraní závorky. Samozřejmě výjimka potvrzuje pravidlo, takže pokud se po if, else nachází jen jeden jediný řádek, lze závorky vynechat.

Proměnné

Bez proměnných by to nešlo. Proměnné jsou místo v paměti, do kterého můžeme uložit nějakou hodnotu, libovolně ji měnit a libovolně si ji pojmenovat. Máme hned několik typů proměnných:

char Znak, nabývá hodnoty právě jednoho ASCII znaku
byte Je schopen uložit jedno 8 bitové číslo (0-255)
int Nabývá hodnot celého čísla od -32 768 do 32 767 (16 bitů)
unsigned int Podobně jako int, jen se záporné hodnoty "přelijí" do kladných, tedy uloží hodnoty 0-65 535
long Uchovává 32 bitové číslo v rozsahu -2 147 483 648 do 2 147 483 647
unsigned long Obdobně jako unsigned int. 0 - 4 294 967 295
float Desetinné číslo o velikosti 32 bitů
double Desetinné číslo s dvojnásobnou přesností
boolean Nabývá hodnoty 0 (False) až 1 (True)
word Viz. unsigned int
string Uchovává textový řetězec

Jak proměnné deklarovat?

Než proměnné začneme používat, musíme je deklarovat. Pokud se do ní bez deklarace rovnou pokusíme něco uložit, tak nám kompiler vynadá (dá se to přirovnat k tomu, když chcete něco uložit do trezoru, ale žádný trezor jste si nekoupili). Možností deklarace je hned několik:

//první způsob - konstanty, neměnitelné proměnné
#define hodnota = 10 // Hodnotu vytvoříme a rovnou jí nastavíme na 10. Sama se nastaví na int
#define hodnota // Někdy potřebujeme nastavit hodnotu až když je třeba, k tomu slouží tento zápis

//druhý způsob - klasické proměné
int hodnota = 10; // proměnná má nastavený typ int a hodnotu 10
int hodnota; // proměnná typu int bez přiřazené hodnoty

Pokud proměnnou deklarujeme, nepřiřadíme jí hodnotu a poté jí vyvoláme, tak nenastane chyba. Program se bude tvářit, že je v ní 0 (v případě int, float,..), prázdný řetězec(string),...

Proměnným pak můžeme nastavovat různé hodnoty:

vstup = Serial.read();
pocet = 10

A co kdybyste chtěli hodnotu pocet zvýšit nebo snížit o hodnotu v proměnné zmena? Pokud vás napadne:

pocet = pocet + zmena;
pocet = pocet - zmena;

//mimochodem toto se bude jevit jako že se s proměnnou nic neudělalo, protože něco přidáme a hned to samé sebereme

špatně to není, ale není jednodušší napsat

pocet += zmena;
pocet -= zmena;
Tento výukový obsah pomáhají rozvíjet následující firmy, které dost možná hledají právě tebe!

?

Podmínky

Bez podmínek se prakticky neobejdete. Prostě se stále dostáváte do situací, kdy budete potřebovat, aby se jedna část provedla jen když něco platí. Podmínka se řeší pomocí příkazu if (anglicky pokud). Dále tu je ještě else if (nebo pokud) a else (jinak). A jak to funguje? Pokud chceme jen jednu podmínku, tak použijeme jednoduše if

if( podmínka )
{
    // Udělej toto
}

Pokud chceme více podmínek, tak jsou dvě možnosti - záleží na tom, jestli nám je jedno, jestli se jich splní více, nebo jestli chceme, aby se něco stalo v případě, že žádná neplatí.

if( podminka1)
    cinnost1
if( podmínka 2)
    cinnost 2
else
    cinnost 3

Co se zde stane? Dejme tomu, že bychom chtěli, aby se v případě podmínky jedna vykonala činnost 1, v případě podmínky 2 činnost 2 a v případě žádné podmínky činnost 3. Pokud se nesplní ani podmínka 1, ani 2, tak se vykoná činnost 3. Pokud se splní podmínka 2, tak se vykoná činnost 2, ale pokud se splní podmínka 1, tak se vykoná činnost 1 a 3. Jakto? Protože druhé if program bere jako další oddělenou část, takže vykoná podmínku 1 a přejde k druhému if s tím, že se jedná o další věc, kterou třeba otestovat. Podmínka 2 se nesplní, takže se vykoná else. Jak tedy programu říci, aby to celé bral jako jednu část?

Jednoduše, místo druhého if vložíme else if. Program tedy bude fungovat stylem:

Pokud souhlasí první podmínka (if) //pokud ne, přejde na další
    Udělej činnost 1
Nebo pokud souhlasí tato podmínka (else if) //pokud ne, přejde na další
    Udělej činnost 2
Jinak, pokud nic nesouhlasí (else)
    Udělej činnost 3

Takže to je systém fungování podmínek. A jak je používat?

Operátory k podmínkám

Takže co chceme v kódu kontrolovat? Velmi často se setkáme s tím, že nějaká funkce vrátí true nebo false, podle toho, jestli se akce povedla. Pokud chceme zkontrolovat výsledek na true, tak není třeba nic porovnávat, prostě napíšeme

if(vysledek)

A pokud je výsledek true, tak se if vykoná, pokud je false, tak nikoli. Co ale když chceme porovnat nějaká čísla? Zde máme několik operátorů. Ty napíšeme jednoduše mezi dvě hodnoty do závorek za if.

Takže máme zápis:

if( x <operator> y)

Co můžeme dosadit za operátory?

Operátor Kompletní zápis Význam
== x == y pokud se x rovná y
!= x != y pokud se x nerovná y
< x < y pokud je x menší než y
> x > y pokud je x větší než y
<= x <= y pokud je x menší nebo rovno y
>= x >= y pokud je x větší nebo rovno y

To jsou všechny operátory, které Arduino dokáže zpracovat. Ovšem musíme porovnávat věci, které se porovnávat dají. Chyba by byla napsat něco ve stylu if (pocet_kusu_nas­klade(int) >= seznam_zakazni­ku(string))!

Kombinování podmínek & logické operátory

Dejme tomu, že potřebujeme podmínek ověřit více. Jako příklad si vezměme něco ze života. Někdo si jde koupit alkohol a my potřebujeme ověřit několik věcí - bylo mu 18 let? Je Becherovka na skladě? A má u sebe dostatečný obnos? Jak na to? Pokud začnete hned bušit

if( vek >= 18)
{
    if (napoj.jeNaSklade)
    {
        if( hotovost >= napoj.cena)
        {

Tak to sice taky půjde, ale použitelné to je jen v případě, když budeme chtít přijít na to, kde nastala chyba (pomocí else ke každému if). Pokud ale chceme otestovat vše bez ohledu na to, kde to neplatí, tak můžeme všechny 3 podmínky sloučit do jednoho ifu. Jak?

Pomocí logických operátorů:

  • && - neboli a (P Alt + C)
  • || - neboli nebo (P Alt + W)

    && nám vrátí True, pokud platí obě podmínky, které spojujeme. Pokud některá z nich neplatí, vrátí false.

    || nám vrátí True, pokud alespoň jedna z podmínek je True. Pokud jsou obě False, vrací False.

A jak to tedy spojit?

if ((vek >= 18 & (napoj.jeNaSklade == true & (hotovost >= napoj.cena))))

Zde je důležité dbát na to, že pokud spojujeme podmínky s ==, > atd, tak je lepší, když je každá část v závorce, jinak to dělá neplechu.

Dále existuje ještě operátor !, který neguje, takže

!true //je false
!false //je true

if(!Serial.available())
{
    //se vykoná jen když sériový port nebude k dispozici

Pokračujte prosím k druhému dílu.


 

Předchozí článek
Sedmisegmentový display a pole pro Arduino
Všechny články v sekci
Arduino
Článek pro vás napsal Adam Ježek
Avatar
Jak se ti líbí článek?
8 hlasů
Autor se převážně věnuje Arduinu a psaní tutoriálů z této oblasti, občas napíše příležitostně nějakou tu zprávičku. Většinu svého volného času momentálně věnuje Linuxu a/nebo Raspberry Pi. Také umí C#, HTML, CSS, PHP a Python.
Aktivity

 

 

Komentáře

Avatar
rhli
Člen
Avatar
rhli:29.3.2015 18:10

Serial je bezva a moc mi omohl v zacatcich s arduinem.diky RoHl

Odpovědět
29.3.2015 18:10
tata
Avatar
Jiří Šachl:12.4.2015 14:15

Zdravím. Řeším problém se smyčkou loop kde potřebuji aby se prováděly kroky programu s různým časováním.
Konkrétněji : něco běží stále, něco poběží 45 sekund, pak 5 minut nic a pak zase 45 sekund a tak dokola. Něco běží co 5 minut, něco každou minutu, něco 2x denně a něco když čidlo dá pokyn tak čas který další čidlo zastaví (samostatná funkce). Program poběží na Arduino MEGA s RTC (DS1307 AT24C32). Poradíte ?

 
Odpovědět
12.4.2015 14:15
Avatar
Adam Ježek
Redaktor
Avatar
Odpovídá na Jiří Šachl
Adam Ježek:12.4.2015 14:36

No jestli to běží každých 5 minut, něco každých 45s... máš RTC, takže si z něj zjistíš čas (hh:mm:ss), teď si nepamatuju jak se s nim dělá, ale budu počítat s tim, že už mám čas, takže

void loop( {
int hodiny;
int minuty;
int sekundy; //tohle sis zjistil z rtc

if( minuty % 5 == 0) {
    kazdychPetMinut();}

int sec = vteriny + (minuty*60)
if( sec % 45 == 0) {
    kazdychCtyricetPetSekund(); }

if(hodiny % 12 == 0 && denne) { //denne je nejaky bool, ktery si deklaroval na zacatku
    dvakratDenne();
    denne = false; }

if(hodiny % 5 && !denne)
    denne = true;


....
}

Trochu sem nepochopil tu část něco když čidlo dá pokyn tak čas který další čidlo zastaví (samostatná funkce), zkus to líp formulovat
Dejme tomu, že tam máš funkci, kterou když zavoláš, tak zkontroluje něco, a podle toho, zda se to má vykonat by vrátila true/false, takze v loopu dalsi

if(zkontrolujCidlo()) {
    vykonejNaCidlo();
}

a s dalšíma věcma by si možná moh zajít do fóra :)

Odpovědět
12.4.2015 14:36
Počkej chvíli, poradím se s křišťálovou koulí.
Avatar
 
Odpovědět
12.4.2015 14:40
Avatar
Adam Ježek
Redaktor
Avatar
Odpovídá na Jiří Šachl
Adam Ježek:12.4.2015 22:45

Ted mi doslo, ze u tech vterin modulo neni zrovna nejlepsi reseni(nemusel bys to stihnout). A u minut asi taky ne, tam by se to mohlo stihnout provist vicekrat. Mozna to udelat pres pocitani kdy to naposled probehlo (viz muj prispevek zde http://www.itnetwork.cz/…52abd07c11a4#… ) jen pokud misto pocitani casu z rtc zvolite millis(), tak pokud arduino pobezi dele nez 50 dni(predpokadam ze u toho projektu se zavlazovanim ano), tak se po 50 dnech hodnota vynuluje a bezi odznova, takze bude treba vynulovat i ulozene casy

if(millis()<3000)//snad se stihne
naposledyVykonanoCas = 0;
Editováno 12.4.2015 22:49
Odpovědět
12.4.2015 22:45
Počkej chvíli, poradím se s křišťálovou koulí.
Avatar
Odpovídá na Adam Ježek
Jiří Šachl:13.4.2015 7:24

Díky, ověřím si to později. Odešel mi nový Ardiuno MEGA tak části kodu odlaďuji na UNU než mi nové dojde z Číny.

 
Odpovědět
13.4.2015 7:24
Avatar
Jiří Šachl:13.4.2015 7:36

Ptal jsem se i jinde a dostal jsem tuhle odpověď..někomu se to může hodit, prostuduju to co ten TaskSheduler umí...http://fo­rum.robodoupe­.cz/viewtopic­.php?f=13&t=371&p=2272#p­2272

 
Odpovědět
13.4.2015 7:36
Avatar
Tomáš Brůna
Redaktor
Avatar
Tomáš Brůna:21.4.2015 21:09

Ahoj jde použít jako podmínka

if (led, HIGH)**{}**

?

Odpovědět
21.4.2015 21:09
Vi veri universum vivus vici
Avatar
Adam Ježek
Redaktor
Avatar
Odpovídá na Tomáš Brůna
Adam Ježek:21.4.2015 21:16

Tef te nechapu. Chces zjistit jesti je na pinu proud nebo ne?

Odpovědět
21.4.2015 21:16
Počkej chvíli, poradím se s křišťálovou koulí.
Avatar
Tomáš Brůna
Redaktor
Avatar
Odpovídá na Adam Ježek
Tomáš Brůna:21.4.2015 22:06

chci pokus je led dioda rozsvicena aby po zmacknuti klavesy 'A' zhasla

Odpovědět
21.4.2015 22:06
Vi veri universum vivus vici
Avatar
CZkiniCZ
Člen
Avatar
CZkiniCZ:3.6.2015 16:56

Stavím si z Arduina zámek s klávesnicí, displejem a chci si tam přidat i menu k nastavování proměných (kolik s máš na otevření, kolik pokusů zadat pin máš apod . . .), jenže jsem se trochu zamotal v podmínkách. Má to fungovat tak že když přijdu ke klávesnici tak zadám pin a zmáčknu ent aby mě to odemklo (to funguje). Když se chci dostat do menu (už se ztrácím) tak musím zmáčknout F1, vybrat co chci upravit a zmáčknout ent abych tu položku zvolil. To už ale nevím jak udělat. Kod pro odemčení mám takový:
switch (eKey){
case 'E': checkPassword(); break;
case 'C': password.reset(); break;
default:passwor­d.append(eKey);
}
a tet když do toho chci přidat to menu tak mi to nepůjde.
Kod pro menu:

switch (eKey){
case '>':
case '^': uparrow(); break;
case 'v': downarrow(); break;
case '<':
case 'E': execute(); break;
}

Samostatně mi ty programy fungují, ale nevím jak je sloučit dohromady (ta podmínka je jediná věc se kterou si nemůžu poradit).

Odpovědět
3.6.2015 16:56
Age of the geek.
Avatar
Adam Ježek
Redaktor
Avatar
Odpovídá na CZkiniCZ
Adam Ježek:3.6.2015 18:35

Asi bych si tam dal nějaký boolean, který bych po zmáčknutí F1 pro menu změnil. A pak by si měl pokud je false, tak kód pro zámek, pokud true, tak kód pro menu.

Odpovědět
3.6.2015 18:35
Počkej chvíli, poradím se s křišťálovou koulí.
Tento výukový obsah pomáhají rozvíjet následující firmy, které dost možná hledají právě tebe!
Avatar
CZkiniCZ
Člen
Avatar
Odpovídá na Adam Ježek
CZkiniCZ:3.6.2015 19:31

Pořát to nemůžu to přinutit aby to reagovalo na stisknutí klávesi F1. Co jsem našel návody na google tak všude je to jen na spínač a já nevím jak tam implementovat tu klávesnici.

Odpovědět
3.6.2015 19:31
Age of the geek.
Avatar
Adam Ježek
Redaktor
Avatar
Odpovídá na CZkiniCZ
Adam Ježek:3.6.2015 20:37

Zkus si přečtené znaky posílat na sériovou linku. Jestliže všechno funguje, jenom jednu klávesu nějak nezachytíš, tak buď nefunguje, nebo ji píšeš jinak než má být.

Odpovědět
3.6.2015 20:37
Počkej chvíli, poradím se s křišťálovou koulí.
Avatar
CZkiniCZ
Člen
Avatar
Odpovídá na Adam Ježek
CZkiniCZ:3.6.2015 20:48

Všechny klávesy mi fungují ale furt se mi to nedaří rozchodit. Spíš by mi pomohl nějaký tutoriál, nebo ukázka kodu.

Odpovědět
3.6.2015 20:48
Age of the geek.
Avatar
Adam Ježek
Redaktor
Avatar
Odpovídá na CZkiniCZ
Adam Ježek:3.6.2015 20:50

Mě by zase pomohlo, kdyby si ukázal tvůj kód. Zkus založit vlákno ve fóru ( http://www.itnetwork.cz/…-elektronika )a hoď to tam. Ale jestli ty to samostatně funguje, tak by to mělo jít přes if spojit. Pošli a uvidíme :)

Odpovědět
3.6.2015 20:50
Počkej chvíli, poradím se s křišťálovou koulí.
Avatar
ostrozan
Redaktor
Avatar
ostrozan:14.2.2016 15:26

ale vím zhruba toto: Jazyk je odvozený z Wiringu, upravili si ho podle sebe a jmenuje se jednoduše Arduino Language.

týká se to ale pouze hlavního - main sketche vašeho projektu - knihovny jsou psané v tom Wiringu a tak když byste si chtěli napsat svoji vlastní knihovnu, kdybyste náhodou na něco nenašli na GitHubu (což pochybuju) tak stejně jako kdybyste nějaký složitěší sketch chtěli rozdělit do více souborů - musíte to napsat ve Wiringu

Wiring je pro mikrokontrolery upravený C++ ale pozor, není to plnohodnotný objektový jazyk, protože mikrokontrolery v žádném případě objektový přístup nezvládnou - Wiring využívá spíše syntaxi C++ je to takový přechod mezi C a C++

Editováno 14.2.2016 15:28
 
Odpovědět
14.2.2016 15:26
Avatar
sidn
Člen
Avatar
sidn:5.2.2017 12:35

Zdravím mám problém potřebuji spojit dvě proměnné, tak aby 1 a 1 davali 11 a ne 2. V php se to děla tečkou (.), ale ve Wiring jsem něco podobného nenašel asi jsem málo hledal. Tak prosímo radu.

 
Odpovědět
5.2.2017 12:35
Avatar
Adam Ježek
Redaktor
Avatar
Odpovídá na sidn
Adam Ježek:5.2.2017 12:42
int result = (String(numberOne)+String(numberTwo)).toInt();

Budou i elegantnější řešení, ale tohle je takové nejjednodušší.

Odpovědět
5.2.2017 12:42
Počkej chvíli, poradím se s křišťálovou koulí.
Avatar
Jarda Jandac
Člen
Avatar
Jarda Jandac:17.2.2018 14:00

Info na vašich stránkách mi moc pomáhá při učení se programovat ARDUINO. Moc dík

 
Odpovědět
17.2.2018 14:00
Avatar
Roman Havala
Člen
Avatar
Roman Havala:18.2.2018 15:52

Dobrý den nevím si rady z podminkou chci aby při 45% se vypne rele a při 65% se sepne relé

Dekuji

 
Odpovědět
18.2.2018 15:52
Avatar
Patrik Ulrych:17.4.2018 7:24

Teprve se učím. Je možné kombinovat logické operátory s negací (!&-NAND,!|-NOR?

 
Odpovědět
17.4.2018 7:24
Avatar
Josef Půta
Člen
Avatar
Josef Půta:26.4.2020 21:38

V lekcích tohoto kursu zatím tuším příjemné doplňování detailů těch fenomenů, které jsem již studoval v jiných učebnicích jazyka Arduino, tedy wiring ? Lekce jsou velmi dobře koncipované.

 
Odpovědět
26.4.2020 21:38
Avatar
Lukas Luska
Člen
Avatar
Lukas Luska:14.6.2020 2:11

Ahoj jen zvedavost,
nemělo by být v logockem operátorů and 2x &?

V příkladu je jen jeden...

Nyni

if ((vek >= 18 & (napoj.jeNaSklade == true & (hotovost >= napoj.cena))))

Oprava

if ((vek >= 18 && (napoj.jeNaSklade == true && (hotovost >= napoj.cena))))
Editováno 14.6.2020 2:12
 
Odpovědět
14.6.2020 2:11
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 24 zpráv z 24.