Arduino v praxi - užívateľské menu

Arduino v praxi - užívateľské menu
TME S.r.o. Pridal  TME S.r.o.
  212 zobrazení
1
 0
Arduino a príbuzné platformy

V predchádzajúcom článku sme vám predstavili základy používania nadstavby SHIELD-LCD16x2. V tejto časti sa budeme venovať príprave konkrétneho praktického riešenia, ktoré môže byť užitočné pri následných projektoch zariadení – na doske boli namontované komponenty, ktoré môžu byť použité na vytvorenie používateľského menu. Na začiatok pripravíme jednoúrovňové menu, t.j. menu, ktoré okamžite spustí funkciu bez rozšírenia podmenu.

Pripomeňme si, že SHIELD-LCD16x2 je druh nadstavby rozširujúcej možnosti Arduino, vybavenej LCD zobrazovacím modulom (2 riadky po 16 znakov), 4 tlačidlá a 8 ďalších GPIO liniek. Na doske je namontovaný mikrokontrolér PIC, ktorý komunikuje s Arduino UNO prostredníctvom rozhrania TWI. Dostupné knižnice funkcií uľahčujú ovládanie celého modulu, a to aj neskúsenými používateľmi. Začnime s popisom toho, ako funguje program z nášho príkladu.

Arduino v praxi – princíp fungovania vzorového menu

Navrhované riešenie sa skladá z niekoľkých univerzálnych funkcií, ktoré sa – podobne ako knižnice Arduino – ľahko prispôsobujú vašim potrebám. Hoci tento príklad používa hotovú nadstavbu SHIELD-LCD16x2, zmenou určitých definícií (budeme o nich hovoriť neskôr), budeme môcť nakonfigurovať funkciu menu na použitie so zobrazením znakov akéhokoľvek rozlíšenia, napr. 4 riadky s 20 znakmi, 1 riadok obsahujúci 16 znakov atď. Pri vykonávaní programu menu budeme musieť siahnuť po pokročilých prvkoch jazyka C, ako sú ukazovatele, štruktúry a polia. Začnime však opisom toho, ako menu funguje.

Príklad implementuje menu so 4 riadkami. Zobrazuje pomocou displeja 2 riadky so 16 znakmi a ovláda sa štyrmi tlačidlami. Predpokladáme, že:

  • Tlačidlá sa počítajú zľava a sú očíslované od 1 do 4.
  • Tlačidlo „1“ (prvé zľava) posúva znak označenia riadka menu riadka smerom nadol.
  • Tlačidlo „2“ posunie znak riadka menu nahor.
  • Tlačidlo „3“ je akoby vzdanie sa danej možnosti. „Akoby“, pretože ak nemáme do činenia s viacúrovňovým menu, v takom prípade ho nepoužijeme. Predpokladajme teda, že ide o tlačidlo, ktoré môže aplikácia voľne používať.
  • Tlačidlo „4“ (prvé z pravej strany) je potvrdením výberu – ekvivalent klávesu Enter na klávesnici počítača.

Na obrazovke LCD modulu sú 2 riadky po 16 znakov a menu z tohto príkladu má 4 riadky, takže nemôžeme zobraziť celé menu, ale musíme ho rozdeliť na 2-riadkové fragmenty. Predpokladáme, že po zapnutí napájania alebo reštartovaní mikrokontroléra sa na obrazovke zobrazia prvé a druhé riadky ponuky a označenie výberu sa zobrazí v prvom riadku. Po stlačení tlačidla „dole“ sa označenie výberu presunie na riadok ponuky číslo 2. Pri ďalšom stlačení tlačidla „dole“ označenie výberu zostane v riadku displeja číslo 2, ale za ním sa zobrazia riadky menu 2 a 3, takže označenie výberu zobrazí riadok menu číslo 3. Ďalším stlačením tlačidla „dole“ sa zobrazia riadky menu číslo 3 a 4 a označenie výberu zostane v riadku 2 displeja a zobrazí možnosť číslo 4. Ďalšie stlačenie tlačidla „dole“ spôsobí návrat do východiskovej polohy.

Podobne funguje tlačidlo „hore“, ale značka sa pohybuje opačným smerom. A ak stlačíte tlačidlo „hore“ na začiatku operácie programu, označenie výberu sa presunie na zobrazovaný riadok číslo 2 a na obrazovke sa zobrazia riadky ponuky 3 a 4. Stlačením tlačidla „hore“ sa označenie výberu presunie na riadok displeja 1 a na displeji sa stále zobrazia riadky menu 3 a 4. Ďalším stlačením tlačidla „hore“ zostane označenie výberu na prvom riadku displeja, ale na obrazovke sa zobrazia riadky ponuky 2 a 3. A tak ďalej.

