This shows you the differences between two versions of the page.
|
pm:prj2026:bianca.popa1106:alexandru.diaconu [2026/05/27 02:10] alexandru.diaconu04 [Download] |
pm:prj2026:bianca.popa1106:alexandru.diaconu [2026/05/27 03:37] (current) alexandru.diaconu04 [Software Design] |
||
|---|---|---|---|
| Line 97: | Line 97: | ||
| ^ Dată ^ Activitate ^ | ^ Dată ^ Activitate ^ | ||
| - | | Mai 2026 | Definirea conceptului, finalizarea listei de componente | | + | | 1 Mai 2026 | Definirea conceptului, finalizarea listei de componente | |
| - | | TBD | Primirea componentelor și asamblarea hardware | | + | | 4 Mai 2026 | Primirea componentelor și asamblarea hardware | |
| - | | TBD | Implementare software — întreruperi + control LED | | + | | 5 Mai 2026 | Implementare software — întreruperi + control LED | |
| - | | TBD | Implementare software — ADC, PWM, I2C | | + | | 6 Mai 2026 | Implementare software — ADC, PWM, I2C | |
| - | | TBD | Testare și debugging | | + | | 10 Mai 2026 | Testare și debugging | |
| - | | TBD | Demo final și documentație | | + | | 25 Mai 2026 | Demo final și documentație | |
| ===== Software Design ===== | ===== Software Design ===== | ||
| Line 110: | Line 110: | ||
| * PlatformIO (extensie VS Code) | * PlatformIO (extensie VS Code) | ||
| * Placă: Arduino Uno (ATmega328P) | * Placă: Arduino Uno (ATmega328P) | ||
| - | * Limbaj: C / C++ | + | * Limbaj: C++ |
| + | * Fișier principal: ''main.cpp'' | ||
| **Biblioteci third-party** | **Biblioteci third-party** | ||
| Line 122: | Line 123: | ||
| **Arhitectura sistemului** | **Arhitectura sistemului** | ||
| - | Firmware-ul este structurat într-un singur fișier principal: | + | Firmware-ul este structurat într-un singur fișier principal ''main.cpp''. Acesta inițializează toate perifericele (bandă LED, LCD, butoane, buzzer, potențiometru), configurează întreruperile hardware și gestionează logica principală în bucla ''loop()''. |
| - | + | ||
| - | * ''cyberpull.ino'' — punctul de intrare. Inițializează toate perifericele (bandă LED, LCD, butoane, buzzer, potențiometru), configurează întreruperile hardware, pornește jocul și gestionează logica principală în bucla ''loop()''. | + | |
| Pinout-ul complet: | Pinout-ul complet: | ||
| ^ Pin Arduino ^ Componentă ^ Rol ^ | ^ Pin Arduino ^ Componentă ^ Rol ^ | ||
| - | | D2 (INT0) | Buton J1 | Întrerupere externă — apăsare jucător 1 | | + | | D2 (INT0) | Buton J2 (alb) | Întrerupere externă — apăsare jucător 2 | |
| - | | D3 (INT1) | Buton J2 | Întrerupere externă — apăsare jucător 2 | | + | | D3 (INT1) | Buton J1 (roșu) | Întrerupere externă — apăsare jucător 1 | |
| - | | D4 | LED buton J1 | Iluminare buton jucător 1 | | + | | D4 | LED buton J2 (alb) | Iluminare buton jucător 2 | |
| - | | D5 | LED buton J2 | Iluminare buton jucător 2 | | + | | D5 | LED buton J1 (roșu) | Iluminare buton jucător 1 | |
| - | | D6 | Bandă LED WS2812B (DIN) | Semnal date bandă LED | | + | | D6 | Bandă LED WS2812B (DIN) | Semnal date bandă LED (prin rezistență 330Ω) | |
| - | | D11 (OC2A) | Buzzer pasiv | PWM Timer2 — generare sunete | | + | | D11 (OC2A) | Buzzer pasiv | Timer2 CTC — generare sunete | |
| - | | A0 | Potențiometru 10kΩ | ADC — citire dificultate | | + | | A0 | Potențiometru 10kΩ | ADC — citire dificultate 1–8 | |
| | A4 (SDA) | LCD I2C | Linie date I2C | | | A4 (SDA) | LCD I2C | Linie date I2C | | ||
| | A5 (SCL) | LCD I2C | Linie clock I2C | | | A5 (SCL) | LCD I2C | Linie clock I2C | | ||
| Line 143: | Line 142: | ||
| //Întreruperi hardware pentru butoane (Lab 2)// | //Întreruperi hardware pentru butoane (Lab 2)// | ||
| - | Butoanele jucătorilor sunt conectate pe pinii INT0 (D2) și INT1 (D3). La fiecare apăsare se declanșează automat rutinele ''ISR(INT0_vect)'' și ''ISR(INT1_vect)''. Aceasta garantează că nicio apăsare nu este pierdută, indiferent de ce face jucatorul în acel moment. | + | Butoanele jucătorilor sunt conectate pe pinii INT0 (D2) și INT1 (D3), configurate pe front descrescător (falling edge) prin registrele EICRA și EIMSK. La fiecare apăsare se declanșează automat rutinele ''ISR(INT0_vect)'' și ''ISR(INT1_vect)''. Aceasta garantează că nicio apăsare nu este pierdută, indiferent de ce face programul în acel moment. |
| - | Fiecare ISR implementează debouncing software cu o fereastră de 50ms — dacă două apăsări vin în mai puțin de 50ms, a doua este ignorată (zgomot mecanic al butonului). | + | Fiecare ISR implementează debouncing software cu o fereastră de 150ms — dacă două apăsări vin în mai puțin de 150ms, a doua este ignorată (zgomot mecanic al butonului). ISR-ul verifică și starea fizică a butonului cu ''digitalRead()'' pentru a ignora bouncing-ul la eliberare. |
| Logica de mutare a LED-ului: | Logica de mutare a LED-ului: | ||
| Line 152: | Line 151: | ||
| * Contorul se resetează la 0 | * Contorul se resetează la 0 | ||
| - | //Control buzzer prin PWM (Lab 3)// | + | //Control buzzer prin Timer2 CTC (Lab 3)// |
| Buzzerul pasiv este controlat de Timer2 în modul CTC pe pinul D11 (OC2A). Frecvența sunetului se calculează după formula: | Buzzerul pasiv este controlat de Timer2 în modul CTC pe pinul D11 (OC2A). Frecvența sunetului se calculează după formula: | ||
| - | OCR2A = F_CPU / (2 × 64 × frecvență) − 1 | + | OCR2A = F_CPU / (2 × 256 × frecvență) − 1 |
| - | Sunete generate: | + | Prescaler-ul folosit este 256. Sunete generate: |
| * **400 Hz** — mutare spre J1 | * **400 Hz** — mutare spre J1 | ||
| * **600 Hz** — mutare spre J2 | * **600 Hz** — mutare spre J2 | ||
| - | * **Melodie Do-Re-Mi-Fa-Sol** — victorie rundă | + | * **300→500→700 Hz** — start rundă |
| + | * **Melodie Do-Re-Mi-Fa-Sol (262–392 Hz)** — victorie meci | ||
| //Citire potențiometru prin ADC (Lab 4)// | //Citire potențiometru prin ADC (Lab 4)// | ||
| Line 171: | Line 171: | ||
| </code> | </code> | ||
| - | Dificultatea reprezintă numărul de apăsări necesare pentru a muta LED-ul o poziție. La dificultate 1 fiecare apăsare mută LED-ul, la dificultate 8 sunt necesare 8 apăsări. | + | Dificultatea reprezintă numărul de apăsări necesare pentru a muta LED-ul o poziție. La dificultate 1 fiecare apăsare mută LED-ul, la dificultate 8 sunt necesare 8 apăsări. Valoarea este recitită la fiecare iterație a ''loop()'', deci se poate modifica în timp real. |
| //Comunicare LCD prin I2C (Lab 6)// | //Comunicare LCD prin I2C (Lab 6)// | ||
| - | LCD-ul 16x2 cu modulul PCF8574 comunică prin protocolul I2C pe pinii A4 (SDA) și A5 (SCL), la adresa ''0x27''. Display-ul se actualizează la fiecare 500ms cu scorul curent și timpul scurs din rundă. | + | LCD-ul 16x2 cu modulul PCF8574 comunică prin protocolul I2C pe pinii A4 (SDA) și A5 (SCL), la adresa ''0x27''. Display-ul se actualizează la fiecare 500ms cu scorul curent, timpul scurs din rundă și dificultatea curentă. |
| **Funcții implementate** | **Funcții implementate** | ||
| Line 182: | Line 182: | ||
| | ''setup()'' | Inițializează toate perifericele, configurează întreruperile, pornește jocul | | | ''setup()'' | Inițializează toate perifericele, configurează întreruperile, pornește jocul | | ||
| | ''loop()'' | Bucla principală: citește ADC, actualizează LED și LCD, verifică câștig | | | ''loop()'' | Bucla principală: citește ADC, actualizează LED și LCD, verifică câștig | | ||
| - | | ''ISR(INT0_vect)'' | Tratează apăsarea butonului J1 — debounce + mutare LED stânga | | + | | ''ISR(INT0_vect)'' | Tratează apăsarea butonului alb (J2) — debounce 150ms + mutare LED spre dreapta | |
| - | | ''ISR(INT1_vect)'' | Tratează apăsarea butonului J2 — debounce + mutare LED dreapta | | + | | ''ISR(INT1_vect)'' | Tratează apăsarea butonului roșu (J1) — debounce 150ms + mutare LED spre stânga | |
| - | | ''afiseazaBanda()'' | Actualizează banda LED: zona J1 roșu, zona J2 albastru, LED activ alb | | + | | ''showStrip()'' | Actualizează banda LED: zona J1 albastru, zona J2 roșu, bila albă | |
| - | | ''animatieVictorie()'' | Clipire bandă LED în culoarea câștigătorului | | + | | ''flashStrip()'' | Clipire bandă LED în culoarea câștigătorului | |
| - | | ''animatieStart()'' | Animație de intro la începerea rundei | | + | | ''startAnimation()'' | Animație sweep alb la pornirea jocului | |
| | ''buzzerOn()'' | Pornește buzzerul la frecvența specificată prin Timer2 CTC | | | ''buzzerOn()'' | Pornește buzzerul la frecvența specificată prin Timer2 CTC | | ||
| | ''buzzerOff()'' | Oprește buzzerul | | | ''buzzerOff()'' | Oprește buzzerul | | ||
| - | | ''beep()'' | Emite un sunet scurt la frecvența și durata specificate | | + | | ''playTone()'' | Emite un sunet la frecvența și durata specificate | |
| - | | ''melodieVictorie()'' | Redă melodia Do-Re-Mi-Fa-Sol la câștigarea rundei | | + | | ''playMoveJ1Sound()'' | Sunet la mutarea LED-ului spre J1 (400Hz) | |
| - | | ''citesteDificultate()'' | Citește ADC și returnează dificultatea 1–8 | | + | | ''playMoveJ2Sound()'' | Sunet la mutarea LED-ului spre J2 (600Hz) | |
| - | | ''afiseazaLCD()'' | Afișează scorul și cronometrul pe LCD prin I2C | | + | | ''playRoundStart()'' | Sunet de start rundă: 300→500→700Hz | |
| - | | ''afiseazaVictorieLCD()'' | Afișează mesajul de victorie a rundei pe LCD | | + | | ''playRoundWin()'' | Sunet la câștigarea unei runde | |
| - | | ''verificaCastig()'' | Verifică dacă LED-ul a ajuns la capătul benzii | | + | | ''playVictory()'' | Redă melodia Do-Re-Mi-Fa-Sol la câștigarea meciului | |
| - | | ''resetRunda()'' | Resetează pozițiile și contoarele pentru o rundă nouă | | + | | ''updateLCDScore()'' | Afișează scorul, cronometrul și dificultatea pe LCD prin I2C | |
| - | | ''initIntreruperi()'' | Configurează registrele EICRA și EIMSK pentru INT0/INT1 | | + | | ''checkWin()'' | Verifică dacă bila a ajuns la capătul benzii și actualizează scorul | |
| + | | ''startRound()'' | Resetează pozițiile și contoarele pentru o rundă nouă | | ||
| + | | ''checkReset()'' | Verifică dacă ambele butoane sunt ținute 500ms pentru reset joc | | ||
| ===== Bibliografie/Resurse ===== | ===== Bibliografie/Resurse ===== | ||