Table of Contents

Acordor de chitara

Introducere

Proiectul este un acordor de chitara. Selectia unei corzi de acordat se face prin apasarea butonului corespunzator corzii. Dupa selectia microfonul va prelua sunetul si ii va testa frecventa cu frecventa de referinta a sunetului, urmand sa afiseze gradul de corectitudine prin aprinderea unuia dintre cele 3 leduri astfel:

Scopul proiectului este acela de a permite o acordare cat mai simpla a unei chitare.

Descriere generală

Module Hardware

In afara modulelor hardware din cadrul placutei de baza din prima etapa, se disting urmatoarele module:

Module Software

Se disting 5 module software:

Schema bloc Hardware

Schema bloc Software

Hardware Design

Piese
Scheme electrice

Software Design

Module Software

void correct_led()

{
	PORTB |= (1<<PB1);
	PORTB &= ~(1<<PB0) & ~(1<<PB2);
}

void lower_led()

{
	PORTB |= (1<<PB0);
	PORTB &= ~(1<<PB1) & ~(1<<PB2);
}

void higher_led()

{
	PORTB |= (1<<PB2);
	PORTB &= ~(1<<PB0) & ~(1<<PB1);
}

void err_led()

{
	PORTB |= (1<<PB0) | (1<<PB2);
	PORTB &= ~(1<<PB1);
}

int sel_but()

{
 int b_sel = -1;
 int selected = 0;

 if (!(PINC & (1<<PC0)))
	{
		b_sel = 0;
		selected = 1;
	}

 if (!(PINC & (1<<PC1)))
	{
	  if(selected)
		return -2;
	  else
	  {
		b_sel = 1;
		selected = 1;
	  }
	}

 if (!(PINC & (1<<PC2)))
	{
		if(selected)
			return -2;
		else
		{
			b_sel = 2;
			selected = 1;
		}
	}
	
if (!(PINC & (1<<PC3)))
	{
		if(selected)
			return -2;
		else
		{
			b_sel = 3;
			selected = 1;
		}
	}
	
if (!(PINC & (1<<PC4)))
	{
		if(selected)
			return -2;
		else
		{
			b_sel = 4;
			selected = 1;
		}
	}
	
 if (!(PINC & (1<<PC5)))
	{
		if(selected)
			return -2;
		else
		{
			b_sel = 5;
			selected = 1;
		}
	}

 return b_sel;
}

void ADC_init()

{
	ADMUX = 0;
	ADMUX |= (1<<REFS0) | (1<<ADLAR);
	ADCSRA = 0;
	ADCSRA |= (1<<ADIE) | (1<<ADPS2) | (1<<ADPS1) | (1<<ADPS0) | (1<<ADATE);
	SFIOR &= ~(1<<ADTS0) & ~(1<<ADTS1) & ~(1<<ADTS2);
	ADCSRA |= (1<<ADEN);
}

float ADC_get()

{
	
	ADCSRA |= (1<<ADSC);
	loop_until_bit_is_set(ADCSRA,ADIF);
	return ADCH;
}

void fourier(float *x)

{
	long i,j,k,logN,le,le2;
	float *p, *q,t, ur, ui,arg,wr,wi,*p1r,*p1i,*p2r,*p2i,tr,ti;
	logN = (long)(log(16)/log(2.) + .5);
	
	
	for(i=2;i< 30;i+=2)
		{
			for(k=2, j=0;k<32;k<<=1)
				{
					if ( i & k ) j++;
					j <<=1;
				}
			if (i < j)
				{
				 p = x + i;
				 q = x + j;
				 t = *p;
				 *(p++) = *q;
				 *(q++) = t;
				 t = *p;
				 *p = *q;
				 *q = t;
				}
		}
		
	for (k = 0, le = 2; k<logN; k++)
		{
			le <<= 1;
			le2 = le >> 1;
			ur = 1.0;
			ui = 0.0;
			arg = M_PI/(le2>>1);
			wr = cos(arg);
			wi = -sin(arg);
			
			for(j=0;j<le2;j+=2)
				{
				 p1r = x + j; p1i = p1r + 1;
				 p2r = p1r + le2; p2i= p2r + 1;
				 for(i=j;i<32;i+=le)
					{
						tr = *p2r * ur - *p2i * ui;
						ti = *p2r * ui + *p2i * ur;
						*p2r = *p1r - tr;
						*p2i = *p1i - ti;
						*p1r += tr;
						*p1i += ti;
						p1r += le;
						p1i += le;
						p2r += le;
						p2i += le;
					}
				tr = ur *wr - ui * wi;
				ui = ur * wi + ui * wr;
				ur = tr;
				}
		}
}

Rezultate Obţinute

Acordarea nu se face corespunzator deoarece nu s-a putut realiza extragerea corecta a frecventei din sirul rezultat in urma transformatei fourier.

Concluzii

Nu s-a putut finisa proiectul in lipsa unei metode corecte de a extrage frecventa din sirul intors de transformata fourier. Metoda recomandata intoarce intotdeauna o frecventa cu valoarea 0:

fourier(v); max = -100; maxi = 0; F_curent = F_ref[x]; for(i=0;i<16;i++)

 if ( v[i] > max )
{max = v[i]; maxi = i; }

max = maxi * sampleRate/ transformLength;

if(max < F_curent +15 && max > F_curent -15)

correct_led();

else

if (max > F_curent)
	higher_led();
else
	lower_led(); 

Sampelul ales a fost de 16 valori de la ADC. A fost testata placuta si cu sampeluri mai mari (32,64,128) dar cu acelasi rezultat.

Download

Arhiva cu surse si scheme: acordor_de_chitara.zip

Arhiva contine:

Bibliografie/Resurse

Resurse Hardware

Resurse Software