This is an old revision of the document!
Absolut nicio petrecere nu scapa de melodiile anilor 2000. De ce? Pentru ca au un ritm anume, au acel vibe de discoteca, iti aduc aminte de anii in care erai copil, nu ai aveai griji, facultate si teme. In plus, mai greu gasesti melodii pe care sa le stie toata lumea sa se ridice de la masa, sa cante (cu tot sufletul) si sa danseze.
M-am gandit astfel ca daca tot vreau sa fac un player de muzica, sa fie totusi unul cat de cat autentic. Azi doar deschizi Spotify si te conectezi la boxa, inainte aveai nevoie de Cd, Cd player etc. Asa ca proiectul meu incearca sa aduca nostalgia anilor 2000 combinand tehnologia cu amintirea de a veni dupa tine cu casetofonul.
Astfel, player-ul realizat poate reda melodi in format mono, de pe un card SD
Nostalgia player-ul realizat are urmatoarele functii:
Pentru ca atmosfera sa fie si mai bine intretinuta, am adaugat si 2 LED-uri care pulseaza in ritmul melodiei.
Pe un ecran LCD vor fi afisate informatii despre:
Melodiile vor fi stocate pe un card SD si pentru a avea o calitate cat de cat decenta, vor avea urmatoarele specificatii:
Apasarea celor 6 butoane declanseaza intreruperi, pentru ca microprocesorul sa nu citeasca la fiecare loop starea butoanelor, care de cele mai multe ori nu se schimba.
Butoanele folosesc intreruperile:
Astfel folosesc functia interrupts_setup() pentru setarea directiei pinilor si pentru setarea tuturor intreruperilor.
void interrupts_setup() { cli(); // input pins DDRD &= ~(1 << PD5) & ~(1 << PD4) & ~(1 << PD6) & ~(1 << PD7) & ~(1 << PD2); DDRB &= ~(1 << PB0); // input pullup PORTD |= (1 << PD4) | (1 << PD5) | (1 << PD6) | (1 << PD7) | (1 << PD2); PORTB |= (1 << PB0); // external INTERRUPT EIMSK |= (1 << INT0); // Interrupt constrol register PCICR |= (1 << PCIE2) | (1 << PCIE0); // interrupt PIN CHANGE PCMSK2 |= (1 << PCINT20) | (1 << PCINT21) | (1 << PCINT22) | (1 << PCINT23); PCMSK0 |= (1 << PCINT0); // falling edge of INT0 EICRA |= (1 << ISC01); sei(); }
Iar rutinele de tratare a intreruperilor seteaza flag-uri de tip bool pentru fiecare actiune.
// button controls bools volatile bool next_press = false; volatile bool prev_press = false; volatile bool up_vol_press = false; volatile bool down_vol_press = false; volatile bool pause_press = false; volatile bool shuffle_press = false; // next button - PD2 - INT0 ISR(INT0_vect) { next_press = true; } // PCINT2: shuffle - PD4, prev - PD5, down - PD6, up - PD7 ISR(PCINT2_vect) { if ((PIND & (1 << PD4)) == 0) { shuffle_press = true; } else if ((PIND & (1 << PD5)) == 0) { prev_press = true; } else if ((PIND & (1 << PD6)) == 0) { up_vol_press = true; } else if ((PIND & (1 << PD7)) == 0) { down_vol_press = true; } } // PCINT0: pause/play - PB0 ISR(PCINT0_vect) { if ((PINB & (1 << PB0)) == 0) { pause_press = true; } }
Pentru a detecta corect apasarile butoanelor, pentru fiecare dintre butoane am aplicat o logica de debounce, care consta in numararea milisecundelor care au trecut de la ultima apasare. Daca numarul acestora este mai mic decat thresholdul ales (de 500ms) atunci detectarea apasarii a fost gresita si este ignorata (flagul corespunzator este setat pe false).
volatile unsigned long last_debounce = 0; volatile unsigned long current_millis = millis(); const unsigned long debounce_delay = 500; if (press_flag) { unsigned long current_millis = millis(); if (current_millis - last_debounce_next < debounce_delay) { press_flag = false; } else { // button was really pressed => do work } }
Pentru a reda melodiile de pe cardul SD, am folosit biblioteca TMRpcm.
Feature-uri ale bibliotecii: