Meranie reakčnej doby: Rozdiel medzi revíziami
Zo stránky SensorWiki
Bez shrnutí editace |
Bez shrnutí editace |
||
Riadok 56: | Riadok 56: | ||
<source lang="c"> | <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 | |||
int main(void) { | //Manipulacia s bitmi | ||
#define bit_set(p,m) ((p) |= bit(m)) | |||
return(0); | //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> |
Verzia z 17:59, 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.
K zapojeniu treba vypracovať dokumentáciu, popis programu, schému zapojenia displeja a riadiacej jednotky. Ako bonus doplňte riadenie intenzity displeja na základe vonkajšieho osvetlenia.
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
Uveďte stručný popis algoritmu, v akom jazyku a verzii vývojového prostredia ste ho vytvorili. Je vhodné nakresliť aspoň hrubú štruktúru programu napríklad vo forme vývojového diagramu. Rozsiahly program pre lepšiu prehľadnosť rozdeľte do viacerých súborov.
Vyberte podstatné časti zdrojového kódu, použite na to prostredie source:
#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
}
Nezabudnite však nahrať aj kompletné zdrojové kódy vášho programu!
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.