This shows you the differences between two versions of the page.
|
pm:prj2025:ccristi:agavrilut [2025/05/25 22:35] agavrilut [Decizii și detalii de implementare] |
pm:prj2025:ccristi:agavrilut [2025/05/28 02:34] (current) agavrilut [Aplicația MiniSynth Recorder] |
||
|---|---|---|---|
| Line 41: | Line 41: | ||
| * Apăsarea celor 8 butoane pentru a reda note muzicale, folosind buzzer-ul pasiv | * Apăsarea celor 8 butoane pentru a reda note muzicale, folosind buzzer-ul pasiv | ||
| * Ajustarea frecvenței notelor prin rotirea potențiometrului | * Ajustarea frecvenței notelor prin rotirea potențiometrului | ||
| - | * În poziția minimă a potențiometrului, sunt redate notele din gama C4-C5, iar prin rotirea acestuia spre dreapta, frecvențele cresc gradual | + | * În poziția minimă a potențiometrului, sunt redate notele din gama C4-C5, iar prin rotirea acestuia spre dreapta, frecvențele cresc gradual, până la C5-C6 |
| 2. **//Modul record//** | 2. **//Modul record//** | ||
| Line 112: | Line 112: | ||
| | Buzzer | D10 | PB2 (OC1B) | Ieșire PWM pe Timer1 | | | Buzzer | D10 | PB2 (OC1B) | Ieșire PWM pe Timer1 | | ||
| | HC-05 STATE | D13 | PB5 | Indică starea conexiunii Bluetooth | | | HC-05 STATE | D13 | PB5 | Indică starea conexiunii Bluetooth | | ||
| - | | HC-05 RXD | TX0 | PD1 | Comunicare UART (USART0), Arduino->HC-05, conectat prin divizor de tensiune (2kΩ și 1kΩ) | | + | | HC-05 RXD | TX0 | PD1 | Comunicare UART (USART0), Arduino->HC-05, conectat prin divizor de tensiune (2kΩ și 1kΩ), pentru că pinul RXD funcționează la 3.3V | |
| | HC-05 TXD | RX0 | PD0 | Comunicare UART (USART0), HC-05->Arduino | | | HC-05 TXD | RX0 | PD0 | Comunicare UART (USART0), HC-05->Arduino | | ||
| ==== Imagini ==== | ==== Imagini ==== | ||
| + | |||
| + | {{:pm:prj2025:ccristi:whatsapp_image_2025-05-28_at_00.50.06_ffb0866b.jpg?nolink&600|}} | ||
| Inițial am conectat pinii RX și TX de pe HC-05 la D11 și D12, în ideea de a folosi SoftwareSerial. Ulterior i-am mutat pe TX1 și RX0 și am renunțat complet la bibliotecile Arduino. | Inițial am conectat pinii RX și TX de pe HC-05 la D11 și D12, în ideea de a folosi SoftwareSerial. Ulterior i-am mutat pe TX1 și RX0 și am renunțat complet la bibliotecile Arduino. | ||
| Line 138: | Line 140: | ||
| **''main.cpp''** | **''main.cpp''** | ||
| - | Fișierul principal conține funcția ''setup()'' și bucla ''while(1)'', în care sunt apelate funcțiile de actualizare: | + | Fișierul principal conține funcția ''setup()'' și bucla ''while(1)'', în care sunt apelate funcțiile de actualizare |
| - | * ''update_bt_state()'' – verifică dacă modulul HC-05 este conectat, controlează LED-ul albastru și dezactivează modul record în caz de deconectare | + | * ''update_bt_state()'': verifică dacă modulul HC-05 este conectat, controlează LED-ul albastru și dezactivează modul record în caz de deconectare |
| - | * ''update_notes()'' – detectează apăsarea butoanelor, aplică pitch shift în funcție de potențiometru, redă nota pe buzzer și trimite mesaje seriale dacă înregistrarea e activă | + | * ''update_notes()'': detectează apăsarea butoanelor, aplică pitch shift în funcție de potențiometru, redă nota pe buzzer și trimite mesaje seriale dacă înregistrarea e activă |
| - | * ''update_rec_mode()'' – comută între modurile normal și record la apăsarea butonului de înregistrare, controlează LED-ul roșu și trimite serial mesaje de control | + | * ''update_rec_mode()'': comută între modurile normal și record la apăsarea butonului de înregistrare, controlează LED-ul roșu și trimite serial mesaje de control |
| **''io_utils.h''** | **''io_utils.h''** | ||
| - | Funcții pentru configurarea pinilor, folosind structura ''IOPin'', care conține toate registrele asociate unui pin: | + | Funcții pentru configurarea pinilor, folosind structura ''IOPin'', care conține toate registrele asociate unui pin |
| - | * ''conf_input(IOPin)'' – setează pinul ca intrare | + | * ''conf_input(IOPin)'': setează pinul ca intrare |
| - | * ''conf_input_pullup(IOPin)'' – configurare ca intrare cu rezistor de pull-up activ | + | * ''conf_input_pullup(IOPin)'': configurare ca intrare cu rezistor de pull-up activ |
| - | * ''conf_output(IOPin)'' – setează pinul ca ieșire | + | * ''conf_output(IOPin)'': setează pinul ca ieșire |
| - | * ''read_pin(IOPin)'' – returnează starea pinului | + | * ''read_pin(IOPin)'': returnează starea pinului |
| - | * ''set_pin_high(IOPin)'' / ''set_pin_low(IOPin)'' – controlează nivelul logic pe pin | + | * ''set_pin_high(IOPin)''/''set_pin_low(IOPin)'': controlează nivelul logic pe pin |
| **''buzzer.h''** | **''buzzer.h''** | ||
| - | Controlul buzzer-ului prin PWM, folosind Timer1: | + | Controlul buzzer-ului prin PWM, folosind Timer1 |
| - | * ''buzzer_init()'' – configurează Timer1 în modul Fast PWM, cu top în ICR1 și ieșire pe pinul OC1B (PB2) | + | * ''buzzer_init()'': configurează Timer1 în modul Fast PWM, cu top în ICR1 și ieșire pe pinul OC1B (PB2) |
| - | * ''play_note(frequency)'' – calculează valoarea pentru ICR1 în funcție de frecvența dată, activează pinul OC1B și configurează semnalul PWM | + | * ''play_note(frequency)'': calculează valoarea pentru ICR1 în funcție de frecvența dată, activează pinul OC1B și configurează semnalul PWM |
| - | * ''stop_note()'' – dezactivează PWM, setează pinul pe LOW și apoi pe input pentru a opri complet sunetul | + | * ''stop_note()'': dezactivează PWM, setează pinul pe LOW și apoi pe input pentru a opri complet sunetul |
| **''adc_pot.h''** | **''adc_pot.h''** | ||
| - | Citirea valorii de la potențiometru prin ADC0: | + | Citirea valorii de la potențiometru prin ADC0 |
| - | * ''adc_init()'' – inițializează perifericul ADC | + | * ''adc_init()'': inițializează perifericul ADC |
| - | * ''read_pot_value()'' – returnează valoarea potențiometrului mapată în intervalul 0.0–12.0, folosită pentru calculul pitch shift | + | * ''read_pot_value()'': returnează valoarea potențiometrului mapată în intervalul 0.0–12.0, folosită pentru calculul pitch shift |
| **''timer.h''** | **''timer.h''** | ||
| - | Folosește Timer0 pentru funcții asemănătoare cu Arduino: | + | Folosește Timer0 pentru funcții asemănătoare cu Arduino |
| - | * ''timer0_init()'' – configurează Timer0 în mod CTC, cu întrerupere pe compare match A | + | * ''timer0_init()'': configurează Timer0 în mod CTC, cu întrerupere pe compare match A |
| - | * ''_millis()'' – returnează timpul scurs în milisecunde, folosit pentru debounce și timestamp-uri | + | * ''_millis()'': returnează timpul scurs în milisecunde, folosit pentru debounce și timestamp-uri |
| - | * ''_delay(ms)'' – întârziere software folosind ''_millis()'' | + | * ''_delay(ms)'': întârziere software folosind ''_millis()'' |
| **''usart.h''** | **''usart.h''** | ||
| - | Comunicare serială cu modulul HC-05: | + | Comunicare serială cu modulul HC-05 |
| - | * ''usart0_init(ubrr)'' – inițializează USART0 cu baud 9600, format 8N1 | + | * ''usart0_init(ubrr)'': inițializează USART0 cu baud 9600, format 8N1 |
| - | * ''usart0_print(str)'' – transmite un șir de caractere prin USART, folosește ''usart0_transmit(character)'', pentru a trasmite câte un caracter | + | * ''usart0_print(str)'': transmite un șir de caractere prin USART, folosește ''usart0_transmit(character)'', pentru a trasmite câte un caracter |
| ==== Decizii și detalii de implementare ==== | ==== Decizii și detalii de implementare ==== | ||
| Line 285: | Line 287: | ||
| Permite conectarea la dispozitiv prin port serial și înregistrarea notelor transmise în timp real. | Permite conectarea la dispozitiv prin port serial și înregistrarea notelor transmise în timp real. | ||
| + | |||
| + | {{:pm:prj2025:ccristi:screenshot_2025-05-28_005653.png?nolink&500|}} | ||
| * **Port name** – câmp text pentru introducerea portului serial (ex: ''COM11'', ''/dev/ttyUSB0'') | * **Port name** – câmp text pentru introducerea portului serial (ex: ''COM11'', ''/dev/ttyUSB0'') | ||
| Line 292: | Line 296: | ||
| * **Start Recording/Stop Recording** – pornește sau oprește înregistrarea | * **Start Recording/Stop Recording** – pornește sau oprește înregistrarea | ||
| * Înregistrarea se oprește automat și la primirea mesajului ''RECORD_OFF'' de la dispozitiv | * Înregistrarea se oprește automat și la primirea mesajului ''RECORD_OFF'' de la dispozitiv | ||
| - | * După oprirea înregistrării, aplicația procesează datele și le salvează într-un fișier ''.mid'' | + | * După oprirea înregistrării, aplicația procesează datele și le salvează într-un fișier ''.mid'', în folderul ''recordings'' |
| **2. View Recordings** | **2. View Recordings** | ||
| Afișează toate melodiile înregistrate și permite redarea sau ștergerea acestora. | Afișează toate melodiile înregistrate și permite redarea sau ștergerea acestora. | ||
| + | |||
| + | {{:pm:prj2025:ccristi:screenshot_2025-05-28_005720.png?nolink&500|}} | ||
| * **Listă de înregistrări** – scrollable, afișează toate fișierele MIDI salvate | * **Listă de înregistrări** – scrollable, afișează toate fișierele MIDI salvate | ||
| Line 303: | Line 309: | ||
| * **Play/Stop** – redă melodia selectată sau oprește redarea | * **Play/Stop** – redă melodia selectată sau oprește redarea | ||
| * **Delete** – șterge fișierul selectat | * **Delete** – șterge fișierul selectat | ||
| + | |||
| + | |||
| + | ==== Testare ==== | ||
| + | |||
| + | Am testat funcționalitățile incremental, pe măsură ce le-am implementat, prin observarea comportamentului așteptat sau prin afișarea valorilor prin serial monitor, unde era necesar. | ||
| + | * Apăsare butoane - afișarea frecvenței corespunzătoare | ||
| + | * Debounce - se afișează un singur mesaj la fiecare apăsare | ||
| + | * Buzzer - redarea corectă a frecvențelor | ||
| + | * Pitch shift - afișarea valorii citite de la potențiometru, apoi afișarea frecvențelor ajustate și redarea acestora | ||
| + | * am verificat că frecvențele calculate corespund cu tabelul de frecvențe ale notelor (de exemplu, la poziția maximă, am verificat că frecvențele corespund gamei C5-C6) | ||
| + | * Activare/dezactivare mod record - testat vizual (LED) și prin verificarea mesajelor trimise | ||
| + | * Comunicația Bluetooth - testată inițial cu un script care doar citește și afișează mesajele în terminal, ulterior cu aplicația implementată | ||
| + | * am testat apoi cazurile speciale: se încearcă înregistrarea fără conexiune, se întrerupe conexiunea în timpul înregistrării | ||
| + | * Aplicația Python - am implementat și testat pe rând conectarea, citirea mesajelor (prin afișare în terminal), crearea fișierelor MIDI (testate prin redare cu un player și prin analiza notelor într-un software dedicat), redarea înregistrărilor | ||
| + | * am testat cazurile speciale, ex: note fără ''note_off'', actualizarea interfeței la oprirea înregistrării de către dispozitiv (prin ''RECORD_OFF'') etc. | ||
| ===== Rezultate Obţinute ===== | ===== Rezultate Obţinute ===== | ||
| - | <note tip> | + | [[https://youtu.be/qJW-3LLUZFE|Demo]]: |
| - | Care au fost rezultatele obţinute în urma realizării proiectului vostru. | + | |
| - | </note> | + | |
| + | <HTML><iframe width="560" height="315" src="//www.youtube.com/embed/qJW-3LLUZFE" frameborder="0" allowfullscreen></iframe></HTML> | ||
| + | |||
| + | {{:pm:prj2025:ccristi:whatsapp_image_2025-05-28_at_00.50.06_043a05d0.jpg?nolink&500|}} | ||
| + | |||
| + | {{:pm:prj2025:ccristi:whatsapp_image_2025-05-28_at_00.50.06_72c42e1a.jpg?nolink&500|}} | ||
| ===== Concluzii ===== | ===== Concluzii ===== | ||
| + | |||
| + | Proiectul m-a ajutat să înțeleg mai bine conceptele studiate în cadrul laboratoarelor, prin aplicarea practică a noțiunilor de GPIO, UART, PWM, ADC și timere. | ||
| + | |||
| + | În plus, proiectul mi-a oferit ocazia să învăț noțiuni noi despre formatul MIDI și modul în care se procesează digital muzica, de la conversia frecvențelor în note până la generarea și redarea fișierelor MIDI. | ||
| + | |||
| + | |||
| ===== Download ===== | ===== Download ===== | ||
| - | Firmware: {{:pm:prj2025:ccristi:mini-synth-firmware.zip|}} | + | Cod microcontroller: {{:pm:prj2025:ccristi:mini-synth-firmware.zip|}} |
| Recorder Python: {{:pm:prj2025:ccristi:mini-synth-recorder.zip|}} | Recorder Python: {{:pm:prj2025:ccristi:mini-synth-recorder.zip|}} | ||
| Line 326: | Line 356: | ||
| Resurse hardware: | Resurse hardware: | ||
| - | * [[https://ww1.microchip.com/downloads/en/DeviceDoc/Atmel-7810-Automotive-Microcontrollers-ATmega328P_Datasheet.pdf|Datasheet Atmega328P]] | + | * Datasheet ATmega328P: [[https://ww1.microchip.com/downloads/en/DeviceDoc/Atmel-7810-Automotive-Microcontrollers-ATmega328P_Datasheet.pdf|Microchip]] |
| - | * [[https://upload.wikimedia.org/wikipedia/commons/thumb/e/e4/Arduino-nano-pinout.png/1200px-Arduino-nano-pinout.png?20190717220831|Pinout Arduino Nano]] | + | * Pinout Arduino Nano: [[https://upload.wikimedia.org/wikipedia/commons/thumb/e/e4/Arduino-nano-pinout.png/1200px-Arduino-nano-pinout.png|Wikipedia]] |
| + | * Detalii funcționare HC-05 [[https://lastminuteengineers.com/hc05-bluetooth-arduino-tutorial/|Last Minute Engineers]] | ||
| + | |||
| + | Resurse software: | ||
| + | * Exemplu software debounce: [[https://digilent.com/reference/learn/microprocessor/tutorials/debouncing-via-software/start?srsltid=AfmBOopGY96OA4t9osU41cufoSORA-XfGQRbBblO_Mly4EVyrVYBwlT9|Digilent Reference]] | ||
| + | * Exemplu structură pin: [[https://www.avrfreaks.net/s/topic/a5C3l000000UZAwEAO/t149008?comment=P-1421885|AVR Freaks]] | ||
| + | * Frecvențe note muzicale: [[https://mixbutton.com/music-tools/frequency-and-pitch/music-note-to-frequency-chart|MixButton]] | ||
| + | * Formulă pitch shift: [[https://www.diva-portal.org/smash/get/diva2:1381398/FULLTEXT01.pdf|DiVA portal]] | ||
| + | |||
| + | |||
| + | Resurse aplicație Python: | ||
| + | |||
| + | * Documentație Mido: [[https://mido.readthedocs.io/en/stable/files/midi.html|mido.readthedocs.io]] | ||
| + | * Documentație pySerial: [[https://pyserial.readthedocs.io/en/latest/pyserial.html|pyserial.readthedocs.io]] | ||
| + | * Documentație Pygame GUI: [[https://pygame-gui.readthedocs.io/en/latest/index.html|pygame-gui.readthedocs.io]] | ||
| + | * Exemple Pygame GUI: [[https://github.com/MyreMylar/pygame_gui_examples|pygame_gui_examples (GitHub)]] | ||