This shows you the differences between two versions of the page.
pm:prj2022:imacovei:andreea.nistor2208 [2022/05/22 23:24] andreea.nistor2208 [Software Design] |
pm:prj2022:imacovei:andreea.nistor2208 [2022/05/25 21:18] (current) andreea.nistor2208 [Rezultate Obţinute] |
||
---|---|---|---|
Line 47: | Line 47: | ||
===== Software Design ===== | ===== Software Design ===== | ||
- | |||
- | <note tip> | ||
- | 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 | ||
- | </note> | ||
Mediul de dezvoltare folosit este Arduino IDE, schema bloc a fost realizata in Lucidchart, iar schema electrica in EAGLE. De asemenea am folosit librăriile LiquidCrystal.h pentru LCD si EEPROM.h pentru memoria EEPROM. | Mediul de dezvoltare folosit este Arduino IDE, schema bloc a fost realizata in Lucidchart, iar schema electrica in EAGLE. De asemenea am folosit librăriile LiquidCrystal.h pentru LCD si EEPROM.h pentru memoria EEPROM. | ||
Line 60: | Line 52: | ||
== Variabile si utilizare == | == Variabile si utilizare == | ||
- | ** Definire pini si macro-uri: ** | + | ** Definire pini și macro-uri: ** |
* const int rs = 12, en = 11, d4 = 5, d5 = 4, d6 = 10, d7 = 2 -> pentru LCD LiquidCrystal lcd(rs, en, d4, d5, d6, d7); | * const int rs = 12, en = 11, d4 = 5, d5 = 4, d6 = 10, d7 = 2 -> pentru LCD LiquidCrystal lcd(rs, en, d4, d5, d6, d7); | ||
* #define redPin A3, greenPin A4, bluePin A5 -> pini pentru Led-ul RGB | * #define redPin A3, greenPin A4, bluePin A5 -> pini pentru Led-ul RGB | ||
* #define BUTTON_GameState 3, BUTTON_UP 9, BUTTON_DOWN 8, BUTTON_RIGHT 7, BUTTON_LEFT 6 -> pini pentru butoane | * #define BUTTON_GameState 3, BUTTON_UP 9, BUTTON_DOWN 8, BUTTON_RIGHT 7, BUTTON_LEFT 6 -> pini pentru butoane | ||
- | * #define GRAPHIC_WIDTH 16, GRAPHIC_HEIGHT 4, DEBOUNCE_DURATION 25 ->variable pentru dimensiunea interfetei jocului si a duratei de debounce | + | * #define GRAPHIC_WIDTH 16, GRAPHIC_HEIGHT 4, DEBOUNCE_DURATION 25 ->variable pentru dimensiunea interfeței jocului și a duratei de debounce |
** Variabile globale: ** | ** Variabile globale: ** | ||
Line 71: | Line 63: | ||
* enum DisplayItem {GRAPHIC_ITEM_NONE, GRAPHIC_ITEM_A, GRAPHIC_ITEM_B, GRAPHIC_ITEM_NUM}; | * enum DisplayItem {GRAPHIC_ITEM_NONE, GRAPHIC_ITEM_A, GRAPHIC_ITEM_B, GRAPHIC_ITEM_NUM}; | ||
* enum {GAME_MENU, GAME_PLAY, GAME_LOSE, GAME_WIN, GAME_SCORES,GAME_NAMESCORE} gameState; | * enum {GAME_MENU, GAME_PLAY, GAME_LOSE, GAME_WIN, GAME_SCORES,GAME_NAMESCORE} gameState; | ||
- | * enum {SNAKE_LEFT,SNAKE_UP,SNAKE_RIGHT,SNAKE_DOWN} snakeDirection; -> definire stari joc/snake si setare graphica a interfetei / RAM-ului jocului ; | + | * enum {SNAKE_LEFT,SNAKE_UP,SNAKE_RIGHT,SNAKE_DOWN} snakeDirection; -> definire stări joc/snake și setare grafică a interfeței / RAM-ului jocului |
* byte block[3] = {B01110, B11111, B01110,} -> corp snake | * byte block[3] = {B01110, B11111, B01110,} -> corp snake | ||
* byte apple[3] = {B00100, B01110, B00100,} -> corp apple | * byte apple[3] = {B00100, B01110, B00100,} -> corp apple | ||
- | * volatile bool Interrupt -> ajuta la verificarea daca a avut loc o intrerupere | + | * volatile bool Interrupt -> verifică dacă a avut loc o întrerupere |
- | * bool pressed -> ajuta la verificarea ca un buton a fost apasat | + | * bool pressed -> verifică dacă un buton a fost apăsat |
- | * const int max_dimension = GRAPHIC_HEIGHT*GRAPHIC_WIDTH -> dimensiunea maxima posibila | + | * const int max_dimension = GRAPHIC_HEIGHT*GRAPHIC_WIDTH -> dimensiunea maximă posibilă |
- | * size_t snakeLength = 0 -> intializare varibila care o sa salveze dimensiunea snake-ului | + | * size_t snakeLength = 0 -> inițializare variabilă care o să salveze dimensiunea snake-ului |
- | * int a[4] -> folosit in a salva highscore-urile in EEPROM | + | * int a[4] -> folosit pentru a salva highscore-urile in EEPROM |
- | * hue -> folosita in a seta culoare led-ului RGB | + | * hue -> folosită pentru setarea culorii led-ului RGB |
- | * String Name1thPlace,Name2thPlace,Name3thPlace,Name4thPlace ->salvam in oridine numele care au obtinut highscore | + | * String Name1thPlace,Name2thPlace,Name3thPlace,Name4thPlace -> salvăm în ordine numele care au obținut highscore |
- | * const char chars[] = {'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z'} -> salvam literele pentru setarea numelui in caz de highscore | + | * const char chars[] = {'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z'} -> salvăm literele pentru setarea numelui în caz de highscore |
- | * char setName[3] -> o varibaila temporara prin care salvam valorile anterioare ale numelor | + | * char setName[3] -> o variabilă temporară în care salvam valorile anterioare ale numelor |
* struct Pos {uint8_t x=0, y=0;}; | * struct Pos {uint8_t x=0, y=0;}; | ||
* struct Pos applePos; | * struct Pos applePos; | ||
- | * struct Pos snakePosHistory[max_dimension] -> intializare pozitii initiale snake/apple | + | * struct Pos snakePosHistory[max_dimension] -> poziții initiale snake/apple |
- | * unsigned long lastGameUpdateTick = 0 -> o sa salveze progresiv timpul ultimului frame al jocului | + | * unsigned long lastGameUpdateTick = 0 -> salvează progresiv timpul ultimului frame al jocului |
* unsigned long gameUpdateInterval = 850 -> rata de refesh a jocului | * unsigned long gameUpdateInterval = 850 -> rata de refesh a jocului | ||
* uint8_t graphicRam[GRAPHIC_WIDTH*2/8][GRAPHIC_HEIGHT] -> definire dimensiune RAM | * uint8_t graphicRam[GRAPHIC_WIDTH*2/8][GRAPHIC_HEIGHT] -> definire dimensiune RAM | ||
== Funcții == | == Funcții == | ||
+ | |||
+ | * void BtnInterrupt() -> funcția de întrerupere a butonului BUTTON_GameState | ||
+ | * bool debounce_activate_edge(unsigned long* debounceStart), void debounce_deactivate(unsigned long* debounceStart) -> funcții care stabilesc și verifică dacă valoarea logică a unui buton este cea corespunzatoare (atât după apăsarea lui, cât și dacă apar efecte mecanice/zgomot). | ||
+ | |||
+ | * void graphic_flush(), void graphic_generate_characters(), void graphic_clear(), void graphic_add_item(uint8_t x, uint8_t y, enum DisplayItem item) -> funcții care generează RAM-ul jocului și prin care jocul, chiar dacă e pe un lcd 16x2, este jucat pe 4 linii. De asemenea, sunt definite și generate modelele snake-ului si ale marului | ||
+ | |||
+ | * void setLedColorHSV(int h, double s, double v) | ||
+ | * void setLedColor(int redValue, int greenValue, int blueValue) -> funcțile date la laborator pentru a seta culoarea rgb-ului mai usor. | ||
+ | * void game_new_apple_pos() -> generează o poziție random pentru măr. De asemenea, se asigură că un măr nu se generează pe poziția snake-ului | ||
+ | * void game_calculate_logic() -> calculează mișcarea și direcția snake-ului, verifică dacă s-a produs o coloziune (perete/ self) și mărește rata de refresh a jocului dacă snake-ul a mâncat un măr (pana la un maxim al scorului de 20) | ||
+ | |||
+ | * void game_calculate_display() -> schimbă Game State-ul curent al jocului dacă s-a intâmplat un eveniment (de exemplu: jucatorul a pierdut sau a câștigat) | ||
+ | * void Game_INIT() -> starea inițială a jocului (cea inițializată în setup) | ||
+ | * void Game_LOSE() -> starea atunci când jucătorul pierde | ||
+ | * void Game_MAIN() -> starea în care este prezentat ecranul de început | ||
+ | * void Game_WIN() -> starea atunci când jucătorul câștigă | ||
+ | * void Game_PLAY() -> stare care generează snake-ul și mărul la început | ||
+ | * void Game_CHECKHIGHSCORES() -> verifică dacă jucătorul curent a obținut un scor mai mare decât cei salvați în memoria EEPROM | ||
+ | * void Game_HIGHSCORES() -> afișează cei mai buni 4 jucatori cu cele mai mari score-uri și schimbă în memorie top-ul în cazul în care alt jucător a obținut un highscore mai bun | ||
+ | |||
+ | * void Test_SnakeLength() -> funcție care pune un 0 în fața scorului în caz ca acesta este mai mic decat 9 (pur estetic) | ||
+ | * void rgb_color() -> setează culoarea Led-ului RGB in funcție de cât de mare e scor-ul (verde -> albastru -> turcoaz -> roz -> portocaliu) | ||
+ | * void writeStringToEEPROM(int addrOffset, const String &strToWrite) -> permite scrierea în memoriea EEPROM | ||
+ | * String readStringFromEEPROM(int addrOffset) -> permite citirea din memoria EEPROM | ||
** setup() ** | ** setup() ** | ||
+ | |||
+ | void setup(){ | ||
+ | pinMode(redPin,OUTPUT); | ||
+ | pinMode(greenPin,OUTPUT); | ||
+ | pinMode(bluePin,OUTPUT); | ||
+ | pinMode(BUTTON_GameState, INPUT_PULLUP); | ||
+ | pinMode(BUTTON_UP, INPUT_PULLUP); | ||
+ | pinMode(BUTTON_RIGHT, INPUT_PULLUP); | ||
+ | pinMode(BUTTON_LEFT, INPUT_PULLUP); | ||
+ | pinMode(BUTTON_DOWN, INPUT_PULLUP); | ||
+ | attachInterrupt(digitalPinToInterrupt(BUTTON_GameState), BtnInterrupt, FALLING); | ||
+ | graphic_generate_characters(); | ||
+ | Game_MAIN(); | ||
+ | gameState = GAME_MENU; | ||
+ | } | ||
+ | |||
+ | Definesc: | ||
+ | * pinii pentru Led-ul RGB ca OUTPUT (low-impedance state) astfel permințând să treacă curent prin ei. | ||
+ | * pinii pentru butoane ca INPUT_PULLUP folosiți să seteze o valoare fixă pentru un pin, în cazul nostru, dacă butonul este apăsat, acesta o să fie activ pe 0. | ||
+ | * o întrerupe pentru butonul BUTTON_GameState aflat pe pinul 3. Atunci când este apasat, generează în avans caracterele jocului și se apelează funcția pentru interfața inițiala a jocului. | ||
** loop() ** | ** loop() ** | ||
+ | |||
+ | if(Interrupt){ // verifică dacă a apărut o întrerupere | ||
+ | delay(5*DEBOUNCE_DURATION); // un delay cu rol de debounce | ||
+ | switch(gameState){...} // schimbă starea curentă a jocului prematur la apăsarea butonului GameState | ||
+ | Interrupt = false;} // resteaza valoarea setată in întrerupere până la următoarea întrerupere | ||
+ | |||
+ | if(digitalRead(BUTTON_UP) == pressed){ // verifică dacă butonul respectiv a fost apelat | ||
+ | if(debounce_activate_edge(&debCountBUTTON_UP)){ -// verifică debounce-ul | ||
+ | snakeDirection=SNAKE_UP; // schimbă direcția snake-ului | ||
+ | } | ||
+ | }else{ | ||
+ | debounce_deactivate(&debCountBUTTON_UP); // în cazul în care butonul nu a fost apăsat, resetează timer-ul de debounce | ||
+ | } | ||
+ | |||
+ | Același tipar de verificare este apelat pentru restul butoanelor care definesc mișcarea snake-ului. | ||
+ | |||
+ | if(millis()-lastGameUpdateTick > gameUpdateInterval){ | ||
+ | game_calculate_logic(); | ||
+ | game_calculate_display(); | ||
+ | graphic_clear(); | ||
+ | rgb_color(); | ||
+ | lastGameUpdateTick = millis(); | ||
+ | } // verifica constant dacă jocul trebuie să-ți dea refresh să recalculeze starea jocului, culoarea led-ului, dimensiunea, pozitia snake-ului și a mărului | ||
+ | |||
===== Rezultate Obţinute ===== | ===== Rezultate Obţinute ===== | ||
Line 106: | Line 166: | ||
{{:pm:prj2022:imacovei:snake_lost.jpg?800|}} | {{:pm:prj2022:imacovei:snake_lost.jpg?800|}} | ||
- | |||
- | {{:pm:prj2022:imacovei:snake_name_highscore.jpg?800|}} | ||
- | |||
- | {{:pm:prj2022:imacovei:snake_highscore.jpg?800|}} | ||
Demo youtube: https://www.youtube.com/watch?v=DwJfF1_lE9Y | Demo youtube: https://www.youtube.com/watch?v=DwJfF1_lE9Y | ||
Line 119: | Line 175: | ||
===== Download ===== | ===== Download ===== | ||
- | {{:pm:prj2022:imacovei:snake_nistorandreeaiuliana.zip|}} | + | {{:pm:prj2022:imacovei:proiect_pm.zip|}} |
+ | |||
===== Jurnal ===== | ===== Jurnal ===== | ||
- | <note tip> | + | |
* 13.04.2022 : Alegere proiect | * 13.04.2022 : Alegere proiect | ||
* 20.04.2022 : Realizare pagină | * 20.04.2022 : Realizare pagină | ||
Line 129: | Line 187: | ||
* 20.05.2022 : Realizare schemă electrică EAGLE | * 20.05.2022 : Realizare schemă electrică EAGLE | ||
* 23.05.2022 : Finalizare pagină wiki | * 23.05.2022 : Finalizare pagină wiki | ||
- | </note> | + | |
===== Bibliografie/Resurse ===== | ===== Bibliografie/Resurse ===== | ||
- | <note> | + | [[https://ocw.cs.pub.ro/courses/pm/lab/lab3-2022]] |
- | Listă cu documente, datasheet-uri, resurse Internet folosite, eventual grupate pe **Resurse Software** şi **Resurse Hardware**. | + | |
- | </note> | + | |
[[https://www.arduino.cc/en/Tutorial/BuiltInExamples/Debounce]] | [[https://www.arduino.cc/en/Tutorial/BuiltInExamples/Debounce]] |