This shows you the differences between two versions of the page.
|
pm:prj2026:bianca.popa1106:alexandru.diaconu [2026/05/09 22:12] alexandru.diaconu04 |
pm:prj2026:bianca.popa1106:alexandru.diaconu [2026/05/18 19:12] (current) alexandru.diaconu04 |
||
|---|---|---|---|
| Line 102: | Line 102: | ||
| | TBD | Testare și debugging | | | TBD | Testare și debugging | | ||
| | TBD | Demo final și documentație | | | TBD | Demo final și documentație | | ||
| + | |||
| + | ===== Software Design ===== | ||
| + | |||
| + | **Mediu de dezvoltare** | ||
| + | |||
| + | * IDE: Arduino IDE 2.3.8 | ||
| + | * Placă: Arduino Uno (ATmega328P) | ||
| + | * Limbaj: C / C++ | ||
| + | |||
| + | **Biblioteci third-party** | ||
| + | |||
| + | ^ Bibliotecă ^ Rol ^ | ||
| + | | Adafruit NeoPixel | Controlul benzii LED WS2812B adresabile | | ||
| + | | LiquidCrystal_I2C | Comunicare cu LCD 16x2 prin protocolul I2C | | ||
| + | | avr/interrupt.h | Gestionarea întreruperilor hardware INT0/INT1 (built-in AVR) | | ||
| + | | Wire.h | Suport I2C pentru comunicarea cu LCD (built-in Arduino) | | ||
| + | |||
| + | **Arhitectura sistemului** | ||
| + | |||
| + | Firmware-ul este structurat într-un singur fișier principal: | ||
| + | |||
| + | * ''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: | ||
| + | |||
| + | ^ Pin Arduino ^ Componentă ^ Rol ^ | ||
| + | | D2 (INT0) | Buton J1 | Întrerupere externă — apăsare jucător 1 | | ||
| + | | D3 (INT1) | Buton J2 | Întrerupere externă — apăsare jucător 2 | | ||
| + | | D4 | LED buton J1 | Iluminare buton jucător 1 | | ||
| + | | D5 | LED buton J2 | Iluminare buton jucător 2 | | ||
| + | | D6 | Bandă LED WS2812B (DIN) | Semnal date bandă LED | | ||
| + | | D11 (OC2A) | Buzzer pasiv | PWM Timer2 — generare sunete | | ||
| + | | A0 | Potențiometru 10kΩ | ADC — citire dificultate | | ||
| + | | A4 (SDA) | LCD I2C | Linie date I2C | | ||
| + | | A5 (SCL) | LCD I2C | Linie clock I2C | | ||
| + | |||
| + | **Detalii cheie de implementare** | ||
| + | |||
| + | //Î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. | ||
| + | |||
| + | 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). | ||
| + | |||
| + | Logica de mutare a LED-ului: | ||
| + | * ISR numără apăsările într-un contor | ||
| + | * Când contorul atinge valoarea de dificultate → LED-ul se mută o poziție | ||
| + | * Contorul se resetează la 0 | ||
| + | |||
| + | //Control buzzer prin PWM (Lab 3)// | ||
| + | |||
| + | 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 | ||
| + | |||
| + | Sunete generate: | ||
| + | * **400 Hz** — mutare spre J1 | ||
| + | * **600 Hz** — mutare spre J2 | ||
| + | * **Melodie Do-Re-Mi-Fa-Sol** — victorie rundă | ||
| + | |||
| + | //Citire potențiometru prin ADC (Lab 4)// | ||
| + | |||
| + | Potențiometrul este citit pe pinul A0 folosind ''analogRead()''. Valoarea de 10 biți (0–1023) este mapată la intervalul de dificultate 1–8 folosind funcția ''map()'': | ||
| + | |||
| + | <code cpp> | ||
| + | difficulty = map(analogRead(A0), 0, 1023, 1, 8); | ||
| + | </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. | ||
| + | |||
| + | //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ă. | ||
| + | |||
| + | **Funcții implementate** | ||
| + | |||
| + | ^ Funcție ^ Rol ^ | ||
| + | | ''setup()'' | Inițializează toate perifericele, configurează întreruperile, pornește jocul | | ||
| + | | ''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(INT1_vect)'' | Tratează apăsarea butonului J2 — debounce + mutare LED dreapta | | ||
| + | | ''afiseazaBanda()'' | Actualizează banda LED: zona J1 roșu, zona J2 albastru, LED activ alb | | ||
| + | | ''animatieVictorie()'' | Clipire bandă LED în culoarea câștigătorului | | ||
| + | | ''animatieStart()'' | Animație de intro la începerea rundei | | ||
| + | | ''buzzerOn()'' | Pornește buzzerul la frecvența specificată prin Timer2 CTC | | ||
| + | | ''buzzerOff()'' | Oprește buzzerul | | ||
| + | | ''beep()'' | Emite un sunet scurt la frecvența și durata specificate | | ||
| + | | ''melodieVictorie()'' | Redă melodia Do-Re-Mi-Fa-Sol la câștigarea rundei | | ||
| + | | ''citesteDificultate()'' | Citește ADC și returnează dificultatea 1–8 | | ||
| + | | ''afiseazaLCD()'' | Afișează scorul și cronometrul pe LCD prin I2C | | ||
| + | | ''afiseazaVictorieLCD()'' | Afișează mesajul de victorie a rundei pe LCD | | ||
| + | | ''verificaCastig()'' | Verifică dacă LED-ul a ajuns la capătul benzii | | ||
| + | | ''resetRunda()'' | Resetează pozițiile și contoarele pentru o rundă nouă | | ||
| + | | ''initIntreruperi()'' | Configurează registrele EICRA și EIMSK pentru INT0/INT1 | | ||
| ===== Bibliografie/Resurse ===== | ===== Bibliografie/Resurse ===== | ||