Meranie reakčnej doby: Rozdiel medzi revíziami
Z SensorWiki
(11 medziľahlých úprav od rovnakého používateľa nie je zobrazených.) | |||
Riadok 1: | Riadok 1: | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
{| | {| | ||
|Autori: || '''Miroslav Šimončič, Roman Godál''' | |Autori: || '''Miroslav Šimončič, Roman Godál''' | ||
|- | |- | ||
− | |Študijný odbor: || Aplikovaná mechatronika || 2. Ing. (''' | + | |Študijný odbor: || Aplikovaná mechatronika || 2. Ing. ('''2013''') |
|} | |} | ||
Riadok 16: | Riadok 10: | ||
Naprogramujte zariadenie na meranie reakčnej doby pozostávajúce z trojfarebnej LED diódy a displeja. V kľudovom stave svieti LED dióda na modro. Začatie merania tlačidlom S1 prepne LED na červenú, ktorá sa potom v '''náhodnom''' čase 1 - 7 sekúnd prepne na zelenú. Užívateľ má stlačiť tlačidlo S1 čo najskôr po prepnutí svetla. Po stlačení sa LED znova prepne na modrú a na displeji sa zobrazí čas, ktorý uplynul od prepnutia červená/zelená po stlačenie tlačidla. Na displeji bude okrem toho zobrazený priemer z posledných 5 meraní, najlepšia hodnota a počet meraní 1-5. | Naprogramujte zariadenie na meranie reakčnej doby pozostávajúce z trojfarebnej LED diódy a displeja. V kľudovom stave svieti LED dióda na modro. Začatie merania tlačidlom S1 prepne LED na červenú, ktorá sa potom v '''náhodnom''' čase 1 - 7 sekúnd prepne na zelenú. Užívateľ má stlačiť tlačidlo S1 čo najskôr po prepnutí svetla. Po stlačení sa LED znova prepne na modrú a na displeji sa zobrazí čas, ktorý uplynul od prepnutia červená/zelená po stlačenie tlačidla. Na displeji bude okrem toho zobrazený priemer z posledných 5 meraní, najlepšia hodnota a počet meraní 1-5. | ||
− | |||
− | [[Obrázok: | + | |
+ | [[Obrázok:ard.jpg|400px|thumb|center|Vývojová doska ACROB.]] | ||
'''Literatúra:''' | '''Literatúra:''' | ||
− | * [http:// | + | * [http://ap.urpi.fei.stuba.sk/sensorwiki/index.php/Acrob_technical_description Dokumentácia k doske Acrob] |
* [http://www.humanbenchmark.com/tests/reactiontime/index.php Vyskúšajte si zmerať reakciu on-line] | * [http://www.humanbenchmark.com/tests/reactiontime/index.php Vyskúšajte si zmerať reakciu on-line] | ||
Riadok 32: | Riadok 26: | ||
V našom projekte sme použili procesor AVR 328P, trojfarebnú LED diódu a displej Paralax 8x2 s tlačítkami. Základným postupom bolo dosiahnuť aby tieto zariadenia medzi sebou spolupracovali a boli ovládané mikroprocesorom. | V našom projekte sme použili procesor AVR 328P, trojfarebnú LED diódu a displej Paralax 8x2 s tlačítkami. Základným postupom bolo dosiahnuť aby tieto zariadenia medzi sebou spolupracovali a boli ovládané mikroprocesorom. | ||
− | [[Súbor:ledRGB.jpg|400px|thumb|center|RGB LED.]]] | + | [[Súbor:ledRGB.jpg|400px|thumb|center|RGB LED.]] |
+ | |||
+ | [[Súbor:d.png|400px|thumb|center|Displej.]] | ||
− | [[Súbor: | + | [[Súbor:doska.jpg|400px|thumb|center|Vývojová doska s procesorom AVR 328P.]] |
== Popis riešenia == | == Popis riešenia == | ||
− | + | RGB LED diódu sme zapojili na PORT C procesora. V LED dióde sú umiestnené 4 čipy. Na našu aplikáciu sme využili tri, každá nožička bola zapojená na inom pine procesora. Displej Paralax sa pripája na PORT D procesora. Pre jeho správne fungovanie sme museli zakázať UART komunikáciu, ktorá nám spôsobovala to, že sa nám na displej počas jej prevádzky nič nevypísalo. | |
− | |||
− | + | Pomocou tlačítka pod displejom ovládame našu aplikáciu. V kľudovom stave je na displeji zobrazené IDLE (svieti modrá dióda), po stlačení tlačítka sa na displeji zobrazí READY a rozsvieti sa červená dióda. V tom momente sa spustí náhodne dlhý časový úsek až pokiaľ sa na displeji nezobrazí výzva STLAC a rozsvieti sa zelená dióda. Od rozsvietenia zelenej diódy a zobrazenie výzvy STLAC sa spustí časovač, ktorý počíta dobu pokiaľ nestlačíme tlačítko. Po stlačení tlačítka sa na displeji zobrazí číslo konkrétneho merania a čas reflexu v milisekundách. Tento postup sa opakuje 5 meraní. Po piatich meraniach sa na displeji v prvom riadku zobrazí AVG, čo znamená priemer z časov piatich meraní. V druhom riadku sa zobrazí najlepší čas z posledných piatich meraní. | |
− | |||
− | |||
− | + | [[Súbor:sch.png|400px|thumb|center|Schéma zapojenia dosky Arduino.]] | |
− | |||
+ | [[Súbor:schd.png|400px|thumb|center|Schéma zapojenia LCD displeja.]] | ||
+ | '''Video:''' | ||
+ | * [https://www.youtube.com/watch?v=_l02MBu41n0&feature=youtu.be Reflex ] | ||
=== Algoritmus a program === | === Algoritmus a program === | ||
− | + | Algoritmus nášho programu sa začína ako každý program jazyku C vložením knižníc a hlavičkových súborov obsahujúcich potrebné inštrukcie a funkcie. Následne sme si zadefinovali funkcie na spúšťanie a zastavovanie časovača, a makro na spracovanie bitov pre nastavenie časovača. | |
− | + | Hlavná funkcia programu úvodom povolí prerušenie od použitého časovača a tak isto aj sériovú komunikáciu kvôli kolidovaniu použitých bitov procesora. Nasleduje inicializácia displeja s prvotným výpisom na displej a rozvietením príslušnej led. Ďalším krokom je nekonečný cyklus zabezpečujúci merania reakčného času. V cykle while sa nachádzajú podmienky stanovené na z čítacej funkcie tlačidiel, testovania príslušnej led a pomocných premenných na štruktúrovanie programu. | |
− | + | Pri splnení prvej podmienky program rozsvieti príslušnú led aj s výpisom na displej, vygeneruje náhodnú hodnotu slúžiacu na oneskorenie, počas ktorého musí užívateľ čakať na výzvu k stlačeniu, po uplynutí tohto náhodného čašu sa led prepnú do príslušného stavu ako aj príkaz na displeji a spusti sa meranie čašu. Program Čaka na splnenie ďalšej podmienky od užívateľa stlačením tlačidla, ktorou sa zastaví meranie a vyhodnotí sa čas aj s výpisom na displej, tento postup sa opakuje 5 krát, čo následne splní podmienku ukončenia meraní a vykoná výpočet priemernej hodnoty ako aj že nájde minimum z pola meraní. Tieto hodnoty sú následne vypísane na displej. | |
+ | |||
+ | <source lang="c"> | ||
+ | #include <avr/io.h> | ||
+ | #include <avr/delay.h> | ||
+ | #include <string.h> | ||
+ | #include "LCDlibrary.h" | ||
+ | #include <stdlib.h> | ||
+ | #include <avr/io.h> | ||
+ | #include "lcd.h" | ||
+ | #include <avr/interrupt.h> | ||
+ | #define UART_DISABLE() bits_clear(UCSR0B,bit(RXEN0)|bit(TXEN0)) | ||
+ | #define F_CPU 16000000UL | ||
− | + | //Manipulacia s bitmi | |
+ | #define bit_set(p,m) ((p) |= bit(m)) | ||
− | < | + | //funkcia na spustenie a zastavenie casovaca |
− | / | + | #define TIMER_STOP() bits_clear(TCCR0B,(bit(CS02)|bit(CS01)|bit(CS00)));TCNT0=0 |
+ | #define TIMER_START() TCNT0+=5;bits_set(TCCR0B,(bit(CS01)|bit(CS00))) | ||
+ | |||
+ | int nah=0,i,meranie=0,cas=0,x=0, mer[4], avg=0, best=10000, ok=0,buffer=0; | ||
+ | unsigned char u[10]; | ||
+ | |||
+ | int main(void) | ||
+ | { | ||
+ | |||
+ | bit_set(TIMSK0,TOIE0); //Povolenie prerusenia Casovaca 0 | ||
+ | sei(); | ||
+ | UART_DISABLE(); //zakazanie seriovej kom.,kvoli vyuzitiu bitu | ||
+ | lcd_init(); //inicializacna funkcia displeja | ||
+ | lcd_clrscr(); //funkcia na zmazanie obsahu displeja | ||
+ | lcd_puts_addr(0,"Idle"); //vypis na konkretnu adresu displeja | ||
+ | _delay_ms(500); | ||
+ | |||
+ | DDRC = 0x0E; //nastavenie bitov portu C ako vystup | ||
+ | PORTC = 0x02; //rozvietenie modrej led | ||
+ | |||
+ | // nekonecny cyklus zabezpecujuci meranie | ||
+ | while(1) { | ||
+ | |||
+ | //podmienka ktora sa vykona po stlaceni tlacidla z prislusneho stavu a spusti meranie | ||
+ | if ( (ReadButtons() == 4) && PORTC == 0x02 && meranie<5 && ok==0) | ||
+ | { | ||
+ | PORTC = 0x08; //rozsvietenie cervenej led | ||
+ | lcd_puts_addr(0,"ready"); | ||
+ | _delay_ms(500); | ||
+ | nah=rand() % 60001; //vygenerovanie nahodneho cisla v rozsahu do 60000 | ||
+ | nah=nah/1000; //uprava vygenerovaneho cisla pre cyklus for | ||
+ | for(i=10+nah;i<=70;i=i+1){ //nahodne trvajuci oneskorovaci cyklus | ||
+ | _delay_ms(750); | ||
+ | } | ||
+ | PORTC = 0x04; //rozvietenie zelenej led | ||
+ | meranie+=1; //zapocitanie merania | ||
+ | lcd_puts_addr(0,"stlac"); | ||
+ | cas=0; //vynulovanie pocitadla casu | ||
+ | TIMER_START(); //spustenie casovaca | ||
+ | } | ||
+ | |||
+ | //podmienka zabezpecujuca ukoncenie merania po stlaceni tlacidla v meracom rezime | ||
+ | if ((ReadButtons() == 4 && PORTC == 0x04 && meranie<6 && ok==0)){ | ||
+ | |||
+ | TIMER_STOP(); //zastavenie casovaca | ||
+ | mer[(meranie-1)]=cas; //ulozenie merania do pola merani | ||
+ | lcd_clrscr(); //premazanie displeja | ||
+ | sprintf(u,"%d: %d",meranie,mer[(meranie-1)]); //vytvorenie retazca pre vypis | ||
+ | lcd_puts_addr(0,u); //vypis retazca na displej | ||
+ | } | ||
+ | |||
+ | //podmienka zabezpecujuca opakovanie merani v urcitom pocte | ||
+ | if ((ReadButtons() == 8 && PORTC == 0x04 && meranie<6 && ok==0)){ | ||
+ | |||
+ | PORTC = 0x02; | ||
+ | lcd_clrscr(); | ||
+ | lcd_puts_addr(0,"Idle"); | ||
+ | if ( meranie==5) { // osetrenie poctu merani | ||
+ | ok=1;} | ||
+ | } | ||
+ | |||
+ | //podmienka vykonavajuca sa po ukonceni vsetkych 5 merani | ||
+ | if (meranie==5 && ok==1 && buffer==0){ | ||
+ | |||
+ | avg= (mer[0] + mer[1] + mer[2] + mer[3] + mer[4])/5; //vypocet priemeru | ||
+ | |||
+ | //cyklus na najdenie najmensej hodnoty v poli | ||
+ | for(i=0;i<4;i++){ | ||
+ | if (mer[i]<best) { | ||
+ | best=mer[i]; } | ||
+ | } | ||
+ | |||
+ | lcd_clrscr(); | ||
+ | sprintf(u,"MIN:%d",best); //vypis najlepsieho casu do retazca | ||
+ | lcd_puts_addr(0x40,u); | ||
+ | _delay_ms(500); | ||
+ | sprintf(u,"AVG:%d",avg); //vypis primerneho casu do retazca | ||
+ | lcd_puts_addr(0,u); | ||
+ | buffer=1; | ||
+ | } | ||
+ | } | ||
+ | return(0); | ||
+ | } | ||
− | + | //funkcia urcena na obsulu prerusenia od casovaca | |
− | + | ISR(TIMER0_OVF_vect) | |
− | + | { | |
− | + | TCNT0+=5; //spresnenie hodnoty inkrementom registra | |
+ | cas++; //pocitadlo ms | ||
} | } | ||
</source> | </source> | ||
− | |||
− | |||
− | [[Médiá: | + | Zdrojový kód: [[Médiá:lcd.h|serial.h]] a [[Médiá:lcd.c|main.c]] |
+ | |||
+ | [[Médiá:Reflex.c|reflex.c]] | ||
=== Overenie === | === Overenie === | ||
− | + | Na používanie našej aplikácie stačia dve tlačítka a postup používania je opísaný v sekcii popis riešenia. | |
− | + | Na konci uvádzame fotku záverečnej obrazovky pred resetom. Vypísaný je tu priemerný čas a najlepší čas. | |
− | |||
− | |||
− | + | [[Súbor:fot.png|400px|thumb|center|Aplikácia.]] | |
[[Category:AVR]] [[Category:DVPS]] | [[Category:AVR]] [[Category:DVPS]] |
Aktuálna revízia z 18:22, 10. január 2014
Autori: | Miroslav Šimončič, Roman Godál | |
Študijný odbor: | Aplikovaná mechatronika | 2. Ing. (2013) |
Zadanie
Naprogramujte zariadenie na meranie reakčnej doby pozostávajúce z trojfarebnej LED diódy a displeja. V kľudovom stave svieti LED dióda na modro. Začatie merania tlačidlom S1 prepne LED na červenú, ktorá sa potom v náhodnom čase 1 - 7 sekúnd prepne na zelenú. Užívateľ má stlačiť tlačidlo S1 čo najskôr po prepnutí svetla. Po stlačení sa LED znova prepne na modrú a na displeji sa zobrazí čas, ktorý uplynul od prepnutia červená/zelená po stlačenie tlačidla. Na displeji bude okrem toho zobrazený priemer z posledných 5 meraní, najlepšia hodnota a počet meraní 1-5.
Literatúra:
Analýza
V našom projekte sme použili procesor AVR 328P, trojfarebnú LED diódu a displej Paralax 8x2 s tlačítkami. Základným postupom bolo dosiahnuť aby tieto zariadenia medzi sebou spolupracovali a boli ovládané mikroprocesorom.
Popis riešenia
RGB LED diódu sme zapojili na PORT C procesora. V LED dióde sú umiestnené 4 čipy. Na našu aplikáciu sme využili tri, každá nožička bola zapojená na inom pine procesora. Displej Paralax sa pripája na PORT D procesora. Pre jeho správne fungovanie sme museli zakázať UART komunikáciu, ktorá nám spôsobovala to, že sa nám na displej počas jej prevádzky nič nevypísalo.
Pomocou tlačítka pod displejom ovládame našu aplikáciu. V kľudovom stave je na displeji zobrazené IDLE (svieti modrá dióda), po stlačení tlačítka sa na displeji zobrazí READY a rozsvieti sa červená dióda. V tom momente sa spustí náhodne dlhý časový úsek až pokiaľ sa na displeji nezobrazí výzva STLAC a rozsvieti sa zelená dióda. Od rozsvietenia zelenej diódy a zobrazenie výzvy STLAC sa spustí časovač, ktorý počíta dobu pokiaľ nestlačíme tlačítko. Po stlačení tlačítka sa na displeji zobrazí číslo konkrétneho merania a čas reflexu v milisekundách. Tento postup sa opakuje 5 meraní. Po piatich meraniach sa na displeji v prvom riadku zobrazí AVG, čo znamená priemer z časov piatich meraní. V druhom riadku sa zobrazí najlepší čas z posledných piatich meraní.
Video:
Algoritmus a program
Algoritmus nášho programu sa začína ako každý program jazyku C vložením knižníc a hlavičkových súborov obsahujúcich potrebné inštrukcie a funkcie. Následne sme si zadefinovali funkcie na spúšťanie a zastavovanie časovača, a makro na spracovanie bitov pre nastavenie časovača. Hlavná funkcia programu úvodom povolí prerušenie od použitého časovača a tak isto aj sériovú komunikáciu kvôli kolidovaniu použitých bitov procesora. Nasleduje inicializácia displeja s prvotným výpisom na displej a rozvietením príslušnej led. Ďalším krokom je nekonečný cyklus zabezpečujúci merania reakčného času. V cykle while sa nachádzajú podmienky stanovené na z čítacej funkcie tlačidiel, testovania príslušnej led a pomocných premenných na štruktúrovanie programu. Pri splnení prvej podmienky program rozsvieti príslušnú led aj s výpisom na displej, vygeneruje náhodnú hodnotu slúžiacu na oneskorenie, počas ktorého musí užívateľ čakať na výzvu k stlačeniu, po uplynutí tohto náhodného čašu sa led prepnú do príslušného stavu ako aj príkaz na displeji a spusti sa meranie čašu. Program Čaka na splnenie ďalšej podmienky od užívateľa stlačením tlačidla, ktorou sa zastaví meranie a vyhodnotí sa čas aj s výpisom na displej, tento postup sa opakuje 5 krát, čo následne splní podmienku ukončenia meraní a vykoná výpočet priemernej hodnoty ako aj že nájde minimum z pola meraní. Tieto hodnoty sú následne vypísane na displej.
#include <avr/io.h>
#include <avr/delay.h>
#include <string.h>
#include "LCDlibrary.h"
#include <stdlib.h>
#include <avr/io.h>
#include "lcd.h"
#include <avr/interrupt.h>
#define UART_DISABLE() bits_clear(UCSR0B,bit(RXEN0)|bit(TXEN0))
#define F_CPU 16000000UL
//Manipulacia s bitmi
#define bit_set(p,m) ((p) |= bit(m))
//funkcia na spustenie a zastavenie casovaca
#define TIMER_STOP() bits_clear(TCCR0B,(bit(CS02)|bit(CS01)|bit(CS00)));TCNT0=0
#define TIMER_START() TCNT0+=5;bits_set(TCCR0B,(bit(CS01)|bit(CS00)))
int nah=0,i,meranie=0,cas=0,x=0, mer[4], avg=0, best=10000, ok=0,buffer=0;
unsigned char u[10];
int main(void)
{
bit_set(TIMSK0,TOIE0); //Povolenie prerusenia Casovaca 0
sei();
UART_DISABLE(); //zakazanie seriovej kom.,kvoli vyuzitiu bitu
lcd_init(); //inicializacna funkcia displeja
lcd_clrscr(); //funkcia na zmazanie obsahu displeja
lcd_puts_addr(0,"Idle"); //vypis na konkretnu adresu displeja
_delay_ms(500);
DDRC = 0x0E; //nastavenie bitov portu C ako vystup
PORTC = 0x02; //rozvietenie modrej led
// nekonecny cyklus zabezpecujuci meranie
while(1) {
//podmienka ktora sa vykona po stlaceni tlacidla z prislusneho stavu a spusti meranie
if ( (ReadButtons() == 4) && PORTC == 0x02 && meranie<5 && ok==0)
{
PORTC = 0x08; //rozsvietenie cervenej led
lcd_puts_addr(0,"ready");
_delay_ms(500);
nah=rand() % 60001; //vygenerovanie nahodneho cisla v rozsahu do 60000
nah=nah/1000; //uprava vygenerovaneho cisla pre cyklus for
for(i=10+nah;i<=70;i=i+1){ //nahodne trvajuci oneskorovaci cyklus
_delay_ms(750);
}
PORTC = 0x04; //rozvietenie zelenej led
meranie+=1; //zapocitanie merania
lcd_puts_addr(0,"stlac");
cas=0; //vynulovanie pocitadla casu
TIMER_START(); //spustenie casovaca
}
//podmienka zabezpecujuca ukoncenie merania po stlaceni tlacidla v meracom rezime
if ((ReadButtons() == 4 && PORTC == 0x04 && meranie<6 && ok==0)){
TIMER_STOP(); //zastavenie casovaca
mer[(meranie-1)]=cas; //ulozenie merania do pola merani
lcd_clrscr(); //premazanie displeja
sprintf(u,"%d: %d",meranie,mer[(meranie-1)]); //vytvorenie retazca pre vypis
lcd_puts_addr(0,u); //vypis retazca na displej
}
//podmienka zabezpecujuca opakovanie merani v urcitom pocte
if ((ReadButtons() == 8 && PORTC == 0x04 && meranie<6 && ok==0)){
PORTC = 0x02;
lcd_clrscr();
lcd_puts_addr(0,"Idle");
if ( meranie==5) { // osetrenie poctu merani
ok=1;}
}
//podmienka vykonavajuca sa po ukonceni vsetkych 5 merani
if (meranie==5 && ok==1 && buffer==0){
avg= (mer[0] + mer[1] + mer[2] + mer[3] + mer[4])/5; //vypocet priemeru
//cyklus na najdenie najmensej hodnoty v poli
for(i=0;i<4;i++){
if (mer[i]<best) {
best=mer[i]; }
}
lcd_clrscr();
sprintf(u,"MIN:%d",best); //vypis najlepsieho casu do retazca
lcd_puts_addr(0x40,u);
_delay_ms(500);
sprintf(u,"AVG:%d",avg); //vypis primerneho casu do retazca
lcd_puts_addr(0,u);
buffer=1;
}
}
return(0);
}
//funkcia urcena na obsulu prerusenia od casovaca
ISR(TIMER0_OVF_vect)
{
TCNT0+=5; //spresnenie hodnoty inkrementom registra
cas++; //pocitadlo ms
}
Zdrojový kód: serial.h a main.c
Overenie
Na používanie našej aplikácie stačia dve tlačítka a postup používania je opísaný v sekcii popis riešenia. Na konci uvádzame fotku záverečnej obrazovky pred resetom. Vypísaný je tu priemerný čas a najlepší čas.