This shows you the differences between two versions of the page.
pm:prj2025:ajipa:bianca.pintilie [2025/05/27 03:07] bianca.pintilie |
pm:prj2025:ajipa:bianca.pintilie [2025/05/27 05:06] (current) bianca.pintilie [Rezultate Obţinute] |
||
---|---|---|---|
Line 120: | Line 120: | ||
* **mișcarea păsării** - în jocul de bază, ca să ții pasărea într-o anumită poziție trebuia să apeși continuu pe ecran, aplicându-se legile gravitației, însă în versiunea mea, prin mișcarea joystick-ului în sus și în jos, nu doar că se duce în acea poziție, dar și rămâne acolo, fără a mai fi nevoie de interacțiunea jucătorului | * **mișcarea păsării** - în jocul de bază, ca să ții pasărea într-o anumită poziție trebuia să apeși continuu pe ecran, aplicându-se legile gravitației, însă în versiunea mea, prin mișcarea joystick-ului în sus și în jos, nu doar că se duce în acea poziție, dar și rămâne acolo, fără a mai fi nevoie de interacțiunea jucătorului | ||
- | {{:pm:prj2025:ajipa:input_joystick.png?300|}} | + | * **oprirea/repornirea jocului** - în versiunea originală, odată ce ai început jocul nu te mai poți opri decât dacă pierzi, în schimb jocul meu oferă opțiunea de a-l pune pe pauză și de a-l reporni prin apăsarea unui simplu buton |
- | {{:pm:prj2025:ajipa:miscarea_pasarii.png?300|}} | + | * **LED-uri** - în implementarea proiectului am adăugat două LED-uri care îi arată jucătorului dacă este în timpul jocului (un LED verde se aprinde și stinge continuu) sau în afara lui (un LED roșu se aprinde și stinge continuu) |
- | * **oprirea/repornirea jocului** - în versiunea originală, odată ce ai început jocul nu te mai poți opri decât dacă pierzi, în schimb jocul meu oferă opțiunea de a-l pune pe pauză și de a-l reporni prin apăsarea unui simplu buton | + | **Funcționalități laborator** |
- | {{:pm:prj2025:ajipa:isr.png?400|}} | + | * **Întreruperi** |
- | * **LED-uri** - în implementarea proiectului am adăugat două LED-uri care îi arată jucătorului dacă este în timpul jocului (un LED verde se aprinde și stinge continuu) sau în afara lui (un LED roșu se aprinde și stinge continuu) | + | Am configurat butoanele conectate la pinul PD2, respectiv PD4, ca intrări și le-am activat rezistențele de pull-up. În cazul butonului de pe pinul PD2, i-am activat întreruperea externă care va avea loc pe falling edge pentru a gestiona schimbările de stare în joc: |
+ | * dacă game_state este 0, jocul începe, resetând scorul și fundalul | ||
+ | * dacă game_state este 4, trece la actualizarea tabelului de highscore | ||
+ | * în alte cazuri, schimbă între start și pauză | ||
+ | * de asemenea, resetează starea LED-urilor și valorile PWM asociate. | ||
+ | |||
+ | {{:pm:prj2025:ajipa:setup_butoane.png?600|}} | ||
+ | |||
+ | {{:pm:prj2025:ajipa:isr.png?500|}} | ||
+ | |||
+ | * **PWM** | ||
+ | |||
+ | Am configurat pinii PD5 și PD6 ca ieșiri PWM pentru controlul LED-urilor, utilizând modul Fast PWM cu un prescaler de 64. | ||
+ | |||
+ | Funcția **fade_leds**: | ||
+ | * controlează luminozitatea LED-urilor roșu (PD5) și verde (PD6) prin variarea graduală a valorii de umplere (duty cycle) între 0 și 255 | ||
+ | * cât timp jocul rulează (game_state = 1) LED-ul verde este activ, iar în restul de cazuri (în meniul principal, în meniul de highscore, când jocul este pe pauză, când jocul s-a încheiat) LED-ul roșu este activ | ||
+ | * creșterea și descreșterea valorilor din OCR0A și OCR0B simulează un efect de fade (aprindere/stingere graduală) | ||
+ | |||
+ | {{:pm:prj2025:ajipa:setup_leduri.png?700|}} | ||
{{:pm:prj2025:ajipa:functie_leduri.png?300|}} | {{:pm:prj2025:ajipa:functie_leduri.png?300|}} | ||
- | /* TODO (de completat): | + | **Alte funcționalități:** |
- | - utilizare instructiuni AVR in C (buton, PWM, pini) | + | |
- | - bucati de cod | + | * **UART** |
- | - calibrare joystick | + | În cod, folosesc UART pentru a primi un nume de la utilizator printr-o conexiune serială. |
- | - optimizari | + | |
- | */ | + | Procesul se desfășoară astfel: |
+ | * atunci când jocul este în starea game_state = 5 (salvare highscore), programul intră într-o buclă în care așteaptă date de la tastatură prin portul serial | ||
+ | * după ce datele sunt disponibile, folosesc funcția Serial.readStringUntil() pentru a citi numele jucătorului introdus de la tastatura laptop-ului | ||
+ | * numele citit îl utilizez pentru a actualiza tabela de highscore (names[] și scores[]), apelând funcția update_highscore() | ||
+ | * funcția update_highscore() caută poziția unde trebuie adăugat noul scor, apoi mută celelalte scoruri pentru a-i face loc astfel încât să fie în ordine descrescătoare | ||
+ | |||
+ | {{:pm:prj2025:ajipa:uart.png?400|}} | ||
+ | |||
+ | {{:pm:prj2025:ajipa:update_highscore.png?500|}} | ||
+ | |||
+ | ***ADC** | ||
+ | |||
+ | Folosesc Convertorul Analog-Digital pentru a citi poziția joystick-ului, astfel modificând poziția păsării: | ||
+ | * am configurat pinul A1 ca intrare pentru a citi semnalul analogic de la joystick | ||
+ | * utilizez funcția analogRead(A1) pentru a converti tensiunea de pe pinul A1 într-o valoare între 0 și 1023 (această valoare reprezintă poziția joystick-ului pe axa Y) | ||
+ | * după câteva încercări, am constatat că atunci când dau în jos joystick-ul primesc valori apropiate de 0 (mai mici decât 10), iar când îl dau în sus primesc valori apropiate de 1023 (mai mari decât 1010) | ||
+ | * cu aceste valori am reușit să creez o mișcare decentă pentru pasăre, limitându-i înălțimea când aceasta ar fi putut ieși din ecran | ||
+ | |||
+ | {{:pm:prj2025:ajipa:input_joystick.png?400|}} | ||
+ | |||
+ | {{:pm:prj2025:ajipa:miscarea_pasarii.png?500|}} | ||
+ | |||
+ | * **Sunete** | ||
+ | |||
+ | Am folosit funcția tone() pentru a genera semnale audio atunci când am trecut cu bine de turnuri (am generat un semnal cu o frecvență ridicată timp de 100ms), dar și atunci când m-am lovit de acestea (am generat un semnal cu o frecvență mai scăzută timp de 100ms). | ||
+ | |||
+ | {{:pm:prj2025:ajipa:sunete.png?700|}} | ||
+ | |||
+ | |||
+ | * **SPI** | ||
+ | |||
+ | Am folosit în majoritatea codului protocolul SPI fiind necesar în afișarea întregului joc pe ecranul LCD. | ||
+ | |||
+ | De la afișarea meniurilor și până la desenarea pieselor jocului, anume pasărea și turnurile, toate acestea le-am realizat utilizând funcții legate de acest protocol. | ||
+ | |||
+ | Prin utilizarea variabilei **game_state**, în funcție de valoarea acesteia, pot să determin ce stare din joc să afișez în acel moment. | ||
+ | |||
+ | **Optimizări:** | ||
+ | * creare de funcții pentru evitarea codului repetitiv (show_main_menu(), show_highscore_menu(), etc.) | ||
+ | * micșorarea size-ului variabilelor (int8_t sau int16_t în loc de int pentru a micșora memoria totală a programului) | ||
+ | * logica PWM pentru controlul LED-urilor (în loc să folosesc cicluri software pentru controlul intensității, care ar fi blocat loop-ul, am utilizat hardware PWM: OCR0A, OCR0B) | ||
+ | * manipularea eficientă a întreruperilor (prin utilizarea întreruperii hardware de la butonul roșu am evitat blocarea buclei principale) | ||
===== Rezultate Obţinute ===== | ===== Rezultate Obţinute ===== | ||
+ | |||
+ | Link YouTube: [[https://youtube.com/shorts/IP-DghO4OIs?feature=share|FlappyBird]] | ||
+ | |||
===== Concluzii ===== | ===== Concluzii ===== | ||
+ | |||
+ | Proiectul a reprezentat o oportunitate excelentă de a îmbina cunoștințele teoretice și practice dobândite în timpul orelor de curs și laboratoarelor, punându-mi în valoare atât abilitățile software, cât și cele hardware. Realizarea efectivă a jocului a fost o experiență unică și captivantă, care mi-a permis să explorez interacțiunea dintre componentele fizice și software, ducând la un rezultat funcțional de care m-am putut bucura. | ||
+ | |||
===== Download ===== | ===== Download ===== | ||
Link GitHub: [[https://github.com/biancapintilie/Flappy-Bird/tree/main|FlappyBird]] | Link GitHub: [[https://github.com/biancapintilie/Flappy-Bird/tree/main|FlappyBird]] | ||
- | |||
- | Link YouTube: [[https://youtube.com/shorts/Ube13TH9jZk?feature=share|FlappyBird]] | ||
===== Bibliografie/Resurse ===== | ===== Bibliografie/Resurse ===== | ||
+ | |||
+ | [[https://www.optimusdigital.ro/en/?gad_source=1&gad_campaignid=21513560576&gbraid=0AAAAADv-p3DwhPcCOgY9guycqRYwBhMVR&gclid=Cj0KCQjwotDBBhCQARIsAG5pinPZmdbjlwyYPcRXZtRa83IJr0csoiy0RhoOkBFCOTyUIHmIppgzgfcaAkxXEALw_wcB|Optimus Digital]] | ||
+ | |||
+ | [[https://sigmanortec.ro/?gad_source=1&gad_campaignid=22305750370&gbraid=0AAAAAC3W72PxHH_lWjqfxfti6gpiQGRIW&gclid=Cj0KCQjwotDBBhCQARIsAG5pinM6W7pTRfSCa5EAEixfWoWsUH15yGOgEzek3ucAcyeKkMtxJ0lEHCIaAikGEALw_wcB|Sigmanortec]] | ||
+ | |||
+ | [[https://cleste.ro/|Clește]] | ||
+ | |||
+ | [[https://ww1.microchip.com/downloads/en/DeviceDoc/Atmel-7810-Automotive-Microcontrollers-ATmega328P_Datasheet.pdf|ATmega328P Datasheet]] |