Vydělávej až 160.000 Kč měsíčně! Akreditované rekvalifikační kurzy s garancí práce od 0 Kč. Více informací.
Hledáme nové posily do ITnetwork týmu. Podívej se na volné pozice a přidej se do nejagilnější firmy na trhu - Více informací.

Lekce 7 - Čtení uživatelských vstupů v Arduinu

V předchozím kvízu, Kvíz - Datové typy, podmínky a cykly v Arduinu, jsme si ověřili nabyté zkušenosti z předchozích lekcí.

V dnešní lekci Arduino tutoriálu se budeme zabývat tématem čtení vstupů zadaných uživatelem. Čtení vstupu od uživatelů je jednou z klíčových funkcí v programování pro platformu Arduino. Umožňuje nám reagovat na akce uživatelů. Ti mohou takto například rozsvěcet LED diody, nastavovat jim intenzitu jasu a podobně regulovat různé komponenty.

V tomto článku si ukážeme různé způsoby, jak číst vstupy od uživatelů. Uvedeme si také konkrétní příklady, jak jednotlivé funkce pro čtení implementovat do našeho kódu.

Funkce Serial.available()

Představme si nejdříve funkci Serial.available(). Pomocí této funkce získáme informaci o počtu bajtů, které jsou k dispozici ke čtení v přijímacím bufferu sériového portu. Můžeme ji tedy použít k ověření, zda jsou k dispozici data k přečtení. Další funkce tak budeme volat až poté, co uživatel pošle data ke čtení.

Funkce Serial.available() vrací celé číslo odpovídající počtu bajtů, jež máme k dispozici. Pokud je v bufferu 10 bajtů, vrátí nám hodnotu 10 a podobně. Dokud uživatel nic nezadá, vrací funkce hodnotu 0.

Funkci Serial.available() použijeme v kombinaci s cyklem while nebo s podmínkou, abychom ověřili, zda jsou k dispozici data k přečtení. Teprve poté se pustíme do samotného čtení dat.

Použití Serial.available() s while cyklem

Příklad využití funkce Serial.available() s while cyklem vypadá takto:

byte hodnota_vstupu;

void setup()
{
  Serial.begin(9600);
}

void loop()
{
  while (Serial.available() > 0)
  {
     hodnota_vstupu = Serial.read();

     // Nyní s načtenou hodnotu můžeme dále pracovat, my si ji necháme vypsat.

     Serial.println(hodnota_vstupu);
  }
}

Pomocí while cyklu zjišťujeme, zda je hodnota funkce Serial.available() vyšší než 0. Pokud ano, přikročíme ke čtení dat a jejich zpracování v těle cyklu.

Použití Serial.available() s podmínkou

Použití podmínky je podobné. Funkce loop() poté vypadá takto:

void loop()
{
  if (Serial.available() > 0)
  {
     hodnota_vstupu = Serial.read();

     // Nyní s načtenou hodnotu můžeme dále pracovat, my si ji necháme vypsat.

     Serial.println(hodnota_vstupu);
  }
}

Pro čtení dat z uživatelského existuje několik funkcí. V ukázkách výše jsme použili funkci Serial.read(). K dispozici máme ale i další funkce. Všechny se používají pro čtení, avšak je mezi nimi rozdíl. Ten spočívá v tom, jaký typ dat chceme číst a jakým způsobem jsou tato data zpracována. Pojďme si je postupně ukázat a popsat si jejich specifika.

Funkce Serial.readString()

Pro práci s textovými řetězci využijeme funkci Serial.readString(). Funkce nám dobře poslouží, jestliže očekáváme na vstupu od uživatele zadaný text.

Ukázkový kód s implementací této funkce vypadá následovně:

String text_vstup; // Vytvoříme si proměnnou typu String pro uložení textového řetězce.

void setup()
{
  Serial.begin(9600); // Nastavíme sériový monitor.
}

void loop()
{
  if (Serial.available() > 0) // Zkontrolujeme, zda se v bufferu nacházejí data.
  {
     text_vstup = Serial.readString(); // Přečteme data a uložíme je do naší proměnné.
     Serial.print("Vase zprava: ");
     Serial.println(text_vstup); // Vypíšeme získaná data do sériového monitoru.
  }
}

Pozor! Vývojové prostředí Tinkercad, které v kurzu používáme, nepodporuje českou diakritiku. Texty je tedy potřeba psát bez háčků a čárek a dalších speciálních znaků.

Funkce Serial.read()

Přejděme k funkci Serial.read(). Tato funkce čte jeden bajt dat z bufferu sériového portu a vrací ho jako celé číslo. Postupně tedy načítá data ze sériového portu a vrací ASCII hodnotu pro každý zadaný znak. Funkci Serial.read() můžeme použít ke čtení libovolného typu dat.

Upravme náš ukázkový příklad a nechme si vypsat hodnoty získané pomocí funkce Serial.read():

byte znak_vstup; // Vytvoříme si proměnnou typu byte pro uložení znaku.

void setup()
{
   Serial.begin(9600);
}

