Differences

This shows you the differences between two versions of the page.

Link to this comparison view

pm:prj2026:florin.stancu:alexandru.negru2603 [2026/05/24 00:54]
alexandru.negru2603 [Download]
pm:prj2026:florin.stancu:alexandru.negru2603 [2026/05/24 01:10] (current)
alexandru.negru2603
Line 23: Line 23:
   * **Modulul de Output Sonor:** Un buzzer activ oferă feedback acustic imediat (ex: un ton scurt pentru o lovitură reușită, un ton diferit pentru o lovitură ratată sau expirarea timpului).   * **Modulul de Output Sonor:** Un buzzer activ oferă feedback acustic imediat (ex: un ton scurt pentru o lovitură reușită, un ton diferit pentru o lovitură ratată sau expirarea timpului).
  
 +===== Planificare și Ipoteză =====
 +
 +==== Ipoteza proiectului ====
 +Credem că implementarea unei arhitecturi software non-blocante (zero-delay) bazată pe un automat cu stări finite (FSM) și pe un timer hardware dedicat pentru ''​millis()''​ va îmbunătăți calitatea multiplexării vizuale și va garanta un timp de scanare a inputurilor (butoane) sub 5ms. Presupunem că, deoarece microcontrolerul nu va mai irosi cicluri de ceas în bucle de așteptare blocante, acesta va permite actualizarea display-ului și citirea jucătorului în mod simultan, fără efect de flicker.
 +
 +==== Planificarea sarcinilor (Gantt) ====
 +Următorul tabel descrie activitățile principale desfășurate pe parcursul celor 4 săptămâni alocate proiectului.
 +
 +^ Săptămâna ^ Activitate asumată ^
 +| **Săptămâna 1** | **Documentare și Arhitectură:​** Alegerea componentelor,​ studierea datasheet-urilor (ATmega328P,​ 74HC595) și definirea ipotezei proiectului,​ redactarea documentației pe OCW. |
 +| **Săptămâna 2** | **Hardware Design:** Proiectarea schemei electrice, asamblarea componentelor pe breadboard și testarea conexiunilor la pini (LED-uri, butoane, display). |
 +| **Săptămâna 3** | **Software Design:** Implementarea driverelor bare-metal (Timer0 pentru millis, Timer1 pentru generare ton, ADC, EEPROM, SPI/​ShiftOut) și scrierea logicii FSM. |
 +| **Săptămâna 4** | **PM Fair & Profilare:​** Profilarea codului, ajustarea dificultății,​ curățarea finală a repository-ului de Git și pregătirea prezentării. |
 ===== Hardware Design ===== ===== Hardware Design =====
 {{:​pm:​prj2026:​florin.stancu:​negrualexandru_schematic1.png?​700|}} {{:​pm:​prj2026:​florin.stancu:​negrualexandru_schematic1.png?​700|}}
Line 37: Line 50:
     * 1 x Breadboard 830 puncte.     * 1 x Breadboard 830 puncte.
     * Fire de conexiune tip Dupont (Tată-Tată și Mamă-Tată).     * Fire de conexiune tip Dupont (Tată-Tată și Mamă-Tată).
 +
 ===== Software Design ===== ===== Software Design =====
  
 ==== Mediu de dezvoltare ==== ==== Mediu de dezvoltare ====
- 
 Cod scris în **C bare-metal** pentru ATmega328P, fără framework Arduino. Toolchain: Cod scris în **C bare-metal** pentru ATmega328P, fără framework Arduino. Toolchain:
- 
   * **avr-gcc** 7.3.0 — compilator   * **avr-gcc** 7.3.0 — compilator
   * **avr-libc** 2.0.0 — pentru macro-uri de registre din ''<​avr/​io.h>'',​ ''<​avr/​interrupt.h>'',​ ''<​util/​delay.h>''​   * **avr-libc** 2.0.0 — pentru macro-uri de registre din ''<​avr/​io.h>'',​ ''<​avr/​interrupt.h>'',​ ''<​util/​delay.h>''​
