Automatic Guitar Tuner

                           _    _   _ __    _ __
                          | |  | | | '_ \  | '_ \
                          | |  | | | |_) | | |_) |
                          | |  | | | .__/  | '_ )
                          | \__/ | | |     | |_) |
                          \______/ |_|     |_.__/
                          -------- _______ -------

   _______________________________________
  / Look for my W-USO ;)                  \
  \ (No, seriously, don't look...)        /
   ---------------------------------------
          \   ^__^
           \  (oo)\_______
              (__)\       )\/\
                  ||----w |
                  ||     ||

Autor

Introducere

Proiectul implementează un Acordor Automat pentru Chitară care permite acordarea mult mai facilă și rapidă a unei chitare. Scopul proiectului este să permită selectarea mai multor acordaje pentru chitară, cât și selectarea notei și înălțimea la care trebuie acordată o anumită coardă. Coarda va fi apoi acordată (semi-)automat, chitaristul trebuind doar să zdrăngănească coarda pe care dorește să o acordeze, iar acordorul va trebui să strângă sau să slăbească cheia (șurubul) de acordare.

Descriere Generală

Pe un ecran LCD se va afișa nota selectată, iar cu ajutorul a două butoane se poate selecta o notă mai joasă sau mai înaltă. Cu ajutorul unui microfon, acordorul primește sunetul produs de una dintre corzile chitarei și verifică cât de aproape este sunetul primit față de nota de referință (dacă sunetul este mai înalt sau nu față de aceasta) iar apoi folosind un motor stepper va încerca să strângă sau să slăbească cheia (șurubul) de acordare pentru a acorda coarda. Microcontrolerul se va ocupa de analiza semnalului primit și de compararea frecvenței notei cu cea de referință (la care se dorește acordarea).

Diagrama Bloc

Hardware Design

Lista de Piese

Listă Orientativă

Denumire Cantitate
Placă PM 1
Microcontroller ATMega324PA-PU 1
Kit-ul cu Componentele de Bază 1
Modul Motor Stepper sau Servomotor 1
Modul Microfon 1
Modul Display LCD 16×2 1
Butoane 3
Breadboard 1

Piese Placa de Bază

<hidden Componente de Bază>

Denumire Cantitate
Soclu Microcontroller 1
Jumper 1
Mufă USB B 1
Cristal Cuarț 16 MHz 1
Header 1×10 4
Header 2×3 1
Header 1×3 6
Header 2×5 1
Header 1×3 1
Pushbutton Switch 2
LED 2
Diodă Zener 2
Rezistor 100 Ohmi 2
Rezistor 470 Ohmi 3
Rezistor 1K5 Ohmi 1
Rezistor 10K Ohmi 1
Condensator Ceramic 100nF 3
Condensator Ceramic 15pF 2
Condensator Electrolitic 0.1uF 1

</hidden>

<hidden Componente Opționale 5V - 3V3>

Denumire Cantitate
Regulator Tensiune 5V - 3V3 1
Condensator Electrolitic 10uF 1

</hidden>

<hidden Componente Opționale Display LCD Grafic>

Denumire Cantitate
Rezistor 1K Ohmi 1

</hidden>

<hidden Componente Opționale LCD Text>

Denumire Cantitate
Header 1×16 1
Rezistor 1K Ohmi 1
Rezistor 10K Ohmi 2

</hidden>

Listă Kit cu Componente de Bază

Modul Motor Stepper sau Servomotor

Modul Microfon

Microfon Electret cu Terminale Amplificator Audio LM386 (DIP-8) LM386 microphone amplifier

Denumire Cantitate
Microfon Electret 1
Modul LM386 1
Rezistor 10K Ohmi 2
Condensator Ceramic 100nF 1
Condensator Ceramic 47nF 1
Condensator Electrolitic 220uF 1
Condensator Electrolitic 100uF 1
Condensator Electrolitic 10uF 2
Condensator Electrolitic 1uF 1

Modul Display LCD 16x2

Modul LCD 1602 cu backlight albastru de 5 V

Denumire Cantitate
Ecran LCD 16×2 cu Backlight Albastru 1

Schema Electrică

Schemă Orientativă

Rezultatele Simulării

