KURZ: Práce s displejem - Možnosti praktického využití

KAPITOLY

MOŽNOSTI PRAKTICKÉHO VYUŽITÍ

Displej řidící jednotky robotické stavebnice LEGO MINDSTORMS NXT lze využít jako výstupní zařízení několika způsoby. Nejjednodušší využití je výpis dat, s kterými pracujeme nebo která jsou snímána senzory. Specifickou možností je zobrazování obrázků a grafických souborů formátu .ric. Pokročilejší uživatelé mohou pomocí displeje vykreslovat křivky a grafy, které vyjadřují dynamicky se měnící hodnoty.

VYUŽITÍ displeje

Praktické využití displeje si ukážeme na třech jednoduchých příkladech. První z nich bude pouze zobrazovat na displeji hodnotu snímanou senzorem. V tomto případě se jedná o zobrazování textu. V druhém příkladu si vysvětlíme jak na displeji zobrazovat grafiku. Konkrétně se bude jednat o vykreslení obrázku smajlíka. Na posledním a zároveň nejsložitějším příkladu si vysvětlíme, jak na displeji zobrazovat průběh grafu průběžně snímaných hodnot některého ze senzorů.

NXT-G

ZOBRAZENÍ TEXTU A HODNOT

Zobrazení jakýchkoliv hodnot na displeji řídící jednotky je v programovacím prostředí NXT-G prováděno ve vše případech pomocí programového bloku DisplayDragged Display. Záleží pouze na typu zobrazovaných dat. V prvním příkladě si přiblížíme možnost nejjednoduššího zobrazení na displeji. Bude se jednat o neustálé zobrazování vzdálenosti zjišťované ultrazvukovým senzorem. Tato hodnota se poté bude neustále zobrazovat na ploše displeje.

Krok 1 - Snímání hodnot

Prvním krokem, který při vytváření programu zrealizujeme, bude neustálé snímání hodnot ultrazvukovým senzorem. Ten je ovládán blokem DistanceSensorDragged Ultrasonic Sensor. V jeho nastavení si zvolíme příslušný port, ke kterému je připojen a nastavíme, aby se vzdálenost vyjadřovala v centimetrech. Abychom zajistili neustálé snímání hodnot, musíme blok umístit do cykluc010 loop large Loop, v jehož nastavení zvolíme možnost Forever, která zajistí neustálé provádění.

 
Krok 2 - Výpis hodnot na displej

Zjištěnou vzdálenost budeme nyní chtít zobrazit na displej řídící jednotky. Do programu si tedy přesuneme blok DisplayDragged Display. V sekci Action vybereme možnost zobrazení textu a zvolíme si řádek displeje, na kterém bude zobrazen. V našem příkladě jsou použity bloky  DisplayDragged Display dva. Druhý slouží k popisu a zobrazuje o řádek výše popisek hodnot.

 
Krok 3 - Převod hodnot

Posledním krokem k úspěšné realizaci programu je převod hodnot. Vzdálenost zjištěná senzorem je totiž vyjádřena v číselné hodnotě, ovšem na displeji musí být zobrazena jako text. Pro převod této hodnoty musíme použít blok NumberToTextDragged Number to Text. Jeho propojení s ostatními bloky můžete vidět na obrázku níže, který zobrazuje výsledný program. Na vstupní konektor bloku je přivedena vzdálenost z konektoru Distance ultrazvukového senzoru. Tuto hodnotu chceme převést na textové vyjádření. Propojíme tedy výstup s názvem Text bloku  NumberToTextDragged Number toText se vstupním konektorem Text bloku  DisplayDragged Display.

 
Výsledný program

Na obrázku můžete vidět výsledný program spolu s propojením konektorů pro převod hodnot. První blok  DisplayDragged Display zobrazuje hodnotu ze senzoru a druhý popisek umístěný o řádek výše.

 

text hotovy program

 