Line 56: Line 68:
  
 ==== Librării 3rd-party ==== ==== Librării 3rd-party ====
- 
 **Niciuna.** Toate perifericele sunt programate direct la nivel de registre. Singurele include-uri sunt header-ele standard avr-libc pentru definiţiile registrelor şi macro-urile de întreruperi. **Niciuna.** Toate perifericele sunt programate direct la nivel de registre. Singurele include-uri sunt header-ele standard avr-libc pentru definiţiile registrelor şi macro-urile de întreruperi.
  
 ==== Algoritmi şi structuri ==== ==== Algoritmi şi structuri ====
- 
   * **Automat cu stări finite** — 3 stări: IDLE, PLAYING, GAME_OVER, cu tranziţii într-un ''​switch''​ din main loop.   * **Automat cu stări finite** — 3 stări: IDLE, PLAYING, GAME_OVER, cu tranziţii într-un ''​switch''​ din main loop.
   * **Multiplexare display** — cele 4 cifre împart 8 linii de segmente prin shift register 74HC595. Hold de 2 ms per cifră -> refresh ~125 Hz. Anti-ghosting prin stingerea tuturor digiților înainte de încărcarea segmentelor.   * **Multiplexare display** — cele 4 cifre împart 8 linii de segmente prin shift register 74HC595. Hold de 2 ms per cifră -> refresh ~125 Hz. Anti-ghosting prin stingerea tuturor digiților înainte de încărcarea segmentelor.
Line 68: Line 78:
   * **PRNG xorshift32** — generator pseudo-aleator rapid, seed-uit din zgomotul ADC.   * **PRNG xorshift32** — generator pseudo-aleator rapid, seed-uit din zgomotul ADC.
   * **EEPROM** — persistență high score (2 bytes + magic byte pentru detectarea chip-ului virgin). Secvența EEMPE→EEPE protejată cu ''​cli/​sei''​.   * **EEPROM** — persistență high score (2 bytes + magic byte pentru detectarea chip-ului virgin). Secvența EEMPE→EEPE protejată cu ''​cli/​sei''​.
-  * **Punctaj proporțional** — 10/5/1 puncte după cât de rapid s-a apăsat raportat la fereastra disponibilă (33% / 66% / >66%). 
-  * **Difficulty scaling** — fereastra scade cu 5 ms per hit, plafonată la 600 ms. 
-  * **Animație "​slot-machine"​** — la +5 sau +10 puncte, scorul afișat oscilează cu noise aleatoriu apoi se stabilizează. 
-  * **Bară de timp prin DP-uri** — cele 4 puncte decimale ale display-ului indică timpul rămas (1111 → 0111 → 0011 → 0001). 
   * **Delay non-blocant** — toate așteptările folosesc o buclă bazată pe ''​millis()''​ care continuă să refresheze display-ul, eliminând pâlpâirea în timpul melodiilor şi animaţiilor.   * **Delay non-blocant** — toate așteptările folosesc o buclă bazată pe ''​millis()''​ care continuă să refresheze display-ul, eliminând pâlpâirea în timpul melodiilor şi animaţiilor.
  
 +==== Metrici și Profilarea Codului ====
 +Pentru a valida ipoteza și a garanta un gameplay fluid, am urmărit următoarele metrici de performanță:​
 +  * **Latența de Input (Polling Rate):** Ținta asumată a fost un timp de răspuns sub 5ms. La profilarea codului (analizând funcția ''​display_digits''​),​ am observat că fiecare din cele 4 cifre necesită un ''​_delay_us(2000)''​ pentru a garanta o luminozitate optimă a segmentelor. Astfel, un ciclu complet de reîmprospătare durează minimum 8ms, plus overhead-ul shiftării pe 8 biți. Așadar, butoanele sunt scanate la aproximativ 8.5 - 9ms. Deși depășește pragul ipotetic de 5ms, valoarea este suficient de mică pentru a preveni pierderea oricărui input generat de reflexele umane.
 +  * **Frecvența de Refresh (Display):​** Un timp de execuție a buclei de ~8.5ms se traduce într-o frecvență de refresh de aproximativ **115-120 Hz**. Aceasta metrică a atins perfect ținta, rezultând într-un afișaj luminos, clar și absolut lipsit de pâlpâire (flicker).
 +  * **Amprenta pe Memorie:** Executabilul final bare-metal folosește doar ~4.8 KB din memoria Flash și 150 bytes de memorie RAM, demonstrând eficiența optimizării la nivel de registre.
 +
 +Proiectul a fost o oportunitate excelentă de a aprofunda lucrul **bare-metal** cu ATmega328P. Renunţarea la framework-ul Arduino a oferit control complet asupra perifericelor. Cele mai utile decizii s-au dovedit a fi structurarea logicii ca automat cu stări finite și multiplexarea non-blocantă. Cele mai dificile obstacole au fost: 
 +  * Generarea de tonuri pe PD6 (deoarece nu este un pin OC al Timer1, a necesitat crearea unei întreruperi manuale ''​TIMER1_COMPA_vect''​).
 +  * Atomicitatea citirii contorului ''​millis_count''​ pe arhitectura AVR de 8 biți (rezolvată folosind blocul ''​cli()/​sei()''​).
 +  * Scrierea în EEPROM (respectarea timpului critic de 4 cicluri de ceas pentru secvența EEMPE -> EEPE).
 ==== Surse şi funcţii implementate ==== ==== Surse şi funcţii implementate ====