Riadok displeja umožňuje zobraziť reťazec 16 znakov. 2 znaky sú obsadené symbolmi značiek („>“ a „<“), takže v našom menu môže mať nápis 14 znakov. Dĺžka menu (počet možností) je teoreticky ľubovoľná a v praxi obmedzená veľkosťou pamäte programu a kapacitou premenných.

Keď stlačíte tlačidlo č. 4, funkcia User_Menu vráti číslo vybratej možnosti alebo 0, ak nebol vykonaný žiadny výber alebo je nesprávny.

Arduino v praxi – definovanie položiek menu

Na začiatku vzorového programu nájdete množstvo definícií a premenných, ktoré vám umožnia definovať parametre displeja, na ktorom sa zobrazuje ponuka, a počet jeho možností a obsahu správ. Ako prvý uvedieme počet možností v menu. Ako už bolo spomenuté, ponuka v tomto príklade obsahuje 4 riadky, takže definícia menuoptions sa musí rovnať 4.

#define menuoptions 4

V ďalšej definícii musíte venovať pozornosť určitej vlastnosti jazyka C, na ktorej je založený kompilátor Arduino. V jazyku C definícia reťazca znakov (textu) vždy končí bajtom 0. Inštruuje kompilátor, že tu sa končí reťazec a že by ste mali napríklad ukončiť zobrazenie alebo inú operáciu v texte. Ak vytvoríme správu so 14 znakmi, definujeme ju ako char správu[14]. Niektoré kompilátory pridajú znak 0 na konci takejto definície, ukončia reťazec a niektoré nie, pričom definíciu budú považovať za reťazec čísel, nie ako textový zápis. Kompilátor Arduino nepridá znak 0, takže keď si rezervujete priestor pre string tejto dĺžky, musíte buď napísať vlastnú funkciu, ktorá zobrazuje určitý počet znakov bez toho, aby ste preskúmali, či reťazec končí bajtom 0, alebo pridať o jeden znak viac, ako správa potrebuje. Preto by sa hodnota menuitemlen mala vypočítať ako maximálny počet znakov na displeji mínus 1, a nie 2, ako by sa mohlo zdať, pretože 2 znaky sú obsadené znakmi „>“ a „<“, ktoré sa používajú na označenie aktuálneho riadka menu.

#define menuitemlen 15

Ďalšia definícia lcd_lines je triviálna – jednoducho uveďte počet riadkov displeja, na ktorom sa ponuka zobrazí. Pre displej v príklade vyzerá definícia takto:

#define lcd_lines 2

Ďalším prvkom je prvok menuitem obsahujúci parametre jedného riadka menu. Je to štruktúra s poľami:

  • menu_message – opis riadkov menu (upozorňujeme, že nemôže byť dlhšia ako 14 znakov).
  • whereisptr – konštanta určujúca hodnotu, podľa ktorej musíte presunúť bod do tabuľky s definíciou menu na zobrazenie dvoch riadkov údajov. Ako môžete ľahko vidieť, prvé dva riadky sa zmestia na obrazovku, takže s nimi má konštanta hodnotu 0 a potom pre každú nasledujúcu sa zväčší o 1. Ak by mal displej 4 riadky, potom by pri prvých 4 definíciách správy boli 0 a potom 1, 2, 3 atď.
  • y0 – informuje vás, v ktorom riadku je označenie výberu menu, keď sa na obrazovke zobrazí správa.

Viac o štruktúrach nájdete v literatúre o jazyku C. Tu sa zameriame len na praktické uplatnenie štruktúry. V iných jazykoch sa štruktúra často nazýva záznam alebo tuple.

Definovaný typ údajov sa použil na vytvorenie poľa v programovom konštantnom priestore (const), ktoré obsahuje úplnú definíciu menu. Táto tabuľka sa nazýva menu_lines a zahŕňa menuoptions prvkov, z ktorých každý je štruktúrou, ktorá viaže polia definície jedného riadka menu.

Tento príklad definuje veľmi všeobecné správy pre riadky menu. Prvý riadok teda zobrazuje fragment správy „First menu line”, druhý „Second menu line”, tretí „Third menu line”, a štvrtý „Fourth menu line”.

const menuitem menu_lines[menuoptions]=

{{"First menu lin", 0, 1},

{"Second menu li", 0, lcd_lines},

{"Third menu lin", 1, lcd_lines},

{"Fourth menu li", 2, lcd_lines}};

