#include <avr/io.h>
#include <stdio.h>
#include <avr/interrupt.h>
#include "program_novy.h"


unsigned int channel [8];	// pole na ukladanie hodnot po prevode
unsigned int max;			// hodnota maximálne relatívnej zmeny
unsigned char max1 ;		// index kanálu s max. relatívnou zmenou
unsigned int ref [8] = {500,500,500,500,500,500,500,500};	// pole referenčných hodnot napätí
unsigned int dif [8];		// pole zmien napätia v jednotlivých kanáloch AD prevodníka
unsigned char prevod = 0;   // index kanálu ADC
extern unsigned char ch;	// pomocná premenná
unsigned int komp =0 ;		// premenná, ktorá zvýši prah citlivosti po vzniku efektu
unsigned char b=0;			// pomocná premenná, určuje periódu ukladania hodnôt po AD prevode
extern unsigned char fronta [3][4];	// pole na zápis svetelných efektov (ich parametrov)
unsigned char count=0;  	// počítadlo prevodov (0-64)
unsigned char data_master_passive;	// premenná, ktorá informuje riadiacu dosku, že je súčasťou reakcie na svetelný efekt
unsigned char data_slave;	// informuje riadiacu dosku o vzniknutom svetelnom efekte (podriadená doska ju odosiela)


void set_parameters	(unsigned char max1,unsigned char offset);	// funkcia zapíše parametre efektu do pola fronta

//------------------------------------------------------------------------------------------------------
//Obsluha prerušenia po dokončení A/D prevodu
//------------------------------------------------------------------------------------------------------

ISR (ADC_vect)
{
	b++;					// zväčšenie pomocnej premennej, určuje periódu opakovania obsluhy
	if (b==3)
	{

		b=0;				// vynulovanie pomocnej premennej

		if (channel[prevod]<63000)				// zabránenie prípadnému pretečeniu
			{
				channel [prevod] += ADCW ; 		// uloženie výsledku prevodu z daného kanálu (index ch)
			}
	
		count++; 			// inkrementácia počítadla prevodov
	

		if (count == 64)	// testovanie, či už bolo uložených 64 prevodov
			{
				prevod++;	// prepnutie na ďalší kanál A/D prevodníka
		
				if (prevod == 8)		// po ôsmich prevodoch sa spriemerujú výsledky z jednotlivých kanálov
				{	
					priemer = 0;	// vynulovanie priemeru z predošlej analýzy

					for (ch=0;ch<8;ch++)
						{
							channel [ch] = (channel [ch] >>6) ; 	// vypočítanie priemeru v každom kanále (/64)
						
							pomoc2 = (int)channel [ch] - (int)ref [ch];	// výpočet rozdielu súčasného a predošlého priemeru
						
							if (pomoc2 <0)							// ak je rozdiel záporný (zväčšenie osvetlenie) spraví sa z neho abs. hodnota
								{
									pomoc2 = (int)ref[ch] - (int)channel[ch];
								}

							dif [ch] = (pomoc2<<7)/ ref[ch];// výpočet relatívnej zmeny (*128/ref)
						
							
							ref [ch] = channel [ch];		// zápis novej ref. hodnoty
							priemer += channel [ch] ;		// uloženie priemernej hodnoty daného kanálu
						}

			
					
					priemer = (priemer>>3); 	    // výpočet priemeru z hodnôt všetkých kanálov
				
					for (ch=0;ch<8;ch++)			// najdenie kanálu s maximom (max1), a hodnotu maxima (max)
						{	
					 		if ( dif [ch] > max)
								{
									max = (dif[ch]) ;	// uloženie hodnoty maxima
									max1 = ch;			// uloženia indexu kanálu s maximom
									channel [ch] = 0 ;	// vynulovanie pola channel
								}
						}
			
				 	if ((priemer <60))			// určenie prahu spustenia efektu podľa hodnoty priemeru všetkých kanálov
						{
							hranica = 5;
						}
				
					else if (priemer>600)
						{
							hranica = 3;
						}

					else if (priemer>800)
						{
							hranica = 1;
						}

					else 
						{
							hranica = 20;
						}

					if (max > (hranica+komp))	// testovanie či bola zmena väčšia ako prahová hodnota (+ kompenzácia) 
						{
							set_parameters (max1,0);	// zápis efektu do poľa fronta (časový offset je nulový, efekt vznikol na doske)
							data_slave = (max1 + 1);	// doska si nastaví nenulovú odpoveď na oslovenie (podľa miesta vzniku efektu)

						}
								
					max=0;				// vynulovanie maxima
					prevod = 0;			// nastavenie prvého kanála A/D prevodníka 
				}

				ADMUX = prevod + 0b01000000; // zmena kanála v registre ADMUX
				count = 0;				// vynulovanie počítadla prevodov
			}
	}
}

// funkcia, ktorá zapíše dané parametre efektu do poľa fronta
void set_parameters	(unsigned char max1, unsigned char offset)
{			
	switch (max1)				// prepínač podla indexu kanálu A/D prevodníka s najväčšou zmenou
		{
			case 0: 			// nastavia sa príslušné súradnice stredu
					stredx = 0;
					stredy = 4;
					break;

			case 1:
					stredx = 0;
					stredy = 0;
					break;

			case 2:
					stredx = 4;
					stredy = 0;
					break;

			case 3:
					stredx = 7;
					stredy = 0;
					break;
			case 4:
					stredx = 7;
					stredy = 3;
					break;

			case 5:
					stredx = 7;
					stredy = 7;
					break;
		
			case 6:
					stredx = 3;
					stredy = 7;
					break;

			case 7: 
					stredx = 0;
					stredy = 7;
					break;
		}
					
					
	for (ch=0;ch<3;ch++)		// zápis efektu do poľa fronta
		{
			if (fronta [ch][2]==0)		// ak je v poli fronta miesto na zápis (tj. aspoň v jednom riadku je veľkosť nulová)
				{
					fronta [ch][0] = stredx;		// zápis na najvyššie volné miesto
					fronta [ch][1] = stredy;
					fronta [ch][2] = 1 ;			// parameter strana = 1, tj. efekt sa aktivuje
					fronta [ch][3] = offset;		// zapísanie časového offsetu
					komp = 30;			// zníženie citlivosti
					break;
				}
		}
}