Pentru simulări au fost folosite diferite semnale audio cu frecvență constantă, acordorul reușind să identifice cel mai bine frecvențele înalte. Pentru frecvențele joase micile distorsiuni ce apar influențează rezultatele măsurătorii. Pentru semnale audio atenuate, cum sunt cele ale chitarei, acuratețea măsurătorilor este mult mai mică din cauza pierderii din amplitudine a notei cântate. Motorul Stepper folosit pentru acordare are cuplul mult prea mic și nu poate să învârtă cheițele de la chitară pentru a acorda o coardă. Pentru testarea identificării semnalului audio și a notelor muzicale am folosit un playlist Chromatic Tuning Scale ce are frecvențe muzicale pentru următoarele 12 note muzicale: A♭4/G♯4, A4, A♯4/B♭4, B4, C5, C♯5/D♭5, D5, D♯5/E♭5, E5, F5, F♯5/G♭5, G5, G♯5/A♭5.

Software Design

Mediu de Dezvoltare

Codul sursă al aplicației pentru microprocesor a fost scris folosind gedit și CodeBlocks, compilat cu avr-gcc și încărcat în plăcuță folosind bootloadHID.

Biblioteci

Implementarea folosește biblioteci pentru modularizarea fiecărei componente a procesului:

  • btn - pentru descrierea operațiilor efectuate de butoane
  • lcd - pentru operarea cu ecranul LCD 16×02
  • led - pentru comandarea LED-ului ce indică funcționarea microcontrolerului
  • microphone - pentru citirea semnalului audio
  • music - pentru abstractizarea informațiilor despre notele muzicale
  • stepper - pentru controlul Motorului Stepper.

<WRAP prewrap>

music.h
#ifndef MUSIC_H
#define MUSIC_H
 
#define NOTES 12
#define PITCHES 8
#define STRINGS 6
 
extern char *note_names[];
extern float note_freqs[];
extern char *note_pitch[];
 
extern char *standard_names[];
extern float standard_freqs[];
 
extern char *drop_d_names[];
extern float drop_d_freqs[];
 
extern char *d_names[];
extern float d_freqs[];
 
float get_freq(float note, int pitch);
 
#endif /* MUSIC_H_ */
music.c
#include "music.h"
 
char *note_names[] = {"C ", "C#", "D ", "D#",
			"E ", "F ", "F#", "G ",
			"G#", "A ", "A#", "B "};
float note_freqs[] = {8.1758f, 8.6620f, 9.1770, 9.7227f,
			10.301f, 10.914f, 11.563f, 12.250f,
			12.979f, 13.750f, 14.568f, 15.434f};
char *note_pitch[] = {"   0", "   1", "   2", "   3",
			"   4", "   5", "   6", "   7"};
 
char *standard_names[] = {"E2", "A2", "D3",
				"G3", "B3", "E4"};
float standard_freqs[] = {82.407f, 110.000f, 146.830f,
				196.000f, 246.940f, 329.630f};
 
char *drop_d_names[] = {"D2", "A2", "D3",
			"G3", "B3", "E4"};
float drop_d_freqs[] = {73.416f, 110.000f, 146.830f,
			196.000f, 246.940f, 329.630f};
 
char *d_names[] = {"D2", "G2", "C3",
			"F3", "A3", "D4"};
float d_freqs[] = {73.416f, 97.999f, 130.810f,
			174.610f, 220.000f, 293.660f};

</WRAP>

Algoritmi și Structuri de Date

Structurile de date folosite sunt simple și constau în vectori de șiruri de caractere pentru încapsularea datelor ce trebuie afișate într-un meniu sau a notelor și frecvențelor corespunzătoare dintr-un acordaj pentru chitară.

La baza algoritmului de detecție a unei note stau un timer și întreruperile pe pin-ul la care este legat microfonul. Timerul este setat la o secundă, ceea ce corespunde unui Hertz. Timp de o secundă, se numără întreruperile ce apar pe pinul semnalului audio în care amplitudinea semnalului trece în 0, ceea ce corespunde unei schimbări de semn, incrementând un contor ce numără schimbările. După o secundă, când expiră timerul se compară frecvența măsurată cu cea de referință (a unei note) și se decide rotirea motorului (pentru acordare - strângere sau destindere) sau terminarea acordării.

