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 20:53]
ana_maria.toader02 [Software Design]
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>​+ 
 +  * sfârșitul jocului 
 +{{:​pm:​prj2024:​azamfir:​ana_maria.toader02:​game_won.gif?​700|}} 
 +{{:​pm:​prj2024:​azamfir:​ana_maria.toader02:​game_over.gif?​700|}} 
 + 
 +  * 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|}}
  
 ===== Concluzii ===== ===== Concluzii =====
 +Un proiect interesant, mă bucur că am obținut ceva funcțional.
  
 +Deși am ales un proiect simplu, cu puține componente hardware (pentru a nu avea mari bătăi 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.
 ===== Download ===== ===== Download =====
- +[[https://github.com/​anatoad/​Minesweeper-Arduino|Github repo]]
-<note warning>​ +
-O arhivă (sau mai multe dacă este cazul) cu fişierele obţinute în urma realizării proiectuluisurse, scheme, etcUn 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**. +
-</​note>​+
  
 ===== 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 =====
- 
-<​note>​ 
-Listă cu documente, datasheet-uri,​ resurse Internet folosite 
-</​note>​ 
 [[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://​cdn-shop.adafruit.com/​datasheets/​ILI9341.pdf|Datasheet ILI9341]]+[[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://​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.1716486793.txt.gz · Last modified: 2024/05/23 20:53 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