Počítanie sekund

Úloha

Upravte program z predchádzajúceho cvičnia tak aby LED displej zobrazoval plynúce sekundy. Jednotlivé body si môžete pozrieť na nasledujúcom videu

Teória

  1. Výpočet dĺžky trvania funkcie loop().

    Ako prvé je potrebné vypočítať koľko trvá jeden beh funkcie loop(). Tento čas potom použijeme na počítanie uplynutého času. Spočítame koľko trvá volanie funkcií delay(???) a delayMicroseconds(???) Kedže Arduiono doska je taktovaná kryštálovým oscilátorom s frekvenciou 16MHz, môžeme predpokladať že ostatné príkazy sa vykonajú za čas jedna mikrosekunda.
    Celkový čas zaokrúhlime na celé milisekundy.

  2. Deklarácia premenných.

    Pre výpočet času budeme potrebovať dve premenné. Jedna bude slúžiť pre počítanie uplynutých milisekund, druhá pre počítanie uplynutých sekund. Pre úspešné vyriešenie tohoto problému je potrebné poznať typy premenných jazyka C char a int a modifikácie short, unsigned.
    Ďalej je potrebné rozumieť tomu čo je globálna premenná a čo je lokálna premenná. Je tiež vhodné porozmýšlať či sú premenné správne inicializované na počiatočné hodnoty.

  3. Generátor znakov

    Doteraz sme vždy keď sme potrebovali zobraziť nejakú kombináciu na LED tak sme poslali na PORTD nejakú konštantu. To teraz treba zmeniť tak že konštantu je potrebné zistiť podľa hodnoty číslice (0-9). Na toto sa najlepšie hodí vec ktorá sa v jazyku C volá pole (array). Nasledujúci fragment kódu ukazuje ako sa také pole deklaruje a následne je vytvorená funkcia ktorá vyberá z poľa príslušný znak podľa vstupnej hodnoty.
    Obecne je takéto veci treba riešiť pomocou funkcií. Neskôr uvidíme aké to má výhody.

    //vytvor pole ktore obsahuje obrazovu reprezentáciu jednotlivych cislic
    unsigned char generatorCislic[]={ZNAK_0,ZNAK_1,ZNAK_2,ZNAK_3,ZNAK_4,ZNAK_5,
                                     ZNAK_6,ZNAK_7,ZNAK_8,ZNAK_9}; 
    
    /**
      * Funkcia ktora pre cislo v rozsahu 0 az 9 vrati obrazovu 
      * reprezentaciu cislice na sedemsegmentovke
      * vstup cislo - cislo od 0 po 9
      * vystup 8bitova hodnota ktora zobrazi cislicu na sedemsegmentovke
      * ak vstupna hodnota bude viac ako 9 tak sa zobrazi prazdny znak
      */
    unsigned char dajCislicu(unsigned char cislo){
        if (cislo <= 9){
           return generatorCislic[cislo];
        }
        return ZNAK_TMA;
    }
    

  4. Výpočet času.

    Výpočet času zrealizujeme zatiaľ veľmi jednoducho. Na konci funkcie loop() pripočítame k premennej ktorá obsahuje počet milisekund dĺžku trvania funkcie loop(), ktorú sme zistili v prvom bode. Potom je potrebné skontroľovať či hodnota nepresiahla hodnotu 1000 (1000ms = 1 sekunda). V takomto prípade je potrebné premennú milisekund vynulovať a premmenú sekund zvýšiť o jednotku.
    Pre úspešné zvládnutie treba vedieť okrem príkazu na priradenie hodnoty do premennej aj to ako sa používa príkaz if

  5. Zobrazenie času

    Čas (zatiaľ iba sekundy) sa postupne mení a aktuálna hodnota sa vždy nachádza v premennej. Obsah premennej sa bude postupne zvyšovať. Podľa typu premenne sa hodnota môže postupne meniť od nuly až po maximum (127, 255, 32767, 65535, 2147483647, 4294967295) Aby sme vedeli z tohoto celého čísla vyseparovať jednotlivé číslice tak je potrebné ovládať dve matematické operácie. Prvá je pomerne bežná. Je to delenie. Pozor na to že v našom prípade pôjde o celočíselné delenie. To znamená že výsledok bude mať zahodné desatinné miesta. Číslo sa ani bude zaokrúhlovať. Teda napríklad 59 / 10 je 5.
    Druhá oprácia je pomerne exotická a bežne sa v stredoškolskej matematike moc nepoužíva. Je to operácia s názvom modulo. Alebo inak povedané zvyšok po delení. V jazyku C sa zapisuje pomocou znaku %. Ak teda napíšem predošlý výraz s týmto novým matematickým znamienkom 59 % 10 je 9. Funguje to tak že sa 59 vydelí číslom 10 a výsledkom je zvyšok po delení.
    Pomocou tejto finty sa bude dať císlo ktoré obsahuje kompletný počet sekund "rozbiť" na jednotlivé číslice.

