Autorul poate fi contactat la adresa: Login pentru adresa
Proiectul meu este un tuner pentru chitara (de orice tip). Tuner-ul functioneaza astfel:
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:
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
.
Programul poate fi impartit in urmatoarele module:
Practic, modulele interactioneaza precum in schema urmatoare:
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, "");
chosen_string
, care retine indexul notei selectate.
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.
Din cauza circuitului de preamplificare, tuner-ul nu functioneaza cu foarte mare acuratete. Dar, totusi, functioneaza
Linux Mint 17.1
, dar nu a vrut sa o vada nicicum, ce sa mai zic de scris cod. Am trecut la un alt laptop, care avea si Linux si Windows. Pe aceeasi versiune de Linux, imi vedea placuta, dar nu puteam sa scriu cod. Pe Windows 7
, in schimb, mi-a vazut placuta si a mers sa o si programez. In cele din urma, am incercat si un al treilea laptop, care tot Linux Mint 17.1
avea pe el si … surpriza, a mers bine totul. Concluzie: a treia e cu noroc;
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