Table of Contents

Georgiana-Diana CIOCÎRDEL - Tuner pentru chitara

Autorul poate fi contactat la adresa: Login pentru adresa

Introducere

Proiectul meu este un tuner pentru chitara (de orice tip). Tuner-ul functioneaza astfel:

Descriere generală

Logica tuner-ului poate fi descrisa prin urmatoarea schema bloc:

Hardware Design

Lista de materiale necesare realizarii proiectului:

Denumire Cantitate
LCD care respecta standardul Hitachi 44780 1
Rezistente 10K 2
Rezistente 100K 1
Microfon capsula 1
Tranzistor 2N3904 1
Condensator 0.1 uF 2
Protoboard 1
Pini mama 16
Pini tata 20 (ajung si 19)
Cablu UTP cateva fire din interior
Fire cu pini mama-mama 3

Schema electrica ce include LCD-ul conectat la ATMEGA324, precum si circuitul de preamplificare, conectat la pinii de ADC ai microcontroller-ului este urmatoarea:

Software Design

Pentru dezvoltarea codului, am lucrat initial pe Windows si apoi pe Linux. Pentru Windows, am instalat pachetul avr-gcc si am folosit (in lipsa de altceva) Programmer's Notepad (este, totusi, mai okay decat gvim). Pentru Linux am instalat, de asemenea avr-gcc, dar, din fericire, Linux are vim 8-).

Module software

Programul poate fi impartit in urmatoarele module:

Practic, modulele interactioneaza precum in schema urmatoare:

Selectia unei note

Pentru interfatarea LCD-ului m-am folosit de API-ul pus la dispozitie in laboratorul 1. La pornirea aplicatiei, utilizatorul are posibilitatea de a selecta nota pe care doreste sa o testeze.

Acest lucru se face prin:

#define E  164.81                                                               
#define A  220.00                                                               
#define D  293.66                                                               
#define G  391.99                                                               
#define B  493.88                                                               
#define EH 659.26
/******************************************************************************/
/* LCD specific stuff. */                                                       
#define FST_LINE_FST_CHAR 0x00                                                  
#define SND_LINE_FST_CHAR 0x40                                                  
#define EMPTY_LINE "                "                                           
/******************************************************************************/
LCD_printAt (FST_LINE_FST_CHAR + chosen_string * 3, "");

Detalii de implementare tuner

Ideea de preluare si prelucrare a input-ului de la circuitul de preamplificare este asemanatoare cu cea descrisa aici: http://www.myplace.nu/avr/gtuner/index.htm, desigur, cu unele modificari. Iesirea circuitului de preamplificare este legata pe portul B, pinul PB7 si este setata ca input pentru ATMEGA.

void input_init (void) {                                                        
    DDRB &= ~(1 << PB7);                                                        
    PCICR |= (1 << PCIE1);                                                      
    PCMSK1 |= (1 << PCINT15);                                                   
}

Tensiunea de la pin este citita ca 0 sau 1 logic, in functie de tensiune. Un semnal 1 logic va activa o intrerupere, unde se incrementeaza un contor.

ISR (PCINT1_vect) {                                                             
    if ((PINB & (1 << PB7)) == 0) {                                             
        /* If there is a low-high transition */                                 
        count_down_up++;                                                        
    }                                                                           
} 

In program, este initializat un timer, cu urmatoarele proprietati: prescaler = 256, tip CTC, TOP = OCR1A = 31 250. Practic, frecventa lui este de 2Hz, deci expira o data la 0.5s.

void timer1_init (void) {                                                       
    TCCR1B |= (1 << CS12) | /* Prescaler = 256 */                               
              (1 << WGM12); /* Clear on compare, TOP = OCR1A */                 
    TIMSK1 |= ( 1<< OCIE1A);                                                    
    OCR1A = 31250; /* TOP */                                                    
}

La expirarea timer-ului, se trateaza rutina de intrerupere. Se asteapta un numar de 3 intreruperi pentru a calcula o medie a numarului de treceri LOW-HIGH a semnalului receptionat. Daca inmultim valoarea obtinuta cu 2, se obtine frecventa semnalului. Aceasta se compara cu frecvente standard pentru note muzicale:

/* Two times the standard guitar guitar tunings as per                          
 * http://en.wikipedia.org/wiki/Guitar_tunings#Standard */                      
float std_fr[] = {164.81, 220.00, 293.66, 391.99, 493.88, 659.26};              
char *str_std_fr[] = {"E  ", "A  ", "D  ", "G  ", "B ", "EH"};

Se calculeaza procentul cu care difera nota emisa fata de nota dorita (in mod absolut), dupa care se afiseaza pe ecranul LCD-ului.

Rezultate Obţinute

Din cauza circuitului de preamplificare, tuner-ul nu functioneaza cu foarte mare acuratete. Dar, totusi, functioneaza =)

Concluzii

Download

Arhiva cu proiectul contine biblioteca LCD (lcd.c si lcd.h), precum si fisierul sursa main.c si fisierul Makefile: georgianaciocirdel_334cc_proiectpm.zip

Am folosit Gitlab pentru versionare, pentru ca am schimbat de cateva ori implementarea tuner-ului (initial folosisem ADC, dar, ulterior, mi-am dat seama ca este mai simplu cu un pin oarecare de input). Codul se gaseste aici: https://gitlab.cs.pub.ro/georgiana.ciocirdel/pm-proiect

Jurnal

Bibliografie/Resurse