This is an old revision of the document!
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.
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:
Cod scris în C bare-metal pentru ATmega328P, fără framework Arduino. Toolchain:
<avr/io.h>, <avr/interrupt.h>, <util/delay.h>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.
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.
switch din main loop.OCR1A = F_CPU / (2 × prescaler × freq) - 1.uint32_t; citirea protejată cu cli/sei pentru atomicitate.cli/sei.millis() care continuă să refresheze display-ul, eliminând pâlpâirea în timpul melodiilor şi animaţiilor.
Cod organizat într-un singur fişier (whack_a_led.c, ~810 linii) cu următoarele grupuri funcţionale:
timer0_init, millis, tone_start/stop, adc_read, eeprom_read/write_byte_raw, prng_nextshift_out_msb, write_segments, display_digits, display_score, display_idle, display_game_over, compute_dp_masktone_blocking, play_melodydisplay_countdown, start_new_game, pick_next_led, trigger_game_over, score_roll_animation, level_up_sequenceget_pressed_buttonload_high_score, save_high_scorewhile(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.
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.
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().
Arhiva conţine:
whack_a_led.c — sursa C bare-metalschematic.png — schema electrică
<avr/io.h>, <avr/interrupt.h> şi funcţiile din <util/delay.h>. nongnu.org/avr-libc-mmcu, -Os, -DF_CPU).SimplyCodes