Autorul poate fi contactat la adresa: Login pentru adresa
Proiectul va fi un joc electronic de memorie. Vor fi multiple jocuri single și multiplayer (până la 4 jucători), ce vor testa rapiditatea și coordonarea participanților.
Jocul va fi reprezentat de o suprafață de joc cu 9 beculețe RGB, ce se vor aprinde și vor forma diverse pattern-uri ce trebuie urmărite de jucători, și 4 butoane pentru a interacționa și a încerca să câștigi jocul. Pe lângă acestea, adițional, va exista un buton pentru a trece de la un mod de joc la altul și un LCD pentru a afișa mesaje despre jocul selectat, progres, câștigători și pierzători.
Jocul vrea să fie o versiune puțin simplificată a jocului MiniWizard [1] - jocul electronic distractiv care ajuta copiii să învețe în anii '80.
Utilitatea unui astfel de joc există și în ziua de azi, deoarece cei mici pot învăța, se pot distra în același timp și își pot dezvolta spiritul competitiv. Cu toate acestea, jocul nu este adresat doar copiilor, putând reprezenta pentru adulți un mod bun de a scăpa de stresul vieții cotidiene, în timp ce adolescenții pot crea drinking games cu acest aparat (e doar o idee, nu trebuie neapărat pusă în practică).
MATCH ME - single-player
HAMMERING HANDS - single-player
GREEN HAMMERING HANDS - single-player
CENTER SHOT - multiplayer
BLUE CENTER SHOT - multiplayer
Dispozitivul va comunica cu jucătorul prin toate elementele sale: elementele principale sunt matricea de LED-uri RGB (3×3) si gamepad-ul, prin intermediul cărora se vor desfășura jocurile. Diverse mesaje (de început de joc, numele jocului, câștig sau pierdere) sunt afișate pe ecranul LCD atașat.
Componentă | Cantitate | Preț/buc | Preț total |
---|---|---|---|
placa de bază PM 2018 [2] | 1 | 8 (placa) + 25 (kit) | 33 |
LED RGB cu Catod Comun | 9 | 1 | 9 |
Modul LCD 1602 cu Backlight Galben-Verde de 5V | 1 | 13 | 13 |
Buton 6x6x6 | 5 | 1 | 5 |
Placa de test universala 70×90 mm | 2 | 8 | 16 |
Fire mamă-mamă | 5 | 4 | 20 |
Rezistor 220Ω | 10 | 0.1 | 1 |
Rezistor 1KΩ | 4 | 0.1 | 0.4 |
Rezistor 10KΩ | 4 | 0.1 | 0.4 |
Header de pini (40p) | 2 | 1 | 2 |
Cablu USB AM la BM | 1 | 3.5 | 3.5 |
Preț total | 105 lei |
Schema electrică a fost realizată în Eagle, datorită licenței pentru studenți pusă la dispoziție de Autodesk.
Astfel, LCD-ul se interfațează pe 7 biți (conform indicațiilor din laborator), pinii de control fiind pe PORT A, iar cei de date pe PORT C, conform schemei. La acesti 7 biti, se adauga si un bit pentru A (care activeaza/dezactiveaza iluminarea display-ului) pe pinul PC2. De asemenea, pe placa de bază va fi necesară lipirea a 3 rezistențe 1K și 1 rezistență 10K.
Cele 9 LED-uri RGB vor fi plasate într-o matrice de pixeli [3], deoarece fiecare LED ar ocupa câte un pin pentru fiecare culoare (Red, Green, Blue), ceea ce ar însemna 27 de pini ocupați doar de LED-uri, ceea ce nu este posibil, dat fiind că avem doar 32 de pini la dispoziție. În acest caz, am ales să implementez o matrice de LED-uri RGB, ceea ce va presupune ca LED-urile să fie puse într-o formație 3×3, iar pe linii să se lege R, G și B (3 coloane cu câte 3 pini), iar pe coloane să se lege catodul comun (3 pini). În total, vor fi 12 pini ocupați de către matricea de LED-uri (3 Red, 3 Green, 3 Blue, 3 Catod) ce se vor găsi pe porturile A și B. De asemenea, de notat că pe legăturile cu LED-urile vor fi necesare rezistențe pentru a limita curentul ce trece prin ele (ideal, rezistențele ar fi fost de 470Ω, dar cum nu am găsit, am folosit de 220Ω).
Cele 5 butoane (4 pentru controlarea jocului și 1 pentru schimbarea jocului) trebuiau atașate microcontroller-ului la portul D (PD0-4). Din cauze conexiunii USB, pinii PD2 si PD3 sunt folositi, ceea ce a facut ca butoanele de pe acei pini sa fie mutate mai departe pe PORT D. Aceasta descoperire a durat cateva ore pentru a fi facuta si a fost rezolvata in mai putin de 2 minute.
Fișierul Schematic este atașat la secțiunea Download.
Modul LCD
Modul Matrice LED-uri RGB
Modul Gamepad
Mediu de dezvoltare: AtmelStudio cu version control Github (repository-ul îl puteți găsi la secțiunea Download).
Librarii si surse 3rd-party: -
Structura proiect
Proiectul este organizat în jurul modulelor hardware, fiecare dintre cele 3 module principale (matrice LED-uri, gamepad, LCD) având un API pentru folosirea lui. Pe langa acestea, am scris si unit tests pentru a testa fiecare modul hardware in parte si de a ma asigura ca software-ul este scris corect.
LCD API este preluat din laborator. La acesta, pe langa setarea parametrilor, am mai adus mici functionalitati (aprinderea/stingerea luminii de fundal, printare de text pe ambele linii). Funcțiile puse la dispoziție sunt următoarele:
/* From lab source code */ void LCD_init(void); uint8_t LCD_read(void); uint8_t LCD_readStatus(void); uint8_t LCD_readData(void); uint8_t LCD_isBusy(void); void LCD_waitNotBusy(void); void LCD_write(uint8_t data); void LCD_writeInstr(uint8_t instr); void LCD_writeData(uint8_t data); void LCD_putChar(char c); void LCD_putCharAt(uint8_t addr, char c); void LCD_print(const char* msg); void LCD_printAt(uint8_t addr, const char* msg); /* Toggles the backlight of the LCD */ void LCD_toggleBacklight(void); /* Prints on both lines after clearing the display */ void LCD_print2(const char* msg1, const char* msg2);
RGB LED Matrix API este construit de mine si este folosit pentru parametrizarea si initializarea matricei de pixeli, la care aduce functionalitati de aprins/stins un anumit LED identificat cu un rand si o coloana (indexate de la 1). Funcțiile puse la dispoziție sunt următoarele:
/* Initialize the RGB matrix. Must be called only once at the beginning. */ void RGB_matrix_init(void); /* Turn on in red the LED at a certain row and column. */ void RGB_matrix_turn_on_red(int row, int col); /* Turn on in green the LED at a certain row and column. */ void RGB_matrix_turn_on_green(int row, int col); /* Turn on in blue the LED at a certain row and column. */ void RGB_matrix_turn_on_blue(int row, int col); /* Turn off the LED at a certain row and column. */ void RGB_matrix_turn_off(int row, int col);
Gamepad API este construit de mine si este folosit pentru parametrizarea si initializarea gamepad-ului format din butoane cu ajutorul carora se pot juca jocurile. Funcțiile puse la dispoziție sunt următoarele:
/* Initialize the gamepad. */ void gamepad_init(void); /* Check if UP button is pressed */ int gamepad_is_up_pressed(void); /* Check if DOWN button is pressed */ int gamepad_is_down_pressed(void); /* Check if LEFT button is pressed */ int gamepad_is_left_pressed(void); /* Check if RIGHT button is pressed */ int gamepad_is_right_pressed(void); /* Check if CHANGE GAME button is pressed */ int gamepad_is_game_pressed(void);
Game API este construit de mine si este folosit pentru initializarea si rularea jocurilor. Funcțiile puse la dispoziție sunt următoarele:
/* Initialize the game */ void game_init(void); /* Load a new game */ void game_start(void); /* Start MATCH ME game mode - single player*/ void game_match_me(void); /* Start HAMMERING HANDS game mode - single player*/ void game_hammering_hands(void); /* Start GREEN HAMMERING HANDS game mode - single player*/ void game_green_hammering_hands(void); /* Start CENTER SHOT game mode - multiplayer*/ void game_center_shot(void); /* Start BLUE CENTER SHOT game mode - multiplayer*/ void game_blue_center_shot(void);
In functia main() a proiectului, se initializeaza jocul si se incepe. Dupa fiecare joc terminat, exista 5 secunde puse la dispozitie pentru a schimba jocul prin butonul GAME. Dupa acestea, jocul la care s-a ajuns va incepe (dupa afisarea numelui jocului selectat pe ecran, o numaratoare 3..2..1 si o secventa de semafoare rosii care se sting pe matricea de LED-uri) si va fi apelata respectiva functie.
Rezultatele au fost foarte bune, conform asteptarilor, iar cum o poza face o mie de cuvinte, rezultatul final arata in felul urmator:
Un video nu stiu cate cuvine face, dar aici este un video cu mine jucand (destul de prost) jocul MATCH ME.