- 
 Cod organizat într-un singur fişier (''​whack_a_led.c'',​ ~810 linii) cu următoarele grupuri funcţionale:​ Cod organizat într-un singur fişier (''​whack_a_led.c'',​ ~810 linii) cu următoarele grupuri funcţionale:​
- 
   * **Drivere low-level**:​ ''​timer0_init'',​ ''​millis'',​ ''​tone_start/​stop'',​ ''​adc_read'',​ ''​eeprom_read/​write_byte_raw'',​ ''​prng_next''​   * **Drivere low-level**:​ ''​timer0_init'',​ ''​millis'',​ ''​tone_start/​stop'',​ ''​adc_read'',​ ''​eeprom_read/​write_byte_raw'',​ ''​prng_next''​
   * **Display**:​ ''​shift_out_msb'',​ ''​write_segments'',​ ''​display_digits'',​ ''​display_score'',​ ''​display_idle'',​ ''​display_game_over'',​ ''​compute_dp_mask''​   * **Display**:​ ''​shift_out_msb'',​ ''​write_segments'',​ ''​display_digits'',​ ''​display_score'',​ ''​display_idle'',​ ''​display_game_over'',​ ''​compute_dp_mask''​
Line 86: Line 100:
   * **Main loop**: inițializare periferice + ''​while(1)''​ cu refresh display + FSM   * **Main loop**: inițializare periferice + ''​while(1)''​ cu refresh display + FSM
  
-Parametrii ​de joc (timpi de reacţie, punctajedurate animaţii) sunt grupaţca ''#​define''​-uri la începutul fişierului ​pentru ​tuning rapid.+===== Elementul ​de Noutate ===== 
 +Elementul principal de noutate și originalitate ​(5% din evaluare) constă în **sistemul hibrid și dinamic ​de ajustare a dificultății**,​ secondat de inovații vizuale pe afișajul 7-segmente:​ 
 +  * **Dificultatea Scalabilă Hibrid:** Fereastra de timp pe care o are jucătorul la dispoziție nu este un simplu parametru static stabilit de potențiometru. Potențiometrul setează doar pragul "de bază" (între 3s și 1s). Peste acesta se aplică un algoritm de "​Accelerare Progresivă":​ pe măsură ce scorul creștedin timpul total disponibil se scad automat câte 5 ms per punct acumulatforțând o escaladare organică a dificultății. Timpul este totușplafonat hardware (hard-limit la 600ms) ​pentru ​ca jocul să rămână fizic posibil. 
 +  * **Punctaj Proporțional:​** Jucătorul nu primește mereu 1 punct per lovitură. Logica este împărțită pe trepte de reacție (se acordă 10, 5 sau 1 punct în funcție de plasarea timpului de reacție în treimea corespunzătoare a ferestrei alocate), recompensând reflexele extreme. 
 +  * **Bara de Progres pe Display (DP HUD):** Pentru a indica vizual cât timp mai are jucătorul înainte să expire runda curentă fără să întrerupă afișarea scorului, am folosit inteligent cele 4 puncte zecimale (DP) de pe afișaj. Acestea se sting rând pe rând pe măsură ce fereastra de timp trece (1111 → 0111 → 0011 → 0001), servind drept indicator vizual (Timer Bar).
  
 ===== Rezultate Obţinute ===== ===== Rezultate Obţinute =====