Surse și Funcții Implementate

Implementarea detecției unei frecvențe pentru o notă are la bază următoarea implementare.

<WRAP prewrap>

main.c
char *note;
float freq = 0.0f;
int count_freq;
 
void MICROPHONE_init(void)
{
	/* start audio interrupts */
	MICROPHONE_DDR &= ~(1 << MICROPHONE_P);
	PCICR |= (1 << MICROPHONE_PCIE);
	MICROPHONE_PCMSK |= (1 << MICROPHONE_PCINT);
}
 
void TIMER1_init(void)
{
	/* set timer to one second, or one Hertz */
	TCCR1B |= (1 << CS12) | (1 << WGM12);
	TIMSK1 |= (1 << OCIE1A);
	OCR1A = 62500 - 1;
}
 
void TIMER1_free(void)
{
	TCCR1B = 0;
	TIMSK1 = 0;
	OCR1A = 0;
}
 
ISR(TIMER1_COMPA_vect)
{
	TIMER1_free();
	char buff[BUFF_SIZE];
	float f = count_freq;
	float df = freq - f;
 
	LCD_clear();
	LCD_printAt(LCD_FIRST_LINE_BEGIN, note);
	sprintf(buff, "%d", count_freq);
	LCD_printAt(LCD_SECOND_LINE_BEGIN, buff);
	if (fabsf(df) < FREQ_TOLERANCE) {
		/* note frequency is in tolerance interval */
		note = NULL;
		freq = 0.0f;
		_delay_ms(1000);
		LCD_clear();
		LCD_printAt(LCD_FIRST_LINE_BEGIN, note);
		LCD_printAt(LCD_SECOND_LINE_BEGIN, "OK");
		count_freq = 0;
	} else {
		/* tune note */
		if (f > FREQ_TOLERANCE)
			STEPPER_rotation(df);
		count_freq = 0;
		TIMER1_init();
	}
}
 
ISR(PCINT0_vect)
{
	/* count changes of sign in oscillation */
	if ((MICROPHONE_PIN & (1 << MICROPHONE_P)) == 0)
		count_freq++;
}

</WRAP>

Pornind de la o notă cu o frecvență de bază, frecvențele pentru octavele superioare pot fi obținute astfel:

<WRAP prewrap>

float get_freq(float note, int pitch)
{
	/* from a note in an octave to next octave multiply by two */
	float freq = (1 << (pitch + 1)) * note;
	return freq;
}

</WRAP>

Rezultate Obținute

În urma realizării proiectului a fost obținut un acordor ce poate fi folosit nu doar în acordarea unei chitare, ci și pentru acordarea multor alte instrumente, datorită opțiunii de acordarea a oricărei note în opt octave. Din păcate motorul folosit nu are putere foarte mare, așa că partea de acordare automată a rămas doar în stadiul de dezvoltare, deși motorul este capabil să se rotească pentru a indica unghiul de rotație pentru acordarea chitarei.

Concluzii

Realizarea proiectului a fost plăcută și distractivă, puțin frustrantă uneori, mai ales din cauza problemelor cauzate de precizia microfonului și de cuplul motorului. Cheltuielile sunt în jurul a 200 de RON, deși încă nu a fost făcut bugetul final.

Download

Codul sursă este disponibil în această arhivă, împreună cu bootloader-ul.

Automatic Guitar Tuner

Jurnal

  • 20.04.2019 - Tema proiectului, lista de piese și schema bloc (Milestone 1)
  • 24.04.2019 - Placa de bază (Milestone 2)
  • 04.05.2019 - Schema electrică a proiectului (Milestone 3)
  • 10.05.2019 - Realizarea completă a părții Hardware
  • 19.05.2019 - Realizarea completă a părții Software
  • 21.05.2019 - Terminarea proiectului și scurtă prezentare a acestuia la laborator
  • 24.05.2019 - Terminarea paginii de proiect și a documentației

Bibliografie/Resurse

Document PDF: Automatic Guitar Tuner

pm/prj2019/astratulat/ioan_florin.nitu.txt · Last modified: 2021/04/14 17:07 (external edit)
CC Attribution-Share Alike 3.0 Unported
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0