Program ke stažení

Stažení ve formátu .rbt


ZOBRAZENÍ OBRÁZKŮ

Možnost vykreslení obrázků ve formátu .ric si ukážeme na příkladu s využitím světelného senzoru. Na základě zjištěné hodnoty se na displeji zobrazí rozesmátý nebo zamračený smajlík. Pokud bude hodnota nižší než 45, bude smajlík rozesmátý, pokud bude vyšší než 45, bude zamračený.

Krok 1 - Snímání hodnot

Na úvod programu musíme zajistit, aby světelný senzor neustále snímal hodnotu intenzity světla v okolí. Použijeme tedy blok LightSensorDragged Light Sensor pro jeho ovládání a zvolíme příslušný port, ke kterému je připojen. Aby bylo snímání prováděno neustále, umístíme blok do cyklu c010 loop large Loop. Jeho provádění nastavíme na Forever, tedy neustálé.

 
Krok 2 - Porovnání a výpis na displej

Nyní musíme rozlišit, jak vysoká je úroveň intenzity světla. K porovnání slouží blok NumericComparisonDragged Compare. V jeho nastavení v sekci Operation nastavíme volbu nižší než (Less than) 45 a na vstupní konektor bloku přivedeme hodnotu z výstupního konektoru bloku LightSensorDragged Light Sensor s názvem Intensity (intenzita světla v okolí). Následně musíme rozlišit, co se stane, když je podmínka splněna a co v opačném případě. Do programu tedy vložíme podmínku Switch, která je řízená hodnotou (Value). Při splnění podmínky se má na displeji vykreslit rozesmátý smajlík, v opačném případě zamračený. Do obou možností tedy vložíme blok  DisplayDragged Display. Zvolíme vykreslení obrázku (Image) a vybereme příslušné obrázky k vykreslení.

 
Výsledný program

Na obrázku můžete vidět finální podobu programu. Světelný senzor, jehož hodnota je přivedena k porovnání do bloku NumericComparisonDragged Compare a výstupem je následně řízena podmínka Switch. V obou možnostech je umístěn blok DisplayDragged Display pro vykreslení příslušných obrázků. Pro konzistentnost vykreslování je na konec programu umístěn blok WaitForTimeDrag Wait. Tento blok zajišťuje oddálení provádění dalšího příkazu o 1 vteřinu. Všechny bloky jsou umístěny v nekonečném cyklu, aby se program prováděl neustále.

 

obrazek hotovy program

 

Program ke stažení

Stažení ve formátu .rbt


VYKRESLENÍ GRAFU

Pokročilejší možnosti využití výstupu na displej si ukážeme na příkladu, ve které zvukový senzor bude snímat hodnotu hluku v okolí a bude ji zobrazovat na displeji v podobě grafu.

Krok 1 - Deklarace proměnných

Jelikož se bude hodnota zvuku zobrazovat postupně na vodorovné ose X, potřebujeme proměnnou, která bude zaznamenávat postup po jednotlivých pixelech displeje. Příslušnou proměnnou jsme nazvali x. Tato proměnná bude vždy obsahovat pořadové číslo pixelu na ose X, od kterého se bude momentálně vykreslovat křivka zobrazující úroveň zvuku.

Podrobný postup deklarace naleznete v kapitole Vytvoření proměnné nebo konstanty.

 
Krok 2 - Snímání a výpis na displej