void loop()
{
   if (Serial.available() > 0) // Zkontrolujeme, zda se v bufferu nacházejí data.
   {
      znak_vstup = Serial.read(); // Načteme zadaný znak a uložíme ho do naší proměnné.
      Serial.print("ASCII hodnota vlozeneho znaku: ");
      Serial.println(znak_vstup); // Vypíšeme číslo odpovídající hodnotě znaku v ASCII tabulce.
   }
}

Zadáme-li například písmeno a, vypíše se nám hodnota 97. To je hodnota znaku a v ASCII kódování. Zadáním písmena b získáme 98 atd. Zkusme si v příkladu zadat delší text, např. ahoj. Vidíme, že funkce Serial.read() projde postupně všechny znaky a vypíše pod sebe jejich ASCII hodnoty.

Kdybychom pomocí funkce Serial.read() načítali číselnou hodnotu, získáme opět její ASCII kód. Číslo 1 má hodnotu 49 atd.

Funkce Serial.parseInt()

Ukažme si nyní zpracování celočíselných hodnot načítaných ze sériového portu. K tomu nám nejlépe poslouží funkce Serial.parseInt(). Funkce čte bajty z bufferu, dokud nenarazí na konec čísla nebo na jiný nečíselný znak (např. mezeru nebo koncový znak řetězce).

Načítání celých čísel pak vypadá následovně:

int cislo_vstup;

void setup()
{
  Serial.begin(9600);
}

void loop()
{
  if (Serial.available() > 0)
  {
    cislo_vstup = Serial.parseInt();
    Serial.print("Vlozene cislo: ");
    Serial.println(cislo_vstup);
  }
}

Jako datový typ naší proměnné jsme použili int. Zkusme si jej v kódu přepsat na byte. Víme, že proměnné typu byte mohou nabývat hodnot 0255. Když nyní zadáme -2, překročíme limit typu byte a na sériovém monitoru se nám vypíše 254. Pokud funkci Serial.parseInt() zkusíme poslat znak nebo celý textový řetězec, vrátí nám hodnotu 0.

Parsování vstupu

Funkce Serial.parseInt(), kterou jsme si popsali výše, je součástí knihovny Serial pro Arduino. Tuto funkci lze volat přímo na objektu Serial a automaticky převádí řetězec v bufferu na celé číslo. Převodu datových typů se říká parsování a tento termín figuruje již v názvu funkce.

Pro parsování existuje ale také metoda toInt(). Tu využijeme kdykoliv budeme potřebovat převést textový řetězec na celé číslo. Tuto metodu voláme přímo na objektu typu String.

Stejného výsledku jako v předchozím příkladu, dosáhneme s použitím metody toInt() následovně:

String vstup;
int cislo;

void setup()
{
  Serial.begin(9600);
}

void loop()
{
  if (Serial.available() > 0)
  {
    vstup = Serial.readString();
    cislo = vstup.toInt();
    Serial.print("Vlozene cislo: ");
    Serial.println(cislo);
  }
}

Zadaný vstup jsme tedy nejdříve načetli a uložili jako textový řetězec funkcí readString(). Poté jsme do proměnné typu int uložili parsovaný vstup. Výsledek jsme si opět nechali vypsat na sériový monitor.

Ošetření vstupů

Zastavme se ještě u tématu, které se čtením vstupů úzce souvisí. V našem programu je velice důležité myslet i na ošetření nesprávně zadaných hodnot. Jedná se například o případ, kdy vyžadujeme číslo a uživatel nám zadá text. V naší aplikaci ho pak na to musíme upozornit, aby se program choval předvídatelně.

K ošetření vstupů využijeme podmínky, případně konstrukci switch.

Pro kontrolu, zda uživatel zadal číslo, upravíme předchozí kód například takto:

String vstup;
int cislo;

void setup()
{
  Serial.begin(9600);
}

void loop()
{
  if (Serial.available() > 0)
  {
    vstup = Serial.readString();
    cislo = vstup.toInt();

    if (cislo != 0)
    {
      Serial.print("Vlozene cislo: ");
      Serial.println(cislo);
    }
    else
    {
      Serial.println("Nespravna hodnota, zadej znovu.");
    }
  }
}

Pokud se nám podaří načíst číselnou hodnotu, necháme ji vypsat na sériový monitor. Jestliže uživatel zadá nečíselný znak, vyzveme jej k zadání nového vstupu.

V následujícím cvičení, Řešené úlohy k 6.-7. lekci programovacího jazyka Arduina, si procvičíme nabyté zkušenosti z předchozích lekcí.


 

Předchozí článek
Kvíz - Datové typy, podmínky a cykly v Arduinu
Všechny články v sekci
Arduino - Programovací jazyk
Přeskočit článek
(nedoporučujeme)
Řešené úlohy k 6.-7. lekci programovacího jazyka Arduina
Článek pro vás napsal Dominik Němeček
Avatar
Uživatelské hodnocení:
39 hlasů
Autor se věnuje programování mikropočítačů Arduino.
Aktivity