This is an old revision of the document!
Micro Invaders
Introducere
Prezentarea pe scurt a proiectului:
Scopul proiectului este de a simula comportamentul unei console de jocuri de tip handheld. Acest concept presupune integrarea tuturor componentelor hardware (microcontrolerul, ecranul, joystick-ul și butoanele) într-un format compact și ergonomic.
Ideea proiectului a pornit de la consolele pe care le-am folosit de-a lungul anilor, cum ar fi Nintendo DS sau Steam Deck, și de la un joc clasic al copilăriei mele: “Chicken Invaders”. Practic, mi-am propus să construiesc propria versiune a unei astfel de console, realizată de la zero și la o scară mult mai mică.
Proiectul este, de asemenea, un exercițiu bun de optimizare și adaptare a codului unui joc video pentru un microcontroller, care are mai multe limitări (memorie redusă, clock speed scăzut, etc.).
Descriere generală
Jocul este implementat pe microcontroller-ul ATmega328P și include următoarele funcționalități:
Hardware Design
Bill of Materials
| Nr. crt. | Nume componentă | Specificații | Cantitate |
| 1 | Arduino Nano | Placă de dezvoltare bazată pe microcontroller-ul ATmega328P | 1 |
| 2 | Modul ecran LCD | Modul LCD de 1.44'' cu SPI și Controller ST7735 (128×128 px) | 1 |
| 3 | Joystick analogic | Modul joystick cu 2 potențiometre (axa X, axa Y) | 1 |
| 4 | Buton (Push button) | Microîntrerupător tactil | 1 |
| 5 | Breadboard | Placă de test 830 de puncte | 1 |
| 6 | Fire de conexiune | Fire cu izolație PVC (22AWG) | 1 set |
| 7 | Cablu USB | Pentru alimentare și programare | 1 |
Descriere componente
Pinout
| Componentă | Pin Componentă | Pin Arduino Nano | Port / Registru ATmega328P | Descriere |
| Display LCD | VCC | 5V | — | Alimentare logică ecran. |
| | GND | GND | — | Masă circuit. |
| | SCL | Pin 13 | PORTB (PB5) | Hardware SPI Clock: Sincronizează transferul rapid de date. |
| | SDA | Pin 11 | PORTB (PB3) | Hardware SPI MOSI: Linie master-to-slave pentru trimis pixeli. |
| | RES | Pin 9 | PORTB (PB1) | Reset hardware la inițializarea ecranului. |
| | DC | Pin 8 | PORTB (PB0) | Data/Command: Schimbă starea între comenzi (0) și pixeli (1). |
| | CS | Pin 10 | PORTB (PB2) | Chip Select: Activează/dezactivează magistrala SPI pentru ecran. |
| | BLK | 3.3V | — | Alimentare LED Backlight (lumină fundal). |
| Joystick | 5V | 5V | — | Alimentare potențiometre interne. |
| | GND | GND | — | Referință masă (0V). |
| | VRx | Pin A0 | ADC0 (Canal 0) | Convertor Analog-Digital: Citește poziția X (valori 0-1023). |
| | VRy | Pin A1 | ADC1 (Canal 1) | Convertor Analog-Digital: Citește poziția Y (valori 0-1023). |
| Push Button | Pin 1 | Pin 3 | PORTD (PD3) | Citire rapidă stare buton. Are Pull-up intern activat. |
| | Pin 2 | GND | — | Închide circuitul la masă când butonul este apăsat. |
Schematic
Demo
Software Design
Descrierea codului aplicaţiei (firmware):
mediu de dezvoltare (if any) (e.g. AVR Studio, CodeVisionAVR)
librării şi surse 3rd-party (e.g. Procyon AVRlib)
algoritmi şi structuri pe care plănuiţi să le implementaţi
(etapa 3) surse şi funcţii implementate
Mediu de dezvoltare
Aplicația a fost dezvoltată pe VS Code cu extensia PlatformIO.
Librării şi surse 3rd-party
Pentru controlul ecranului TFT și randarea primitivelor grafice, au fost utilizate următoarele librării externe:
Adafruit_GFX Library: Oferă funcțiile de bază pentru desenarea figurilor geometrice (linii, dreptunghiuri).
Adafruit_ST7735 Library: Asigură comunicarea SPI dintre ATmega328P și modulul LCD ST7735.
Structuri de date
struct Enemy: Grupează variabilele de poziţie curentă (x, y), memoria grafică locală (oldX, oldY), poziţia de referinţă pentru mişcarea sinusoidală (baseY) şi un flag boolean “alive”. Inamicii sunt stocați într-un vector de astfel de structuri.
Funcții implementate
Logica jocului, controlul perifericelor și randarea grafică sunt gestionate prin intermediul următoarelor funcții:
setup(): Configurarea inițială a sistemului. Inițializează regiștrii de direcție ai porturilor (DDRB, DDRD) stabilind pinii ca ieșire/intrare, configurează multiplexorul ADC și registrul de control, setează Timer 2 în modul CTC pentru generarea întreruperilor la 1ms și pornește ecranul TFT afișând ecranul inițial.
loop(): Nucleul asincron al programului. Rulează pe baza cadrelor de timp (gameTicks), executând logica jocului o dată la ~30ms pentru a asigura un framerate stabil. Gestionează citirea potențiometrelor joystick-ului și apelează funcțiile de actualizare (updateEnemies(), updatePlayerBullet(), updateSparks()). De asemenea, loop() conține și cod specific jucătorului, precum definirea limitelor ecranului, desenarea navei, afișarea scorului și verificarea dacă jucătorul a tras spre inamici.
updateEnemies(): Actualizează poziția pe ecran a inamicilor. Verifică dacă grupul a atins marginile laterale pentru a inversa direcția de mers și calculează șansa aleatorie (~2%) ca un inamic să genereze un proiectil la oricare cadru. Pentru efectul sinusoidal de mișcare al inamicilor, am păstrat valoarea Y de bază (baseY) pe care am folosit-o în ecuația de update a coordonatei Y (flock[i].y). De asemenea, funcția gestionează și logica de coliziune dintre jucător și inamici.
updatePlayerBullet() / updateSparks(): Funcțiile de mișcare ale proiectilelor. Mută pozițiile pe ecran (în sus pentru jucător, în jos pentru inamici), aplică algoritmul de ștergere a pixelilor vechi, redesenează obiectele și verifică continuu coliziunile cu țintele prin calcularea distanțelor absolute (AABB).
drawShip() / drawEnemy(): Funcții pentru desenarea acestor obiecte pe ecran. Pentru obținerea unor aspecte mai detaliate, am desenat “de mănă” pixel-artul navei și a inamicilor (microcontrollere, hence the name “Micro Invaders”) prin definirea unui bitmap. Pe lăngă bitmap, am mai adăugat și alte detalii mai simple prin “fillRect()”. Pentru ștergerea sprite-urilor de pe pozițiile vechi, se desenează utilizând culoarea fundalului (ST77XX_BLACK).
Rezultate Obţinute
Care au fost rezultatele obţinute în urma realizării proiectului vostru.
Concluzii
Download
O arhivă (sau mai multe dacă este cazul) cu fişierele obţinute în urma realizării proiectului: surse, scheme, etc. Un fişier README, un ChangeLog, un script de compilare şi copiere automată pe uC crează întotdeauna o impresie bună

.
Fişierele se încarcă pe wiki folosind facilitatea Add Images or other files. Namespace-ul în care se încarcă fişierele este de tipul :pm:prj20??:c? sau :pm:prj20??:c?:nume_student (dacă este cazul). Exemplu: Dumitru Alin, 331CC → :pm:prj2009:cc:dumitru_alin.
Jurnal
Puteți avea și o secțiune de jurnal în care să poată urmări asistentul de proiect progresul proiectului.
Bibliografie/Resurse
Listă cu documente, datasheet-uri, resurse Internet folosite, eventual grupate pe Resurse Software şi Resurse Hardware.
Export to PDF