Postup

  1. Načítajte si program z predošlého cvičenia. Uložte ho pod novým názvom pomocou File > Save As Program preložte a nahrajte do arduína. Overte či sa zobrazujú na displeji štyri číslice.
  2. Výpočet dĺžky trvania funkcie loop().

    Podľa návodu v teoretickom rozbore vypočítajte koľko trvá vykonanie funkcie looo(). Číslo zaokrúhlite na celé milisekundy.

  3. Deklarácia premenných.

    Deklarujte dve globálne premenné. Jedna pre počítanie uplynutých ms. Druhá pre počítanie uplynutých sekund. Vyskúšajte preložiť program (netreba nahrávať do arduína) aby ste si overili či prekladač pochopil čo po ňom chcete.

  4. Generátor znakov

    Skopírujte si kód z teórie do svojho programu. Opäť vyskúšajte preložiť program (netreba nahrávať do arduína) aby ste si overili či je program stále bez chyby.

  5. Výpočet času.

    Po každom kroku si overte či prekladač chápe čo mu chcete povedať. Robte to pomocou príkazu Project > Overenie/Kompilácia Program je zbytočné nahrávať do Arduina. Nakonci funkcie loop() vytvorte kód ktorý:

    1. pripočíta k milisekundám dobu trvania funkcie loop. (Bolo by pekné keby ste to urobili pomocou textovej konštanty)
    2. otestuje či je hodnota premennej viac ako 1000 (test či už uplynula sekunda)
    3. ak áno, tak zvýši hodnotu premennej sekund o jednotku
    4. od premennej s milisekundami odpočíta hodnotu 1000. (tento trik slúži na to aby sa nestrácali nejaké drobné milisekundy, ak hodnota nevyjde presne 1000.
    5. Teraz je čas overiť či sa sekundy počítajú správne. To sa docieli tak že miesto číslic sa na PORTD všade (štyri miesta) vloží hornota premennej sekund. Na Displeji to bude ukazovať hovadiny, ale príslušná osmica zelených diod by mala pekne po sekunde zobrazovať binárnu hodnotu. Pozri video

  6. Zobrazenie času

    Zase budeme postupovať po malých krokoch:

    1. Ako prvé upravte program aby na každom segmente displeja zobrazoval tmu. Úpravu vyskúšajte priamo na doske
    2. Pomocou operácie modulo vypočítajte poslednú číslicu ktorá by mala reprezentovať aktuálnu sekundu. Pomocou volania funkcie dajCislicu(???) požiadajte generátor znakov o príslušnú obrazovú reprezentáciu danej číslice a zobrazte ju na poslednom mieste displeja. Program nahrajte a v prípade úspešného zobrazovania číslic 0-9 na poslednom segmente zavolajte vyučujúceho na kontrolu a ocenenie. Pozri video
    3. Pomocou operácie deleno vypočítajte hodnotu, ktorá by mala reprezentovať aktuálne desiatky sekund. Rovnakým postupom ako v predošlom bode ju prevedte na obrazovú reprezentáciu a zobrazte ju na treťom segmente displeja. Program opäť nahrajte do arduina a úspešné riešenie ukážte vyučujúcemu. Pozri video

  7. Bonusové úlohy pre študentov ktorý to zvládli ľavou zadnou

    Súbor si vždy uložte pod novým názvom pomocou File > Save As napr pridajte slovo bonus a číslo úlohy

    1. Vymyslite ako zobrazovať stovky sekund. Vyskúšajte čo to urobí ak sa zmení typ premennej sekundy na signed char, unsigned char, short Pozri video
    2. Vymyslite ako zobrazovať seundy a desatiny sekund. Úplne perfekt by bolo ak by sa zobrazila aj desatinná bodka. Pozri video
    3. Vymyslite ako zobrazovať sekundy a desatiny a stotiny sekundy. Tiež pokliaľ možno aj s desatinnou bodkou. Pozri video
    4. Vymyslite program tak aby odpočítaval sekundy napríklad od hodnoty 600 až k hodnote 000. Na čo by sa to dalo využiť? Pozri video
    5. Upravte program tak aby zobrazoval sekundy v hexadecimálnej sústave. Aký maximálny počet sekund sa potom dá zobraziť na štvormiestnom displeji? Pozri video