V následujícím kroku zrealizujeme zpracování hodnot ze senzoru a následné vykreslování na displej. Použijeme tedy blok SoundSensorDragged SoundSensor. Hodnotu jím zjištěnou nyní budeme odesílat na displej. Jelikož by ale zjištěná hodnota byla příliš vysoká a nebylo by možné ji zobrazit na displeji, vydělíme ji dvěma. K matematickým operacím se používá blok FPNumericOperationsDraggedMath. Hodnotu z výstupního konektoru nazvaného Sound Level přivedeme na vstupní konektor A bloku FPNumericOperationsDragged Math. Zvolíme matematickou operaci Division (dělení) a jako hodnotu B zadáme 2. Tím se nám hodnota zmenšila na polovinu, ale stále ji nemáme zobrazenou na displeji. Vložíme tedy do programu blok DisplayDragged Display. Jako akci zvolíme v sekci Action vykreslování křivek (Drawing). Vykreslování křivek ještě vybereme v sekci Type, kde vybereme volbu Line. Nesmíme zapomenout odškrnout možnost Clear, protože jinak by nám křivka v grafu po vykreslení okamžitě mizela.

Všechny tyto bloky nyní umístíme do cyklu c010 loop large Loop. Tento cyklus bude mít pevný počet průchodů. Tím bude hodnota 100, což je počet pixelů displeje na vodorovné ose X. V sekci Control tedy zvolíme možnost Count (pevný počet průchodů) a zadáme hodnotu 100. Musíme také zaškrnout, že chceme, aby se nám zobrazil konektor pro čítání (Counter). Nyní využijeme nadeklarovanou proměnnou X. Vložíme ji na začátek cyklu a propojíme s jeho čítačem. Nyní se nám do proměnné bude ukládat aktuální počet průchodu cyklem. Využítí proměnné ale tkví v něčem jiném. My za její pomoci určíme, na kterém pixelu osy X se v daný okamžik bude vykreslovat křivka zobrazující hodnotu zvuku. Vykreslování bude probíhat zleva doprava. Vložíme tedy proměnnou ještě před blok DisplayDragged Display, jak vidíte na obrázku a její výstupní konektor připojíme na vstupní konektory x a End point x. Tímto jsme nyní určili bod, ze kterého se křivka bude vykreslovat.

 

snimani a vypis

 

Krok 3 - Zajištění přehlednosti výpisu

Program ovšem ještě není hotový. Nyní by se graf vykresloval tak rychle, že bychom hodnoty na displeji těžko postřehli. Musíme jejich vykreslování ještě nastavit tak, aby se daly hodnoty na displeji přehledně sledovat. K této činnosti použijeme blok TimerDragged Timer. Jak název napovídá, jedná se o čítač, kterým můžeme ovlivnit dobu provádění některých příkazů. Nejprve je nutné čítač vynulovat. Vložíme tedy tento blok ještě před snímání senzorem a v sekci Action zvolíme Reset, tedy nulování. Nyní musíme zařídit zmíněné zpomalení vykreslování. Použijeme blok cyklu c010 loop large Loop a v sekci, ve které se volí možnost jeho řízení zvolíme Sensor, tedy řízení senzorem. V nabídce senzorů poté vybereme Timer. Narozdíl od předchozího použití, kdy jsme časovač nulovali, nyní budeme hodnoty číst. Vybereme proto možnost Read. Cyklus následně bude prováděn po dobu 0,02 sekundy. Po vyzkoušení jsme zvolili tuto hodnotu, protože pro potřeby plynulého vykreslování byla ideální. V sekci Until tedy nastavíme, že provádění cyklu bude trvat, dokud hodnota nebude větší než 0,02 (> 0,02). V těle cyklu se žádný příkaz provádět nebude. Pouze se jeho prováděním oddálí provedení dalšího příkazu a tedy nové vykreslování průběhu křivky. Umístění bloků časovače můžete vidět na obrázku.

Před cyklus provádějící vykreslování jsme ještě vložili blok  DisplayDragged Display, který zde slouží ke smazání displeje před dalším vykreslením. Celý cyklus i s tímto blokem poté umístíme do nekonečného cyklu, aby se program prováděl neustále.

 

Výsledný program
vykreslovani citac 80
 
Program ke stažení

Stažení ve formátu .rbt

RobotC

Zobrazení textu a hodnot