Budeme tiež potrebovať ukazovateľ pre jednotlivé štruktúry v menu, číslo aktuálnej položky v menu (miesto, kde sa zobrazujú označenia výberu), premennú s výberom používateľa a – ako v predchádzajúcom príklade – premennú s číslom tlačidla.

menuitem*menu_lines_ptr;

signed char menu_position;

char user_choice;

int pressed;

Ukazovateľ je veľmi užitočný typ premennej a veľmi uľahčuje programovanie. Ak, ako v príklade, ukazovateľ zobrazuje prvý prvok poľa a pridáme k nemu 1, potom bez zbytočného počítania bajtov a určenia veľkosti jeho prvku nám ukáže pozíciu číslo 2 v tomto poli.

Arduino v praxi – použitie menu

Po definovaní položiek menu ich môžeme vyvolať v našom programe. Po prvé, vo funkcii void setup() musíme uviesť počiatočnú hodnotu premennej určujúcej aktuálnu položku v menu, to znamená menu_position = 0; a zobraziť menu pomocou vyvolania funkcie Display_Menu().

Vo funkcii void loop() odčítame číslo stlačeného tlačidla pomocou vyvolania

pressed = Number_of_Button();

Ak používateľ stlačil tlačidlo s číslom iným ako 0, môžeme vyvolať funkciu User_Menu(pressed); pričom číslo tlačidla berieme ako parameter obsahujúci primeranú reakciu. A tak tlačidlo „1“ posúva označenia výberu nadol, „2“ – hore a „4“ – výber možností menu. Číslo vybratej možnosti vráti funkcia a môže byť prehodnotený napríklad pomocou switch…case alebo if. V príklade, na ilustráciu práce ponuky, sú vyvolané funkcie, ktoré menia jas podsvietenia pozadia displeja, ale samozrejme môžu to byť akékoľvek iné definované programátorom.

void loop()

{

pressed = Number_of_Button();

if (pressed > 0) user_choice = User_Menu(pressed);

switch (user_choice)

{

case 1:

//akcja 1break;

case 2:

//akcja 2break;

case 3:

//akcja 3break;

case 4://

akcja 4break;

}

}

Arduino – Ďalšie informácie o tvorbe menu

Ukazovateľ (pointer) je premenná, ktorá obsahuje adresu inej premennej. Použitie ukazovateľov vedie k efektívnejšiemu kódu, aký by bol získaný inými metódami. Bohužiaľ, ich nešikovné použitie môže prispieť k zhoršeniu čitateľnosti programu. Nastáva to najmä vtedy, keď sa používajú chaoticky, bez komentárov, označujúc premenné, ktoré nikto nevie, akého sú typu. Na druhej strane schopnosť priamo ukazovať na oblasti pamäte a vykonávať na nich akcie je jedným z najsilnejších mechanizmov jazyka C. Pozrime sa teraz na ďalší príklad:

char x = 1, y = 2, z[5];

char* ukazovateľ;

ukazovateľ =& x; //premenná ukazovateľ označuje x

y =*ukazovateľ; //teraz premenná y má hodnotu 1

*ukazovateľ = 0; //teraz má premenná x hodnotu 0

ukazovateľ = &z[0] //premenná ukazovateľ označí prvý prvok poľa s

Pri deklarovaní ukazovateľov sa používa symbol * (hviezdičky), ktorý je takzvaným operátorom nepriameho adresovania. Tento operátor jazyka C, ktorý sa používa pre ukazovateľ, určuje obsah definovaného objektu. V jazyku C existuje iná metóda priraďovania indikácií konkrétnej premennej. Jednoargumentový operátor & (symbol and) vráti adresu premennej (poznámka: môže sa použiť len na objekty, ktoré zaberajú pamäť premenných a polí). Syntax vyhlásenia ukazovateľa musí obsahovať sledovanie prvku, ku ktorému sa môže indikácia vyskytnúť.

Vďaka ukazovateľom môžete zjednodušiť a urýchliť prevádzku programu. Napríklad vývojári sú dobre oboznámení s potrebou preniesť parametre do funkcií. V mnohých programovacích jazykoch sa parametre odovzdávajú uvedením ich dlhého zoznamu. To zaberá však zaberá v RAM veľmi veľa miesta. Samozrejme, keď vytvoríme program pre PC, nie je to veľký problém, ale v mikrokontroléri táto pamäť často nie je veľmi rozsiahla. S premennými, ktoré máte k dispozícii a ktoré označujú zoznam parametrov vrátane dlhých polí, napr. obsahujúcich správy zobrazené programom alebo medzipamätami údajov, môžete jednoducho prejsť ukazovateľom na adresu v pamäti, kde sa táto premenná nachádza.

