Differences

This shows you the differences between two versions of the page.

Link to this comparison view

pm:prj2024:azamfir:ana_maria.toader02 [2024/05/23 21:09]
ana_maria.toader02 [Bibliografie/Resurse]
pm:prj2024:azamfir:ana_maria.toader02 [2024/05/27 03:27] (current)
ana_maria.toader02 [Rezultate Obţinute]
Line 10: Line 10:
   * un board (solvable) randomizat este generat pentru fiecare nou joc   * un board (solvable) randomizat este generat pentru fiecare nou joc
   * un buzzer emite sunete la realizarea unei mișcări greșite sau la câștigarea jocului   * un buzzer emite sunete la realizarea unei mișcări greșite sau la câștigarea jocului
 +  * fiecare joc are o limită de timp de 5 minute; la expirarea timpului, jocul este pierdut
 Scopul proiectului este realizarea unui joc entertaining. Scopul proiectului este realizarea unui joc entertaining.
 ===== Descriere generală ===== ===== Descriere generală =====
Line 35: Line 36:
 | Fire tată-tată | [[https://​www.optimusdigital.ro/​ro/​fire-fire-mufate/​885-set-fire-tata-tata-10p-10-cm.html|Set fire tată-tată]] |  2  |  2,85 lei  | | Fire tată-tată | [[https://​www.optimusdigital.ro/​ro/​fire-fire-mufate/​885-set-fire-tata-tata-10p-10-cm.html|Set fire tată-tată]] |  2  |  2,85 lei  |
 ^   Cost total: 150,87 lei  |||| ^   Cost total: 150,87 lei  ||||
 +
 +**Cablaj final:**\\
 +{{:​pm:​prj2024:​azamfir:​ana_maria.toader02:​cablaj_final.jpeg?​500|}}
 +
 +
 ===== Software Design ===== ===== Software Design =====
 ==== Setup ==== ==== Setup ====
Line 48: Line 54:
  
 ==== Implementare ==== ==== Implementare ====
 +**Logica jocului**\\
 +Tabla de joc este definită ca un array bidimensional în care fiecare celulă poate lua una dintre valorile predefinite ce simbolizează elementele de joc //(BLANK, BOMB, RED_BOMB, FLAG, EMPTY, ONE, TWO, THREE, FOUR, FIVE, SIX, SEVEN, EIGHT)//.
 +<code cpp>​extern unsigned int board[ROWS][COLUMNS];</​code>​
 +Pentru implementarea logicii jocului am scris funcții pentru diverse funcționalități:​
 +  * inițializarea bombelor în poziții random pe grid (tabla este randomizată la fiecare joc nou)
 +  * indicarea poziției pe grid prin highlight-ul unei celule
 +  * input handling pentru acțiunile jucătorului (apăsarea butoanelor, mișcarea joystick-ului sau apăsarea switch-ului de pe joystick)
 +  * descoperirea unei singure celule ce conține un număr sau a tuturor celulelor libere adiacente în cazul unei celule goale
 +  * amplasarea de flag-uri
 +  * afișarea unui timer care se actualizează la interval fix de o secundă
 +  * resetarea jocului la apăsarea switch-ului de pe joystick (cu reinițializarea tuturor parametrilor jocului, a timer-ului și randomizarea tablei)
 +  * verificarea condițiilor de win / lose și în funcție de caz:
 +    * afișarea mesajelor specifice (GAME OVER sau CONGRATULATIONS)
 +    * emiterea unor sunete distinctive acționând buzzer-ul
 +    * la finalul jocului singura acțiune care mai este responsive este apăsarea switch-ului de pe joystick care duce la începerea unui joc nou
 +\\
 +**Grafică**\\
 +Pentru a crea imaginile distinctive jocului pentru fiecare celulă posibilă am desenat imagini de 20x20px pe care le-am convertit folosind un [[https://​javl.github.io/​image2cpp/​|tool]] online în bitmap-uri grayscale de 8biți per pixel. Le-am afișat la poziții corespunzătoare pe ecran folosind funcția ''​**void Adafruit_GFX::​drawBitmap(int16_t x, int16_t y, const uint8_t bitmap[], int16_t w, int16_t h, uint16_t color)**''​ din biblioteca **Adafruit_GFX**. Am adăugat culori prin setarea //​foreground color//. \\
 +
 +{{:​pm:​prj2024:​azamfir:​ana_maria.toader02:​bomb.png?​130 |}}<code c>
 +const unsigned char bomb[] PROGMEM = {
 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0xf0, 0x00, 0x0b, 0xfd, 0x00, 0x07,
 + 0xfe, 0x00, 0x16, 0x7e, 0x80, 0x0e, 0x7f, 0x00, 0x0f, 0xff, 0x00, 0x1f, 0xff, 0x80, 0x1f, 0xff,
 + 0x80, 0x0f, 0xff, 0x00, 0x0f, 0xff, 0x00, 0x17, 0xfe, 0x80, 0x07, 0xfe, 0x00, 0x0b, 0xfd, 0x00,
 + 0x00, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
 +};
 +</​code>​
 +\\
 +**Buzzer**\\
 +La sfârșitul jocului, buzzer-ul emite sunete distinctive. Am ales două melodii din [[https://​github.com/​robsoncouto/​arduino-songs|arduino-songs]] pentru cazurile de victorie / înfrângere.\\
 +\\
 **Timer**\\ **Timer**\\
 Microcontroller-ul **//​ATmega328p//​** conține 3 unități de timer, două pe 8 biți (//Timer0// și //Timer2//) și unul pe 16 biți (//​Timer1//​). \\ Microcontroller-ul **//​ATmega328p//​** conține 3 unități de timer, două pe 8 biți (//Timer0// și //Timer2//) și unul pe 16 biți (//​Timer1//​). \\
Line 96: Line 133:
 } }
 </​code>​ </​code>​
 +\\
 +
 +**Întreruperi**\\
 +La inițializare,​ am activat mecanismul de întreruperi prin activarea bitului **//I//** din registrul **//​SREG//​**.
 +<code cpp>
 +/* Activate interrupts */
 +sei();
 +</​code>​
 +Am definit două rutine pentru tratarea întreruperilor externe (pentru apăsarea butoanelor și pentru apăsarea butonului de la joystick) și una pentru tratarea întreruperilor interne folosind Timer1. \\
 +
 +**Configurarea componentelor care vor trimite întreruperi:​**
 +  * cele două butoane sunt conectate la același pin **//​BUTTON_INTERRUPT//​** pentru întreruperi
 +<code cpp>
 +/* initialize button pins */
 +pinMode(BLUE_BUTTON,​ INPUT);
 +pinMode(RED_BUTTON,​ INPUT);
 +
 +pinMode(BUTTON_INTERRUPT,​ INPUT);
 +attachInterrupt(digitalPinToInterrupt(BUTTON_INTERRUPT),​ ISR_button, RISING);
 +</​code>​
 +Am folosit funcția ''​attachInterrupt''​ pentru a atașa rutina **//​ISR_button//​** evenimentelor de pe pinul corespunzător butoanelor. Parametrul ''​RISING''​ definește momentul în care va fi declanșată întreruperea - atunci când valoarea pinului trece de la LOW la HIGH (la apăsarea unuia dintre butoane). \\
 +  * pinul **//SW//** al joystick-ului este conectat la pinul **//​JOYSTICK_INTERRUPT//​** de pe plăcuță, căruia i-am asociat rutina **//​ISR_joystick//​**
 +<code cpp>
 +/* initialize joystick pins */
 +pinMode(JOYSTICK_X,​ INPUT);
 +pinMode(JOYSTICK_Y,​ INPUT);
 +
 +pinMode(JOYSTICK_INTERRUPT,​ INPUT);
 +digitalWrite(JOYSTICK_INTERRUPT,​ HIGH);
 +attachInterrupt(digitalPinToInterrupt(JOYSTICK_INTERRUPT),​ ISR_joystick,​ RISING);
 +</​code>​
 +
 +Toate variabilele care vor fi modificate într-o rutină de tratare a întreruperilor trebuie marcate ca **''​volatile''​** pentru a indica compilatorului să nu treacă variabila prin cache. Orice acces la o variabilă **''​volatile''​** se va face prin RAM.
 +<code c>
 +/* Initialize volatile variables used with button interrupts */
 +volatile bool blueButtonFlag = false;
 +volatile bool redButtonFlag = false;
 +
 +volatile unsigned long lastPressRed = 0;
 +volatile unsigned long lastPressBlue = 0;
 +
 +volatile bool joystickButtonFlag = false;
 +</​code>​
 +
 +**Definirea rutinelor de tratare a întreruperilor:​**
 +  * pentru **butoane** - declanșarea întreruperii are loc la apăsarea unuia dintre butoane, moment în care se verifică care dintre butoane a fost apăsat și se setează flagul corespunzător acestuia (**//​blueButtonFlag//​** sau **//​redButtonFlag//​**. Pentru a trata existența zgomotului, am implementat debouncing software pentru butoane.
 +<code cpp>
 +void ISR_button() {
 +    buttonPressTime = millis();
 +    if (digitalRead(BLUE_BUTTON) && buttonPressTime - lastPressBlue > debounceTime) {
 +        lastPressBlue = buttonPressTime;​
 +        blueButtonFlag = true;
 +
 +    } else if (digitalRead(RED_BUTTON) && buttonPressTime - lastPressRed > debounceTime) {
 +        lastPressRed = buttonPressTime;​
 +        redButtonFlag = true;
 +    }
 +}
 +</​code>​
 +  * pentru **joystick** - declanșarea întreruperii are loc la apăsarea switch-ului,​ iar rutina de tratare a acesteia setează flag-ul **//​joystickButtonFlag//​** care va fi folosit în logica programului
 +<code cpp>
 +void ISR_joystick() {
 +    joystickButtonFlag = true;
 +}
 +</​code>​
 +  * pentru **Timer1** - întreruperea este declanșată la intervale fixe de o secundă; în rutina de tratare se resetează registrul counter la zero pentru a putea relua numărătoarea,​ se decrementează valoarea timer-ului și se setează flag-ul corespunzător **timerFlag** pentru marcarea faptului că a avut loc întreruperea în fluxul principal al programului
 +<code cpp>
 +ISR(TIMER1_COMPA_vect){
 +    TCNT1 = 0;   /* Reset counter register */
 +
 +    timer--;
 +    timerFlag = true;
 +}
 +</​code>​
 +Parametrul **TIMER1_COMPA_vect** indică faptul că se face Compare Match cu pragul A al timerului.
 ===== Rezultate Obţinute ===== ===== Rezultate Obţinute =====
 +  * inițializarea jocului, cu setarea timer-ului la 5 minute
 +{{:​pm:​prj2024:​azamfir:​ana_maria.toader02:​init.gif?​700|}}
  
-<note tip> +  * eliberarea unui grup de celule 
-Care au fost rezultatele obţinute în urma realizării proiectului vostru. +{{:​pm:​prj2024:​azamfir:​ana_maria.toader02:​clear_multiple_cells.gif?​700|}}
-</​note>​+
  
-===== Concluzii =====+  * sfârșitul jocului 
 +{{:​pm:​prj2024:​azamfir:​ana_maria.toader02:​game_won.gif?​700|}} 
 +{{:​pm:​prj2024:​azamfir:​ana_maria.toader02:​game_over.gif?​700|}}
  
-===== Download =====+  * resetarea jocului la apăsarea switch-ului de pe joystick, cu resetarea timer-ului la 5 minute 
 +{{:​pm:​prj2024:​azamfir:​ana_maria.toader02:​reset.gif?​700|}}
  
-<note warning> +===== Concluzii ===== 
-O arhivă (sau mai multe dacă este cazul) cu fişierele obţinute în urma realizării proiectului:​ surse, scheme, etc. Un fişier READMEun ChangeLog, un script de compilare şi copiere automată pe uC crează întotdeauna o impresie bună ;-).+Un proiect interesantmă bucur că am obținut ceva funcțional.
  
-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**+Deși am ales un proiect simplu, cu puține componente hardware (pentru a nu avea mari bătăde cap :-)) am avut mari bătăi de cap mîncercând să fac display-ul să funcționeze la tensiunea de alimentare de 3v3
-</note>+===== Download ===== 
 +[[https://​github.com/​anatoad/​Minesweeper-Arduino|Github repo]]
  
 ===== Jurnal ===== ===== Jurnal =====
 +  * 01/05/2024 - alegere temă proiect
   * 04/05/2024 - finalizarea documentației + schema bloc\\   * 04/05/2024 - finalizarea documentației + schema bloc\\
   * 07/05/2024 - testarea componentelor hardware\\   * 07/05/2024 - testarea componentelor hardware\\
   * 12/05/2024 - finalizare hardware design\\   * 12/05/2024 - finalizare hardware design\\
 +  * 17/05/2024 - Milestone 2 (hardware) \\
 +  * 21/05/2024 - start code development \\
 +  * 24/05/2024 - Milestone 3 (software) \\
  
 Probleme întâmpinate:​​ Probleme întâmpinate:​​
-  * Alimentarea modulului LCD funcționează la tensiunea de 3.3V, iar tensiunea de funcționare a plăcii de dezvoltare este de 5V. De aceea, am încercat inițial să folosesc un translator de nivel logic. După mult timp pierdut (și un display ars :-\) nu am reușit să îl fac să funcționeze. În urma indicațiilor laborantului,​​ am ales să introduc în circuit rezistențe de 10kΩ.+  ​* Plăcuța de dezvoltare Arduino UNO R3 are doar doi pini digitali ce suportă întreruperi externe (D2, D3). Aveam nevoie să configurez 3 componente pentru a folosi întreruperi (două butoane și un joystick), dar doar doi pini disponibili. Am folosit două diode pentru a multiplexa butoanele pe același pin. 
 +  ​* Alimentarea modulului LCD funcționează la tensiunea de 3.3V, iar tensiunea de funcționare a plăcii de dezvoltare este de 5V. Am încercat inițial să folosesc un translator de nivel logic. După mult timp pierdut (și un display ars :-\) nu am reușit să îl fac să funcționeze. În urma indicațiilor laborantului,​​ am ales să introduc în circuit rezistențe de 10kΩ
 +  * Active buzzer module pe care intenționam să îl folosesc inițial nu funcționa, l-am înlocuit cu un buzzer pasiv de 5V.
 ===== Bibliografie/​Resurse ===== ===== Bibliografie/​Resurse =====
 [[https://​docs.arduino.cc/​resources/​datasheets/​A000066-datasheet.pdf|Datasheet Arduino UNO R3]]\\ [[https://​docs.arduino.cc/​resources/​datasheets/​A000066-datasheet.pdf|Datasheet Arduino UNO R3]]\\
 [[https://​ww1.microchip.com/​downloads/​en/​DeviceDoc/​Atmel-7810-Automotive-Microcontrollers-ATmega328P_Datasheet.pdf|Datasheet ATmega328P]]\\ [[https://​ww1.microchip.com/​downloads/​en/​DeviceDoc/​Atmel-7810-Automotive-Microcontrollers-ATmega328P_Datasheet.pdf|Datasheet ATmega328P]]\\
-[[https://​cdn-shop.adafruit.com/​datasheets/​ILI9341.pdf|Datasheet ILI9341]]+[[https://​cdn-shop.adafruit.com/​datasheets/​ILI9341.pdf|Datasheet ILI9341]]\\ 
 +[[https://​github.com/​adafruit/​Adafruit-GFX-Library|Adafruit GFX Library]]\\ 
 +[[https://​github.com/​robsoncouto/​arduino-songs|arduino-songs]]
  
 <​html><​a class="​media mediafile mf_pdf"​ href="?​do=export_pdf">​Export to PDF</​a></​html>​ <​html><​a class="​media mediafile mf_pdf"​ href="?​do=export_pdf">​Export to PDF</​a></​html>​
  
  
pm/prj2024/azamfir/ana_maria.toader02.1716487766.txt.gz · Last modified: 2024/05/23 21:09 by ana_maria.toader02
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