Meranie reakčnej doby
Zo stránky SensorWiki
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
}
Zdrojový kód: serial.h a main.c
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.