V jazyku C sa parametre vyvolania funkcie prenášajú prostredníctvom hodnoty. V dôsledku toho funkcia nemá prístup k argumentom patriacim do podprogramu, ktorý ju vyvoláva. Jediný spôsob, ako vykonať akcie na premenných z iného podprogramu, je preniesť ukazovatele na tieto premenné ako argumenty.

void Zamien (int*Tx, int *Ty)

{

int temp;

temp =*Tx;

*Tx = *Ty;

*Ty = temp;

}

void main(void){int A = 10, B = 20;Zamien(&A,&B); //výmena hodnôt premenných A a B}

V tomto príklade sa akcie vo vnútri funkcie vykonávajú priamo, na premenných hlavného programu, bez akýchkoľvek „sprostredkovateľov“, napr. umiestňovania premenných do zásobníka v pamäti atď.

Všetky operácie s ukazovateľmi sa automaticky prispôsobia veľkosti daných objektov. Pravidlá aritmetiky ukazovateľov sú veľmi jednoduché. Ak ukazovateľ T zobrazuje začiatok poľa prvkov typu int a sám je tiež typu *int, potom operácia T=T+1; (v opačnom prípade T++;) presunie indikáciu na ďalší prvok poľa. Číslo 1 sa nepridá na adresu indikácie, ale pridá sa 2, pretože premenná typu int má dĺžku 2 bajty.

Platné operácie ukazovateľa zahŕňajú: priradenie ukazovateľov k objektom rovnakého typu, pridanie a odobratie ukazovateľa a celého čísla, odobratie alebo porovnanie dvoch ukazovateľov s prvkami toho istého poľa a priradenie hodnoty 0 indikátoru alebo porovnanie ukazovateľa k 0. Všetky ostatné operácie na ukazovateľoch sú nesprávne. Nepridávajte dva ukazovatele (dokonca ani rovnakého typu) dohromady, nevynásobujte, nedeľte, nepresúvajte doprava ani doľava, neskladajte s maskami (operácie AND a OR) ani k nim nepridávajte čísla s pohyblivou desatinnou čiarkou. Okrem ukazovateľa typu *void – nie je možné ani priradiť ukazovateľ k objektu jedného typu bez transformácie (premietania) ukazovateľa na objekty iného typu.

V tomto príklade ukazovateľ zobrazuje tabuľku, ktoré obsahuje štruktúry (záznamy) údajov. Jednotlivé polia štruktúry majú svoje vlastné názvy a môže na ne byť priamo odkazované bez toho, aby museli špecifikovať posun pre daný prvok štruktúry. Ak chcete označiť pole s konkrétnym názvom, použite operátor šípky „->”. Napríklad

parametre typedef struct

{

int x;

int y;

int výška;

}

parametre*ukazovateľ;

ukazovateľ->x;   umožňuje odkaz na pole

xukazovateľ->výška;   umožňuje odkaz na pole výška

umožňuje odkaz na pole xukazovateľ->výška; umožňuje odkaz na pole výška

Ak vytvoríme tabuľku zo štruktúry parametrov, ukazovateľ sa zmení o počet bajtov, ktorý je veľkosťou jedného prvku tabuľky, označujúc jeho jednotlivé prvky bez toho, aby ste museli vypočítať počet bajtov.

parametre tabuľka_parametrov[10] //definícia tabuľky-zoznamu parametrov

parametre*ukazovateľ = &tablica_parametrów[0]; //teraz ukazovateľ ukazuje

//na začiatok tabuľky(

ukazovateľ+5)->x; //označí pole x piaty prvok tabuľky

//čo umožní získať alebo upraviť premennú;

Ukazovatele v jazyku C sú veľmi rozsiahlou témou. Ak máte záujem o rozšírenie svojich vedomostí a praktických aplikácií ukazovateľov, odporúčame vám prečítať si literatúru o jazyku C a množstvo tutoriálov dostupných na internete.

Stiahnuť materiály



Páčil sa Vám článok? Pridajte k nemu hodnotenie, alebo podporte jeho autora.
 

     

Komentáre k článku

Zatiaľ nebol pridaný žiadny komentár k článku. Pridáte prvý? Berte prosím na vedomie, že za obsah komentárov je zodpovedný užívateľ, nie prevádzkovateľ týchto stránok.
Pre komentovanie sa musíte prihlásiť.

Vyhľadajte niečo na našom blogu

Webwiki ButtonSeo servis