V teoretické části jsme si vysvětlili, pomocí jakých příkazů můžeme zobrazovat text nebo číselné hodnoty na displeji. Nyní si vše vysvětlíme na praktickém příkladu, ve kterém využijeme příkazy nxtDisplayCenteredTextLine() a nxtDisplayCenteredBigTextLine(). Program, na kterém budeme demonstrovat výpis textu a hodnot bude mít za úkol zobrazovat na displej vzdálenost od překážky zjištěnou ultrazvukovým senzorem.

Krok 1 - Deklarace senzoru a proměnných

Na začátku programu, ve kterém budeme používat ultrazvukový senzor, je nutné jej nadeklarovat. Deklarace se provádí automaticky v sekci menu Robot > Motors and Sensors Setup (podrobný popis v kapitole Ultrazvukový senzor).

Jelikož budeme pomocí ultrazvukového senzoru neustále snímat hodnotu vzdálenosti od překážky, bude potřeba si ji průběžně někam ukládat. Pro tento účel slouží v programování proměnné. Nadeklarujeme si tedy proměnnou vzdalenost do které přiřadíme počátečního hodnotu 0, protože po spuštění programu chceme, aby vstupní hodnota byla nulová.

 
int vzdalenost = 0;
 
 
Krok 2 - Snímání hodnot senzorem a výpis na displej

Druhým krokem je samotná realizace snímání a výpisu na displej. Jelikož potřebujeme, aby snímání probíhalo neustále, musíme všechny příkazy umisťovat do nekonečného cyklu while(). Hodnotu zjištěnou senzorem chceme ukládat do proměnné vzdalenost. Musíme je do ní tedy uložit pomocí příkazu SensorValue(), jehož parametrem bude název senzoru. Pro výpis textu na displej jsme zvolili příkazy nxtDisplayCenteredTextLine(), pomocí kterého se vypisuje popisek a nxtDisplayCenteredBigTextLine(), který průběžně vypisuje na 2. řádek displeje snímanou hodnotu. Na konec je nutné přidat příkaz wait1Msec(). Jako jeho parametr jsme zvolili 100 milisekund. Toto oddálení provádění dalšího příkazu zajistí konzistentní provádění výpisu na displej.

 
Výsledný program
 
// deklarace ultrazvukoveho senzoru
#pragma config(Sensor, S1, ultrazvuk, sensorI2CHiTechnicAccel)
 
task main()
{
 // pocatecni inicializace promenne
 int vzdalenost = 0;
 
 // nekonecny cyklus zarucujici neustaly vypis snimane hodnoty na displej
 while(true)
 {
   vzdalenost = SensorValue(ultrazvuk);
   nxtDisplayCenteredTextLine(0, "Zjistena vzdalenost");
   nxtDisplayCenteredBigTextLine(2, "%d", vzdalenost);
   wait1Msec(100);
 }
}
 
 

Program ke stažení

Stažení ve formátu .c


Zobrazení obrázků

Vykreslování obrázků na displeji řídící kostky je poněkud specifickou možností a je pouze na uživateli, jakým způsobem obrázky ve formátu .ric ve svém programu využije. V našem příkladu využijeme dva různé obrázky pro rozlišení hodnot zjištěných senzorem.

Následující program zjišťuje pomocí světelného senzoru intenzitu světla v okolí. Pokud je naměřená hodnota vyšší než 60, zobrazí se na displeji text "Tma" a zamračený smajlík. V případě, že zjištěná hodnota bude nižší než 45, objeví se na displeji text "Svetlo" a rozesmátý smajlík.

Krok 1 - Deklarace senzoru a proměnných

Na úvod každého programu, ve kterém používáme senzory, musíme provést jejich deklaraci. Podrobný popis deklarace světelného senzoru naleznete v kapitole Světelný senzor

