This is an old revision of the document!
Proiectul presupune realizarea unui mini pian digital care poate schimba între mai multe tipuri de sunete: pian de concert, flaut, chitară, vioară. De asemenea, pianul trebuie să fie polifonic (permite redarea mai multor note în același timp).
Am vrut să creez un proiect pe o temă care mă interesează în mod deosebit, văzându-l ca o șansă de a aprofunda un subiect pe care nu l-aș fi abordat în mod normal. Îmi place să cânt la pian, dar nu am căutat până acum și nu m-am gândit la ce piese sunt în interior și cum duc la producerea sunetului.
Proiectul realizat în sine nu cred că este foarte util, fiind mult mai limitat în numărul de note și moduri în care poți să cânți decât un pian online care poate fi accesat cu foarte mare ușurință, dar poate fi o ocazie de descoperire a componentelor hardware și software care duc la redarea sunetelor unui pian.
Modulul Switch are un buton care controlează modul de sunet al pianului. Prin apăsarea lui, se ciclează între tipurile diferite de instrumente/sunete.
Modulul Keyboard cuprinde 8 butoane pentru cele 8 tonuri naturale, de bază ale pianului. Apăsarea lor va determina difuzorul să emită o notă muzicală.
Modulul SD Card presupune prezența unui SD Card Holder și al unui SD Card pe care sunt încărcate sample-uri de la diferite instrumente (note izolate) care vor fi cântate la apăsarea “clapei” corespunzătoare.
Modulul Speaker se referă la difuzorul prin intermediul căruia se vor emite sunetele la apăsarea butoanelor.
Descrierea codului aplicaţiei (firmware):
Implementarea constă în principal din codul pentru diferite întreruperi (butonul de switch, “clapele” și timer-ul pentru difuzor).
Întreruperea pentru butonul de switch presupune ca la apăsarea acestuia să se modifice starea lui, ciclând între 3 moduri: pian, flaut, vioară.
ISR(PCINT0_vect) { if ((PIND & (1 << Switch)) == 0) { // Increment currentWavType and wrap around if necessary switchState = (switchState + 1) % WAV_TYPE_COUNT; } }
Pentru clape, la apăsarea lor se dă play la audio-ul corespondent butonului și activează variabila soundEnabled care este folosită pentru redarea sunetului de către difuzor.
ISR(PCINT2_vect) { for (int i = 0; i < sizeof(buttonPins) / sizeof(buttonPins[0]); i++) { if ((PIND & (1 << buttonPins[i])) == 0) { // Button is pressed, play the corresponding WAV file if (switchState == 0) { playWavFile(pianoFiles[i]); } else if (switchState == 1) { playWavFile(fluteFiles[i]); } else if (switchState == 2) { playWavFile(violinFiles[i]); } soundEnabled = true; return; } } soundEnabled = false; }
Timer-ul difuzorului este de tipul Fast PWM și generează sunet atunci când primește semnal de la clape că una dintre ele este apăsată.
ISR(TIMER1_COMPA_vect) { if (soundEnabled) { // Generate sound PORTB |= (1 << PB1); } else { // Stop sound PORTB &= ~(1 << PB1); } }
Arhiva conține codul sursă și sample-urile de note.