-  +Proiectul a fost finalizat cu succes ​în cele 4 săptămâni alocate. Sistemul funcţionează stabil ca un joc arcade complet, cu input multiplu (4 butoane ​cu pull-up intern ​+ potenţiometru),​ output vizual ​multiplexat ​şi feedback sonor (melodii redate printr-un ISR manual pe Timer1).
-Proiectul a fost finalizat cu succes, toate obiectivele propuse fiind îndeplinite. Sistemul funcţionează stabil ca un joc arcade complet, cu input multiplu (4 butoane + potenţiometru),​ output vizual ​(4 LED-uri arcade + display 4 cifre cu DP) şi feedback sonor.+
  
-===== Concluzii =====+===== Concluzii ​și Validarea Ipotezei ​===== 
 +**Validarea Ipotezei:** Ipoteza inițială a fost validată **parțial**,​ însă cu un rezultat practic excelent. Presupunerea că timpul de polling va scădea sub 5ms s-a dovedit incorectă din cauza necesității hardware de a menține cifra aprinsă timp de 2ms pentru persistența retinei (rezultând într-o buclă de minim 8ms). Cu toate acestea, nucleul ipotezei s-a confirmat pe deplin: arhitectura cu FSM și eliminarea totală a funcțiilor blocante (înlocuite cu funcția custom ''​custom_delay''​ bazată pe ''​millis()''​) a permis ca sistemul să actualizeze display-ul și să scaneze inputurile simultan, fără nicio blocare sau ghosting.
    
-Proiectul a fost o oportunitate excelentă de a aprofunda lucrul **bare-metal** cu ATmega328P. Renunţarea la framework-ul Arduino a oferit control complet asupra perifericelor (Timer0/1, ADC, EEPROM, întreruperi) şi a redus dimensiunea binarului la ~4.8 KB. 
-  
-Cele mai utile decizii s-au dovedit a fi structurarea logicii ca **automat cu stări finite** (care a permis extensia uşoară cu countdown, level-up, animaţii) şi **multiplexarea non-blocantă** apelată din toate buclele de aşteptare, fără ea, display-ul pâlpâia la fiecare ''​_delay_ms()''​. 
-  
-Cele mai dificile probleme au fost: maparea corectă a segmentelor între Q0..Q7 ale shift register-ului şi pinii A..G ai display-ului,​ generarea de tonuri pe PD6 (care nu e pin OC al Timer1, deci necesită ISR manual), atomicitatea citirii ''​millis_count''​ pe AVR pe 8 biţi, şi eliminarea efectului de **ghosting** între cifre. 
-  
-În final, proiectul demonstrează că un sistem interactiv complet, cu input digital şi analogic, output multiplexat şi audio sintetizat poate fi construit fără bibliotecile Arduino, oferind o înţelegere mult mai profundă a microcontrolerului decât abordarea high-level cu ''​digitalWrite()''​ şi ''​tone()''​. 
-  
- 
 ===== Download ===== ===== Download =====
    
