This is an old revision of the document!


Whack-a-Mole Game

Introducere

Ce face: Proiectul reprezintă o adaptare electronică a clasicului joc arcade „Whack-a-Mole”. În loc de cârtițe mecanice, jocul folosește butoane Arcade iluminate. Microcontrolerul va aprinde aleatoriu LED-ul unuia dintre butoane, iar jucătorul trebuie să apese butonul respectiv cât mai repede posibil.

Scopul lui: Scopul principal este testarea și îmbunătățirea timpului de reacție al jucătorului. Din punct de vedere academic, scopul este implementarea unui sistem interactiv complet (bare-metal) care implică citirea de intrări digitale și analogice, generarea de semnale de ieșire multiplexate și utilizarea timerelor.

Ideea de la care am pornit: Ideea a pornit de la dorința de a recrea sentimentul și dinamica jocurilor mecanice retro folosind componente electronice moderne. Am vrut un proiect care să fie nu doar o demonstrație tehnică, ci și un produs final distractiv și interactiv.

Utilitate: Pentru mine, este o oportunitate excelentă de a aprofunda lucrul cu registrele ATmega328p, timerele, întreruperile și optimizarea pinilor folosind un Shift Register. Pentru utilizatori, este un joc antrenant, perfect pentru pauze, care stimulează reflexele.

Descriere generală

Sistemul este centrat în jurul microcontrolerului ATmega328p (pe platforma Arduino UNO). Acesta preia date din lumea fizică, le procesează și oferă feedback vizual și sonor.

Interacțiunea modulelor:

  • Unitatea de procesare: Placa de dezvoltare generează secvența aleatoare de aprindere a LED-urilor, cronometrează timpul de reacție și calculează scorul curent.
  • Modulul de Input (Senzorii): Este compus din cele 4 butoane Arcade (microswitch-uri) și un potențiometru liniar. Potențiometrul este citit prin convertorul analog-digital (ADC) înainte de începerea jocului pentru a stabili nivelul de dificultate (timpul pe care jucătorul îl are la dispoziție pentru a apăsa butonul).
  • Modulul de Output Vizual (Afișajul): Include LED-urile integrate în butoanele Arcade (care indică ținta) și un afișaj cu 7 segmente și 4 digiți (care afișează scorul). Pentru a economisi pinii limitați ai microcontrolerului, afișajul cu 7 segmente este controlat prin intermediul unui Shift Register (74HC595).
  • 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).

Hardware Design

Listă de piese

Software Design

Descrierea codului aplicaţiei (firmware)

Mediu de dezvoltare

Cod scris în C bare-metal pentru ATmega328P, fără framework Arduino. Toolchain:

  • 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>
  • avrdude — flash prin bootloader-ul Arduino
avr-gcc -mmcu=atmega328p -DF_CPU=16000000UL -Os -Wall whack_a_led.c -o whack.elf
avr-objcopy -O ihex -R .eeprom whack.elf whack.hex
avrdude -p atmega328p -c arduino -P /dev/ttyACM0 -b 115200 -U flash:w:whack.hex

Binar rezultat: ~4.8 KB flash + 150 bytes RAM.

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.

Algoritmi şi structuri

  • 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.
  • Generare ton — Timer1 în mod CTC; pentru că PD6 nu e pin OC, comutarea se face manual dintr-un ISR. Frecvența calculată cu OCR1A = F_CPU / (2 × prescaler × freq) - 1.
  • millis() bare-metal — Timer0 CTC cu întrerupere la fiecare 1 ms care incrementează un contor uint32_t; citirea protejată cu cli/sei pentru atomicitate.
  • ADC — citire potențiometru (canal 4) și seed pentru PRNG (canal 5, pin neconectat).
  • 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.
  • 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.

Surse şi funcţii implementate

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
  • Display: shift_out_msb, write_segments, display_digits, display_score, display_idle, display_game_over, compute_dp_mask
  • Audio: tone_blocking, play_melody
  • Secvenţe de joc: display_countdown, start_new_game, pick_next_led, trigger_game_over, score_roll_animation, level_up_sequence
  • Input: get_pressed_button
  • Persistenţă: load_high_score, save_high_score
  • Main loop: inițializare periferice + while(1) cu refresh display + FSM

Parametrii de joc (timpi de reacţie, punctaje, durate animaţii) sunt grupaţi ca #define-uri la începutul fişierului pentru tuning rapid.

Rezultate Obţinute

Care au fost rezultatele obţinute în urma realizării proiectului vostru.

Concluzii

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

Arhiva conţine:

  • whack_a_led.c — sursa C bare-metal
  • schematic.png — schema electrică

</code>

Bibliografie/Resurse

Resurse Hardware

  • ATmega328P Datasheet (Microchip/Atmel) — referinţa oficială pentru registrele perifericelor: Timer/Counter, ADC, EEPROM, USART, întreruperi. datasheet PDF
  • 74HC595 Datasheet (Texas Instruments / NXP) — shift register 8-bit cu latch, folosit pentru controlul segmentelor display-ului. datasheet PDF
  • KH5461AB Datasheet — display 7-segmente 4 cifre, common cathode. Conţine pinout-ul şi specificaţiile electrice ale segmentelor.
  • Arduino UNO R3 Schematic — pentru verificarea conexiunilor pinilor expuşi pe board şi a circuitului de reset.

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>. nongnu.org/avr-libc
  • AVR-GCC Documentation — opţiuni de compilare specifice arhitecturii AVR (-mmcu, -Os, -DF_CPU).
  • AVRDUDE User Manual — opţiuni pentru flash-area HEX-ului prin bootloader. nongnu.org/avrdude

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.
  • Note frequency table — tabela standard de frecvenţe pentru notele muzicale (C4 = 262 Hz, A4 = 440 Hz, etc.).

Export to PDF

SimplyCodes

pm/prj2026/florin.stancu/alexandru.negru2603.1779570494.txt.gz · Last modified: 2026/05/24 00:08 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