Operácie

Meranie reakčnej doby

Zo stránky SensorWiki

Verzia z 17:59, 10. január 2014, ktorú vytvoril StudentDVPS (diskusia | príspevky)
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.

Vývojová doska ACROB.


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.

RGB LED.
Displej.
Vývojová doska s procesorom AVR 328P.


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í.


Schéma zapojenia dosky Arduino.
Schéma zapojenia LCD displeja.

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

program.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.

Aplikácia.