Operácie

Kuchynské minutky: Rozdiel medzi revíziami

Z SensorWiki

(Vytvorená stránka „Záverečný projekt predmetu MIPS / LS2024 - '''Meno Priezvisko''' == Zadanie == Sem príde text zadania, ak bolo len voľne formulované, rozpíšte ho podrobnejši…“)
 
(Overenie)
(10 medziľahlých úprav od rovnakého používateľa nie je zobrazených.)
Riadok 1: Riadok 1:
Záverečný projekt predmetu MIPS / LS2024 - '''Meno Priezvisko'''
+
Záverečný projekt predmetu MIPS / LS2024 - '''Ján Ulej'''
  
  
 
== Zadanie ==
 
== Zadanie ==
  
Sem príde text zadania, ak bolo len voľne formulované, rozpíšte ho podrobnejšie
+
Zostrojte kuchynské minútky. Cez sériovú linku načítajte čas. Po uplynutí času bzučiak zahrá melódiu. 
  
[[Obrázok:ard.jpg|400px|thumb|center|Vývojová doska ACROB.]]
+
[[Obrázok:ArduinoNano_Ulej.jpeg|400px|thumb|center|Vývojová doska Arduino Nano.]]
  
 
'''Literatúra:'''  
 
'''Literatúra:'''  
* [http://ap.urpi.fei.stuba.sk/sensorwiki/index.php/Acrob_technical_description Dokumentácia k doske Acrob]
+
* [https://docs.arduino.cc/resources/datasheets/A000005-datasheet.pdf Dokumentácia k doske Arduino Nano]
* [http://www.humanbenchmark.com/tests/reactiontime/index.php Vyskúšajte si zmerať reakciu on-line]
+
 
  
  
Riadok 17: Riadok 17:
 
== Analýza  a opis riešenia ==
 
== Analýza  a opis riešenia ==
  
Opíšte sem čo a ako ste spravili, ak treba, doplňte obrázkami...
+
Kladný pól reproduktora (bzučiaka) som pripojil na mikroprocesor pin PD6. Ešte som medzi pin PD6 a kladný pól bzučiaka pripojil 220 ohm odpor ktorí slúži na odrušenie šumov ktoré potom vidno na sériovej komunikácii. Tlačidlo som pripojil tiež cez 220 ohm odpor na pin PD7.  
  
[[Súbor:ledRGB.jpg|400px|thumb|center|RGB LED.]]
+
[[Súbor:brucia_tlacidlo_Ulej.jpg|400px|thumb|center|Súčiastky.]]
  
Nezabudnite doplniť schému zapojenia!
+
Schéma zapojenia
  
[[Súbor:schd.png|400px|thumb|center|Schéma zapojenia LCD displeja.]]
+
[[Súbor:schema_zapojenia_Ulej.png|400px|thumb|center|Schéma zapojenia bzučiaka a tlačidla.]]
  
  
 
=== Algoritmus a program ===
 
=== Algoritmus a program ===
  
Algoritmus programu je....
+
Použil som knižnicu <uart.h> kde som si dodefinoval funkcie aby mi fungovalo načítavanie a výpis cez sériovú linku. Na načítavanie som použil 'scanf' a na výpis 'printf'. Tiež som použil knižnice <avr/interrupt.h> na prerušenia a <until/delay.h> na oneskorenie. Premenné ktoré som použil v prerušení som zadefinoval ako static volatile. Vytvoril som si prerušenie kde sa mi odčítaval čas. Realizoval som to pomocou 16-bitového počítadla T1. Vytvoril som funkciu 'hudba()' v ktorej som zadefinoval frekvencie a dĺžku jednotlivých tónov. Na generovanie frekvencií na výstupe som použil počítadlo 'Timer0' v režime generátora frekvencie 'CTC'.
 +
V hlavnom programe som nastavil tlačidlo ako vstup a zapol pull-up rezistor. Na ukladanie stavu tlačidla som použil dátový typ Enumerate.
 +
V hlavnej slučke načítam pomocou sériovej komunikácie čas vo formáte minúty:sekundy. Následne minúty premením na sekundy. Pomocou 'printf' vypisujem čas tiež vo formáte minúty:sekundy. Po uplynutí zvoleného času je zavolaná funkcia 'hudba()'. Skončenie prehrávania hudby a opätovné načítanie času je zabezpečené zatlačením tlačidla.    
  
  
 
<tabs>
 
<tabs>
<tab name="AVR C-code"><source lang="c++" style="background: LightYellow;">
+
<tab name="main.c"><source lang="c++" style="background: LightYellow;">
 
#include <avr/io.h>
 
#include <avr/io.h>
 +
#include "uart.h"
 +
#include <avr/interrupt.h>
 +
#include <util/delay.h>
 +
 +
FILE uart_output = FDEV_SETUP_STREAM(uart_putc, NULL, _FDEV_SETUP_WRITE);
 +
FILE uart_input  = FDEV_SETUP_STREAM(NULL, uart_getc, _FDEV_SETUP_READ);
 +
 +
static volatile int vstup_minuty = 0;
 +
static volatile int vstup_sekundy = 0;
 +
static volatile int cas = 0;
 +
static volatile int vystup_min = 0;
 +
static volatile int vystup_sek = 0;
 +
static volatile int stop = 0;
 +
  
 +
#define SW1 PD7 // tlacitko
 +
 +
#define set_bit(ADDRESS,BIT) (ADDRESS |= (1<<BIT))
 +
#define clear_bit(ADDRESS,BIT) (ADDRESS &= ~(1<<BIT))
 +
 +
 +
enum states { Off, Down, On, Up }; // stavy tlacitka
 +
 +
ISR (TIMER1_OVF_vect)         
 +
{
 +
  TCNT1 = 0xC2F7; // nastavenie pocitadla 
 +
 
 +
  if (cas>=0)
 +
  {
 +
  cas--;
 +
  }
 +
}
 +
 +
void tone(int note, int delay)
 +
{
 +
OCR0A = note;
 +
 +
for (int i=1; i<=delay; i++)
 +
    _delay_ms(1);
 +
}
 +
 +
 +
void hudba() // funkcia prehravania melodie
 +
{
 +
int c = 78;
 +
    int h = 104;
 +
    int p = 0;
 +
 
 +
    tone(c,250);
 +
tone(p,50);
 +
tone(h,250);
 +
tone(p,250);  
 +
 
 +
}
 +
 +
                             
 
int main(void)
 
int main(void)
 
{
 
{
   unsigned int measuredValue;
+
   uart_init();
 
+
  stdout = &uart_output;          // teraz funguje printf()
   while (1)
+
  stdin = &uart_input;            // teraz funguje scanf()
   {
+
 
     /* relax */  
+
  set_bit(PORTD,SW1);      // zapnutie pull-up rezistora
 +
  clear_bit(DDRD,SW1);    //  nastavenie pinu SW1 ako vstup
 +
 
 +
  enum states Tlacitko = Off;
 +
 
 +
 
 +
  //************************** T1 ***********************//
 +
 
 +
  TCNT1 = 0xC2F7;   
 +
  TCCR1B = 0b00000101; // externy zdroj hodin na pin T1 reagujuci na nabeznu hranu
 +
 
 +
 
 +
  // konfiguracia prerusovacieho systemu
 +
  PCMSK2 |= (1<<PCINT21);
 +
  PCICR |= (1<<PCIE2);
 +
  sei(); // povolenie preruseni
 +
 +
  // pretecenie
 +
  TIMSK1 = (1<<TOIE1);    // povolenie pretecenia Timer 1
 +
  sei();                  // povolenie preruseni
 +
 
 +
 
 +
//********************* hudba *************************//
 +
 +
  DDRD  |= (1 << PD6);                      // port D.6 pin ako vystup
 +
  TCCR0A =  (1 << COM0A0) | (1 << WGM01);    // Timer 0 v rezime CTC
 +
  TCCR0B = (1 << CS02);                      // nastavenie preddelicky na 256
 +
 
 +
 
 +
 
 +
   while(1)
 +
   {
 +
puts("Zadaj cas (min:sek)\r");
 +
    scanf("%d:%d",&vstup_minuty,&vstup_sekundy); // nacitanie casu
 +
    cas = vstup_minuty * 60 + vstup_sekundy;     // prepocitanie na sekundy
 +
 +
while(cas>=0)
 +
{
 +
vystup_min = cas / 60;
 +
vystup_sek = cas % 60;
 +
printf("%d:%d\r", vystup_min, vystup_sek);
 +
delay(1000);
 +
if(cas !=-1)
 +
{
 +
printf("    \r");
 +
}
 +
 +
}
 +
stop = 0;
 +
    while(stop == 0)
 +
{
 +
hudba();
 +
if ( (Tlacitko == Off) &&  bit_is_clear(PIND,SW1)  )
 +
    {
 +
 +
    Tlacitko = Down;
 +
           
 +
    }
 +
    else if ( (Tlacitko == Down) &&  bit_is_clear(PIND,SW1)  )
 +
    {
 +
 +
      _delay_ms(10);               
 +
    if ( bit_is_clear(PIND,SW1) ) 
 +
    Tlacitko = On;
 +
 +
    }
 +
    else if  ( (Tlacitko == On) && bit_is_set(PIND,SW1) )  
 +
    {
 +
   
 +
      Tlacitko = Up;
 +
 +
    }
 +
    else if ( (Tlacitko == Up) && bit_is_set(PIND,SW1) )
 +
    {
 +
 +
    _delay_ms(10);
 +
    if ( bit_is_set(PIND,SW1) )
 +
    Tlacitko = Off;
 +
 +
    }
 +
 +
if(Tlacitko == Down)
 +
{
 +
 +
stop = 1;
 +
Tlacitko = Off;
 +
 +
}
 +
}
 
   }
 
   }
 
 
   return(0);
 
   return(0);
 
}
 
}
  
 
</source></tab>
 
</source></tab>
<tab name="filename.h"><source lang="c++" style="background: LightYellow;">
+
<tab name="uart.c"><source lang="c++" style="background: LightYellow;">
 
#include <avr/io.h>
 
#include <avr/io.h>
 +
#include <util/delay.h>
 +
#include "uart.h"
 +
  
void adc_init(void);                                   // A/D converter initialization
+
void uart_init( void )
 +
{
 +
//  for different BAUD rate change the project settings, or uncomment
 +
//  following two lines:
 +
// #undef  BAUD          // avoid compiler warning
 +
//  #define BAUD 115200
 +
 +
  #include <util/setbaud.h>  // requires defined BAUD
 +
 
 +
  UBRR0H = UBRRH_VALUE;
 +
  UBRR0L = UBRRL_VALUE;
 +
  #if USE_2X                // defined in setbaud.h
 +
    UCSR0A |= (1 << U2X0);
 +
  #else
 +
    UCSR0A &= ~(1 << U2X0);
 +
  #endif
 +
 
 +
 
 +
    UCSR0C = _BV(UCSZ01) | _BV(UCSZ00); /* 8-bit data */
 +
    UCSR0B = _BV(RXEN0) | _BV(TXEN0);  /* Enable RX and TX */
 +
}
 +
 
 +
 
 +
int uart_putc( char c, FILE *stream )
 +
{
 +
  if (c == '\n')
 +
      uart_putc('\r',stream);
 +
 
 +
  loop_until_bit_is_set(UCSR0A, UDRE0); /* Wait until data register empty. */
 +
  UDR0 = c;
 +
  return 0;
 +
}
 +
 
 +
 
 +
char uart_getc(void)
 +
{
 +
    //loop_until_bit_is_set(UCSR0A, RXC0); /* Wait until data exists. */
 +
    //return UDR0;
 +
while (!(UCSR0A & (1<<RXC0)));
 +
return UDR0;
 +
 +
}
 +
 
 +
void delay(int delay)      // vlastna funkcia pre dlhsie casy
 +
{
 +
  for (int i=1; i<=delay; i++)
 +
  _delay_ms(1);
 +
}
  
unsigned int adc_read(char a_pin);
 
 
</source></tab>
 
</source></tab>
</tabs>
+
<tab name="uart.h"><source lang="c++" style="background: LightYellow;">
 +
#define set_bit(ADDRESS,BIT) (ADDRESS |= (1<<BIT))
 +
#define clear_bit(ADDRESS,BIT) (ADDRESS &= ~(1<<BIT))
 +
 
 +
#ifndef UART_H_
 +
#define UART_H_
 +
 
 +
#include <stdio.h>
 +
 
 +
#define BAUD_PRESCALE  (((F_CPU / (BAUDRATE * 16UL))) - 1)  // vzorcek z datasheetu
 +
 
 +
void hw_init( void );
 +
void uart_init( void );
 +
   
 +
int uart_putc( char c, FILE *stream );
 +
void uart_puts( const char *s );
  
Pridajte sem aj zbalený kompletný projekt, napríklad takto (použite jednoznačné pomenovanie, nemôžeme mať na serveri 10x ''zdrojaky.zip'':
+
char uart_getc( void );
  
Zdrojový kód: [[Médiá:projektMenoPriezvisko.zip|zdrojaky.zip]]
+
void delay(int delay);
  
 +
#endif /* UART_H_ */
 +
</source></tab>
 +
</tabs>
 +
 +
 +
Zdrojový kód: [[Médiá:Ulejprojekt.zip|zdrojaky.zip]]
  
 
=== 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 používanie treba zapojiť zariadenia podľa schémy vyššie. Na sériovú komunikáciu je potrebný niektorý terminálový program napr. PuTTY.  
Na konci uvádzame fotku záverečnej obrazovky pred resetom. Vypísaný je tu priemerný čas a najlepší čas.  
+
* [https://www.chiark.greenend.org.uk/~sgtatham/putty/latest.html PuTTY download]
 +
 
  
[[Súbor:fotka.jpg|400px|thumb|center|Aplikácia.]]
+
[[Súbor:Aplikacia_Ulej.jpg|400px|thumb|center|Aplikácia.]]
  
 
'''Video:'''
 
'''Video:'''

Verzia zo dňa a času 16:39, 8. máj 2024

Záverečný projekt predmetu MIPS / LS2024 - Ján Ulej


Zadanie

Zostrojte kuchynské minútky. Cez sériovú linku načítajte čas. Po uplynutí času bzučiak zahrá melódiu.

Vývojová doska Arduino Nano.

Literatúra:


Analýza a opis riešenia

Kladný pól reproduktora (bzučiaka) som pripojil na mikroprocesor pin PD6. Ešte som medzi pin PD6 a kladný pól bzučiaka pripojil 220 ohm odpor ktorí slúži na odrušenie šumov ktoré potom vidno na sériovej komunikácii. Tlačidlo som pripojil tiež cez 220 ohm odpor na pin PD7.

Súčiastky.

Schéma zapojenia

Schéma zapojenia bzučiaka a tlačidla.


Algoritmus a program

Použil som knižnicu <uart.h> kde som si dodefinoval funkcie aby mi fungovalo načítavanie a výpis cez sériovú linku. Na načítavanie som použil 'scanf' a na výpis 'printf'. Tiež som použil knižnice <avr/interrupt.h> na prerušenia a <until/delay.h> na oneskorenie. Premenné ktoré som použil v prerušení som zadefinoval ako static volatile. Vytvoril som si prerušenie kde sa mi odčítaval čas. Realizoval som to pomocou 16-bitového počítadla T1. Vytvoril som funkciu 'hudba()' v ktorej som zadefinoval frekvencie a dĺžku jednotlivých tónov. Na generovanie frekvencií na výstupe som použil počítadlo 'Timer0' v režime generátora frekvencie 'CTC'. V hlavnom programe som nastavil tlačidlo ako vstup a zapol pull-up rezistor. Na ukladanie stavu tlačidla som použil dátový typ Enumerate. V hlavnej slučke načítam pomocou sériovej komunikácie čas vo formáte minúty:sekundy. Následne minúty premením na sekundy. Pomocou 'printf' vypisujem čas tiež vo formáte minúty:sekundy. Po uplynutí zvoleného času je zavolaná funkcia 'hudba()'. Skončenie prehrávania hudby a opätovné načítanie času je zabezpečené zatlačením tlačidla.


#include <avr/io.h>
#include "uart.h"
#include <avr/interrupt.h>
#include <util/delay.h>

FILE uart_output = FDEV_SETUP_STREAM(uart_putc, NULL, _FDEV_SETUP_WRITE);
FILE uart_input  = FDEV_SETUP_STREAM(NULL, uart_getc, _FDEV_SETUP_READ); 

static volatile int vstup_minuty = 0;
static volatile int vstup_sekundy = 0;
static volatile int cas = 0;
static volatile int vystup_min = 0;
static volatile int vystup_sek = 0;
static volatile int stop = 0;


#define SW1 PD7		// tlacitko

#define set_bit(ADDRESS,BIT) (ADDRESS |= (1<<BIT))
#define clear_bit(ADDRESS,BIT) (ADDRESS &= ~(1<<BIT))


enum states { Off, Down, On, Up };		// stavy tlacitka

ISR (TIMER1_OVF_vect)          
 {
   TCNT1 = 0xC2F7;		// nastavenie pocitadla  
   
   if (cas>=0)
   {
	   cas--;
   }
 }
 
void tone(int note, int delay)
{
	OCR0A = note;
	
	for (int i=1; i<=delay; i++)
     _delay_ms(1);
}

 
void hudba()		// funkcia prehravania melodie
{
	int c = 78;
    int h = 104;
    int p = 0;
		  
    tone(c,250);
	tone(p,50);
	tone(h,250);
	tone(p,250);	  
  
}

                              
int main(void)
{
  uart_init();
  stdout = &uart_output;           // teraz funguje printf()
  stdin = &uart_input;            // teraz funguje scanf()
  
  set_bit(PORTD,SW1);       // zapnutie pull-up rezistora
  clear_bit(DDRD,SW1);     //  nastavenie pinu SW1 ako vstup
  
  enum states Tlacitko = Off;
  
  
  //************************** T1 ***********************//
  
  TCNT1 = 0xC2F7;    
  TCCR1B = 0b00000101;		// externy zdroj hodin na pin T1 reagujuci na nabeznu hranu
  
  
  // konfiguracia prerusovacieho systemu
   PCMSK2 |= (1<<PCINT21);
   PCICR |= (1<<PCIE2);		
   sei();					// povolenie preruseni
	
  // pretecenie
   TIMSK1 = (1<<TOIE1);    // povolenie pretecenia Timer 1
   sei();                  // povolenie preruseni
  
  
 //********************* hudba *************************//
 
   DDRD   |= (1 << PD6);                      // port D.6 pin ako vystup
   TCCR0A =  (1 << COM0A0) | (1 << WGM01);    // Timer 0 v rezime CTC
   TCCR0B = (1 << CS02);                      // nastavenie preddelicky na 256
   
   
   
  while(1)
  {	
	 puts("Zadaj cas (min:sek)\r");
     scanf("%d:%d",&vstup_minuty,&vstup_sekundy); // nacitanie casu
     cas = vstup_minuty * 60 + vstup_sekundy;     // prepocitanie na sekundy
	 
	 while(cas>=0)
	 {
		 vystup_min = cas / 60;
		 vystup_sek = cas % 60;
		 printf("%d:%d\r", vystup_min, vystup_sek);
		 delay(1000);
		 if(cas !=-1)
		 {
			 printf("     \r");
		 }
		 
	 }
	 stop = 0;
     while(stop == 0)
	 {
		 hudba();
		if ( (Tlacitko == Off) &&  bit_is_clear(PIND,SW1)  )
	     {
			 
		    Tlacitko = Down;
				           	  
	     }
	     else if ( (Tlacitko == Down) &&  bit_is_clear(PIND,SW1)  )
	     {
			 
  		     _delay_ms(10);                 
		    if ( bit_is_clear(PIND,SW1) )  	
		     Tlacitko = On;
			 
	     }
	     else if  ( (Tlacitko == On) &&  bit_is_set(PIND,SW1) ) 	  
	     {
	   	  
	   	    Tlacitko = Up;
			
	     }
	     else if (  (Tlacitko == Up) &&  bit_is_set(PIND,SW1) )
	     {
			 
		     _delay_ms(10); 
		    if ( bit_is_set(PIND,SW1) )	
		    Tlacitko = Off;
			
	     }
		 
		 if(Tlacitko == Down)
		 {
			 
			stop = 1;
			Tlacitko = Off;
			
		 }
	 }
  }
  return(0);
}
#include <avr/io.h>
#include <util/delay.h>
#include "uart.h"


void uart_init( void ) 
{
//  for different BAUD rate change the project settings, or uncomment 
//  following two lines:	
//	#undef  BAUD           // avoid compiler warning
//  #define BAUD 115200
	
   #include <util/setbaud.h>  // requires defined BAUD
   
   UBRR0H = UBRRH_VALUE;
   UBRR0L = UBRRL_VALUE;
   #if USE_2X                 // defined in setbaud.h 
    UCSR0A |= (1 << U2X0);
   #else
    UCSR0A &= ~(1 << U2X0);
   #endif


    UCSR0C = _BV(UCSZ01) | _BV(UCSZ00); /* 8-bit data */
    UCSR0B = _BV(RXEN0) | _BV(TXEN0);   /* Enable RX and TX */	
}


int uart_putc( char c, FILE *stream )
{
   if (c == '\n') 
      uart_putc('\r',stream);
   
   loop_until_bit_is_set(UCSR0A, UDRE0); /* Wait until data register empty. */
   UDR0 = c;
   return 0;
}


char uart_getc(void) 
{
    //loop_until_bit_is_set(UCSR0A, RXC0); /* Wait until data exists. */
    //return UDR0;
	while (!(UCSR0A & (1<<RXC0)));
	return UDR0;
	
}

void delay(int delay)      // vlastna funkcia pre dlhsie casy 
{
  for (int i=1; i<=delay; i++)
  _delay_ms(1);
}
#define set_bit(ADDRESS,BIT) (ADDRESS |= (1<<BIT))
#define clear_bit(ADDRESS,BIT) (ADDRESS &= ~(1<<BIT))

#ifndef UART_H_
#define UART_H_

#include <stdio.h>

#define BAUD_PRESCALE  (((F_CPU / (BAUDRATE * 16UL))) - 1)  // vzorcek z datasheetu

void hw_init( void );
void uart_init( void );
     	 
int uart_putc( char c, FILE *stream );
void uart_puts( const char *s );

char uart_getc( void );

void delay(int delay); 

#endif /* UART_H_ */


Zdrojový kód: zdrojaky.zip

Overenie

Na používanie treba zapojiť zariadenia podľa schémy vyššie. Na sériovú komunikáciu je potrebný niektorý terminálový program napr. PuTTY.


Aplikácia.

Video:

Kľúčové slová 'Category', ktoré sú na konci stránky nemeňte.