Line 114: Line 123:
   * ''​LICENSE''​ — licența MIT a proiectului   * ''​LICENSE''​ — licența MIT a proiectului
 </​note>​ </​note>​
 +
 ===== Bibliografie/​Resurse ===== ===== Bibliografie/​Resurse =====
    
 ==== Resurse Hardware ==== ==== Resurse Hardware ====
-  
   * **ATmega328P Datasheet** (Microchip/​Atmel) — referinţa oficială pentru registrele perifericelor:​ Timer/​Counter,​ ADC, EEPROM, USART, întreruperi. [[https://​ww1.microchip.com/​downloads/​en/​DeviceDoc/​Atmel-7810-Automotive-Microcontrollers-ATmega328P_Datasheet.pdf|datasheet PDF]]   * **ATmega328P Datasheet** (Microchip/​Atmel) — referinţa oficială pentru registrele perifericelor:​ Timer/​Counter,​ ADC, EEPROM, USART, întreruperi. [[https://​ww1.microchip.com/​downloads/​en/​DeviceDoc/​Atmel-7810-Automotive-Microcontrollers-ATmega328P_Datasheet.pdf|datasheet PDF]]
   * **74HC595 Datasheet** (Texas Instruments / NXP) — shift register 8-bit cu latch, folosit pentru controlul segmentelor display-ului. [[https://​www.ti.com/​lit/​ds/​symlink/​sn74hc595.pdf|datasheet PDF]]   * **74HC595 Datasheet** (Texas Instruments / NXP) — shift register 8-bit cu latch, folosit pentru controlul segmentelor display-ului. [[https://​www.ti.com/​lit/​ds/​symlink/​sn74hc595.pdf|datasheet PDF]]
Line 124: Line 133:
    
 ==== Resurse Software ==== ==== Resurse Software ====
-  
   * **AVR Libc Reference Manual** — documentaţia oficială pentru avr-libc, în special pentru macro-urile din ''<​avr/​io.h>'',​ ''<​avr/​interrupt.h>''​ şi funcţiile din ''<​util/​delay.h>''​. [[https://​www.nongnu.org/​avr-libc/​user-manual/​|nongnu.org/​avr-libc]]   * **AVR Libc Reference Manual** — documentaţia oficială pentru avr-libc, în special pentru macro-urile din ''<​avr/​io.h>'',​ ''<​avr/​interrupt.h>''​ şi funcţiile din ''<​util/​delay.h>''​. [[https://​www.nongnu.org/​avr-libc/​user-manual/​|nongnu.org/​avr-libc]]
   * **AVR-GCC Documentation** — opţiuni de compilare specifice arhitecturii AVR (''​-mmcu'',​ ''​-Os'',​ ''​-DF_CPU''​).   * **AVR-GCC Documentation** — opţiuni de compilare specifice arhitecturii AVR (''​-mmcu'',​ ''​-Os'',​ ''​-DF_CPU''​).
Line 130: Line 138:
    
 ==== Inspiraţie & resurse de muzică ==== ==== Inspiraţie & resurse de muzică ====
-  
   * **Mario Bros Game Over (Koji Kondo, 1985)** — transcrierea melodiei NES pentru buzzer, adaptată din proiecte open-source comunitare de Arduino.   * **Mario Bros Game Over (Koji Kondo, 1985)** — transcrierea melodiei NES pentru buzzer, adaptată din proiecte open-source comunitare de Arduino.
   * **Note frequency table** — tabela standard de frecvenţe pentru notele muzicale (C4 = 262 Hz, A4 = 440 Hz, etc.).   * **Note frequency table** — tabela standard de frecvenţe pentru notele muzicale (C4 = 262 Hz, A4 = 440 Hz, etc.).
-  
- 
- 
-<​html><​a class="​media mediafile mf_pdf"​ href="?​do=export_pdf">​Export to PDF</​a></​html>​ 
- 
-SimplyCodes 
- 
pm/prj2026/florin.stancu/alexandru.negru2603.1779573265.txt.gz · Last modified: 2026/05/24 00:54 by alexandru.negru2603
CC Attribution-Share Alike 3.0 Unported
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0