Hodnotu snímanou senzorem potřebujeme v průběhu chodu programu ukládat, abychom jí mohli v dalších částech používat. K tomuto úkonu slouží v programování proměnné. Nadeklarujeme si tedy proměnnou uroven_svetla, do které se bude hodnota průběžně ukládat a provedeme její úvodní inicializaci tím, že do ní přiřadíme hodnotu 0.

 
int uroven_svetla = 0;
 
 
Krok 2 - Neustálé snímání hodnot senzorem

Následně musíme zajistit samotné ukládání hodnoty zjištěné senzorem do proměnné uroven_svetla. Přiřadíme proto tuto hodnotu do proměnné pomocí příkazu SensorValue(), jehož parametrem v závorce je název senzoru. Aby se měření hodnot senzorem a jejich zapisování do proměnné provádělo neustále, musíme příkaz umístit do nekonečného cyklu while().

 
while(true)
 {
 // prirazeni hodnoty snimane senzorem do promenne
 uroven_svetla = SensorValue(svetelny);
}
 
 
Krok 3 - Vykreslení obrázků

Posledním krokem při vytváření programu bude zobrazení obrázků při rozličných hodnotách zjištěných senzorem. Nejprve budeme chtít, aby se při naměření hodnot nižších než 45 zobrazilo na displeji slovo "Svetlo" a usmívající se smajlík. Použijeme tedy podmínku if(), jejímž parametrem bude výraz uroven_svetla < 45. Při jejím splnění tedy chceme, aby se vypsalo slovo "Svetlo", pro což použijeme příkaz nxtDisplayCenteredTextLine() a zobrazil se obrázek s názvem faceOpen.ric. Zobrazení obrázků se provádí příkazem nxtDisplayRICFile(). Před samotným vypisováním je dobré smazat celý dislej příkazem eraseDisplay(). Na závěr přidáme příkaz wait1Msec(), který oddálí o malý časový úsek provádění dalšího příkazu a zajistí tak konzistentnost vykreslování. Jako jeho parametr jsme zvolili 50 milisekund.

Stejným způsobem zrealizujeme i druhou možnost. Pouze požadujeme, aby se při hodnotách vyšších než 60 vypsalo slovo "Tma" a zobrazil zamračeným smajlík. Parametr podmínky tedy bude uroven_svetla > 60. Výpis obrázku a textu se provede použitím stejných příkazů.

 
Výsledný program
 
// deklarace svetelneho senzoru
#pragma config(Sensor, S1, svetelny, sensorLightActive)
 
 
task main()
{
 // pocatecni inicializace promenne
 int uroven_svetla = 0;
 
// nekonecny cyklus zarucujici neustale snimani hodnoty pomoci senzoru 
while(true)
 {
 // prirazeni hodnoty snimane senzorem do promenne
 uroven_svetla = SensorValue(svetelny);
 
 // podminka, pri jejimz splneni se na displeji zobrazi text "Svetlo" a rozesmaty smajlik
 if (uroven_svetla < 45)
 {
 eraseDisplay();
 nxtDisplayCenteredTextLine(0, "Svetlo");
 nxtDisplayRICFile(25, 5, "faceOpen.ric");
 wait1Msec(50);
 }
 
 // podminka, pri jejimz splneni se na displeji zobrazi text "Tma" a zamraceny smajlik
 if (uroven_svetla > 60)
 {
 eraseDisplay();
 nxtDisplayCenteredTextLine(0, "Tma");
 nxtDisplayRICFile(25, 5, "faceclosed.ric");
 }
 }
}
 

 

Program ke stažení

Stažení ve formátu .c


Vykreslení grafu

Na trochu náročnějším programu si ukážeme, jak je možné vykreslovat v programovacím prostředí RobotC na displej graf zaznamenávající úroveň hluku zjištěnou zvukovým senzorem.

Krok 1 - Deklarace proměnných

Při vytvářením programu si budeme muset nadeklarovat proměnné pro ukládání hodnot, se kterými budeme pracovat. První z nich bude proměnná zvuk, do které se bude ukládat hodnota intenzity hluku ze senzoru. Do proměnné se bude ukládat číselná hodnota, bude proto datového typu integer. Druhou proměnnou bude proměnná x. Zde se bude ukládat číslo pixelu na vodorovné ose x. Tato proměnná bude určovat, na kterém bodu displeje se bude vykreslovat vertikální křivka, která bude vyjadřovat intenzitu zvuku. Stejně jako první proměnná bude i tato datového typu integer.

 
 int x;
 int zvuk;
 
 
Krok 2 - Vykreslování hodnot zjištěných senzorem na displej

Vykreslování grafu na displej bude probíhat neustále. Jako první tedy použijeme nekonečný cyklus while(), do jehož těla budeme další příkazy zapisovat. Při každém překreslování dipleje potřebujeme, aby se původně vykreslená data smazala. Nejprve tedy do cyklu vložíme příkaz eraseDisplay(), který displej smaže. Než začneme dále používat proměnné, které jsme si popsali v předchozím kroku, musíme je inicializovat. Zapíšeme tedy jejich deklaraci a přiřadíme jim hodnotu 0.

Nyní již přistupujeme k samotnému vykreslování. To bude prováděno postupně pixel po pixelu zleva doprava. Křivka bude vykreslována od prvního pixelu horizontální osy x. Pixelů v tomto směru je 100. Bude tedy postupováno od 0 do 100. Použijeme proto cyklus s podmínkou na začátku while(). Podmínkou tedy bude, že vykreslování bude prováděno dokud hodnota proměnné x nebude rovna 100. Nyní si popíšeme, co se musí v těle cyklu provádět. Při každém průchodu bude hodnota proměnné x zvýšena o 1 (x++;). Následně začneme zpracovávat hodnotu ze senzoru. Nejdříve ji přiřadíme do proměnné zvuk pomocí příkazu SensorValue(). Aby se tako hodnota dala zpracovávat a nebyla příliš vysoká, vydělíme ji dvěma. Dalším příkazem budeme vykreslovat křivku, která bude vyjadřovat hodnotu zvuku. Použijeme příkaz nxtDrawLine(), který se používá pro vykreslování křivek spojujících dva body na displeji. Aby vykreslování probíhalo konzistentně a nebylo přiliš rychlé, a tím pádem i nepřehledné, přidáme na konec cyklu příkaz wait1Msec(). Jako hodnotu příkazu jsme zvolili 20 milisekund. Díky tomu se na krátký časový úsek oddálí provádění dalšího příkazu. 

 
while (true)
{
 eraseDisplay();
 
 int x = 0;
 int zvuk = 0;
 
 while (x<=100)
 {
 x++;
 zvuk = SensorValue(zvukovy) / 2;
 nxtDrawLine(x,zvuk,x,0);
 wait1Msec(20);
 }
}
 

 

Výsledný program

Hotový program pro zjišťování hluku v okolí pomocí zvukového senzoru a následné vykreslování na displej bude vypadat následovně:

 
// deklarace zvukoveho senzoru
#pragma config(Sensor, S1, zvukovy, sensorSoundDB)
 
task main()
{
 
// cyklus provadejici neustale vykreslovani grafu na displej
while (true)
{
 eraseDisplay();
 
 int x = 0;
 int zvuk = 0;
 
 while (x<=100)
 {
 x++;
 zvuk = SensorValue(zvukovy) / 2;
 nxtDrawLine(x,zvuk,x,0);
 wait1Msec(20);
 }
}
}
 

 

Program ke stažení

Stažení ve formátu .c

1 1 1 1 1 1 1 1 1 1 Hodnocení 5.00 (1 hodnocení)

Nemáte oprávnění přidat komentář.
Komentáře mohou přidávat pouze registrovaní uživatelé, kteří neporušují pravidla diskuze.