This shows you the differences between two versions of the page.
|
pm:prj2022:cstan:21 [2022/05/29 19:53] Vlad_Andrei.Caruntu [Hardware Design] |
pm:prj2022:cstan:21 [2022/06/02 13:45] (current) Vlad_Andrei.Caruntu [Introduction] |
||
|---|---|---|---|
| Line 4: | Line 4: | ||
| <note tip> | <note tip> | ||
| Caruntu Vlad-Andrei 1222A | Caruntu Vlad-Andrei 1222A | ||
| - | This project is meant to recreate the all-famous game known as Tetris. It does this by displaying the game in an distinct and charming way, through LED lightups which the blocks and their falling across a 32x8 Matrix of LEDs. | + | This project is meant to recreate the all-famous game known as Tetris. It does this by displaying the game in a distinct and charming way, through LED lightups which the blocks and their falling across a 32x8 Matrix of LEDs. |
| In case you don't know what the game consists of, here is a short description of it: Tetris is a puzzle game in which geometric shapes called "tetrominoes" fall down onto a playing field, and the player has to arrange them to form gapless lines. | In case you don't know what the game consists of, here is a short description of it: Tetris is a puzzle game in which geometric shapes called "tetrominoes" fall down onto a playing field, and the player has to arrange them to form gapless lines. | ||
| - | This particular variant of the game allows for a competitive multiplayer game to take place, by having 2 players stack blocks until one of them reaches the top and thus gets a game over. | ||
| </note> | </note> | ||
| ===== General Description ===== | ===== General Description ===== | ||
| Line 14: | Line 13: | ||
| </note> | </note> | ||
| - | {{TetrisDiagram.png}} | + | {{tetrisprojectidea.png}} |
| ===== Hardware Design ===== | ===== Hardware Design ===== | ||
| - | {{https://320volt.com/wp-content/uploads/2012/08/pic-tetris-circuit-schematic.gif}} | + | {{Tetris_Schematic.PNG}} |
| Parts List: | Parts List: | ||
| - | -4 8x8 LEB Matrices | + | -8x8 LED Matrices |
| - | -2 Breadboards with 4 Buttons each attached onto them | + | -Joystick |
| - | -2 Arduino Uno Boards | + | -Arduino Uno Board |
| -several Jumper Wires connecting the other components together | -several Jumper Wires connecting the other components together | ||
| ===== Software Design ===== | ===== Software Design ===== | ||
| + | //TETRIS by GEEKEE CEEBEE | ||
| + | /* THE CODE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
| + | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES | ||
| + | * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
| + | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT | ||
| + | * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, | ||
| + | * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | ||
| + | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR | ||
| + | * OTHER DEALINGS IN THE SOFTWARE. | ||
| + | */ | ||
| - | <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> | ||
| - | ===== Rezultate Obţinute ===== | + | #include < LedControl.h > |
| - | <note tip> | + | //We always have to include the library |
| - | Care au fost rezultatele obţinute în urma realizării proiectului vostru. | + | #include "LedControl.h" |
| - | </note> | + | |
| - | ===== Concluzii ===== | ||
| - | ===== Download ===== | + | //***************Global Variables and Definitions****************************************** |
| + | LedControl lc = LedControl(12, 11, 10, 4); | ||
| + | const int SW_pin = 2; // digital pin connected to SW | ||
| + | const int X_pin = A0; // analog pin connected to VRx | ||
| + | const int Y_pin = A1; | ||
| + | float r = 7.0; // row input | ||
| + | int c = 3; // column input | ||
| + | int add = 0; // address input | ||
| + | int add_prev = 1000; | ||
| + | int r_prev = 1000; | ||
| + | int c_prev = 1000; | ||
| + | int ro = 0; // to set block orientation | ||
| + | int ro_prev; | ||
| + | int c2; | ||
| + | float r2; | ||
| + | int check1, check2, check3, check4; | ||
| + | int left_check1, left_check2, left_check3, left_check4; | ||
| + | int right_check1, right_check2, right_check3, right_check4; | ||
| + | int block = 0; | ||
| - | <note warning> | + | //*******************Right Translate Functions************************** |
| - | 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ă ;-). | + | int Right_translate( int c1, boolean state1) { |
| + | int X = analogRead(X_pin); | ||
| + | if (state1 == true && X < 200) { | ||
| + | return c--; | ||
| + | } | ||
| + | else if (state1 == false && X < 200) { | ||
| + | return c; | ||
| + | } | ||
| + | } | ||
| - | 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 ===== | + | //*******************Left Translate Functions************************** |
| + | int Left_translate( int c1, boolean state1) { | ||
| + | int X = analogRead(X_pin); | ||
| + | if (state1 == true) { | ||
| + | if (X > 800) { | ||
| + | return c++; | ||
| + | } | ||
| + | } | ||
| + | else if (state1 == false) { | ||
| + | if (X > 800) { | ||
| + | return c; | ||
| + | } | ||
| + | } | ||
| + | } | ||
| - | <note tip> | ||
| - | Puteți avea și o secțiune de jurnal în care să poată urmări asistentul de proiect progresul proiectului. | ||
| - | </note> | ||
| - | ===== Bibliografie/Resurse ===== | + | //*******************Down Translate Functions************************** |
| + | float Down_translate( float r1, boolean state1) { | ||
| + | int Y = analogRead(Y_pin); | ||
| + | //Serial.print(" Y_pin: "); | ||
| + | // Serial.print(Y); | ||
| + | if (state1 == true ) { | ||
| + | if (Y > 800) { | ||
| + | return r--; | ||
| + | } | ||
| + | } | ||
| + | else if (state1 == false) { | ||
| + | if (Y > 800) { | ||
| + | return r; | ||
| + | } | ||
| + | } | ||
| + | } | ||
| - | <note> | ||
| - | Listă cu documente, datasheet-uri, resurse Internet folosite, eventual grupate pe **Resurse Software** şi **Resurse Hardware**. | ||
| - | </note> | ||
| - | <html><a class="media mediafile mf_pdf" href="?do=export_pdf">Export to PDF</a></html> | + | |
| + | |||
| + | |||
| + | |||
| + | //************************************ I BLOCK FUNCTION ************************************** | ||
| + | void I_block(int add, float r, int c, int ro) { | ||
| + | |||
| + | switch (ro) { | ||
| + | |||
| + | case 0: // Horizontal Orientation | ||
| + | if (ro_prev == 1) { | ||
| + | lc.setLed(add_prev, r_prev, c_prev, false); | ||
| + | lc.setLed(add_prev, r_prev - 1, c_prev, false); | ||
| + | lc.setLed(add_prev, r_prev - 2, c_prev, false); | ||
| + | lc.setLed(add_prev, r_prev - 3, c_prev, false); | ||
| + | } | ||
| + | |||
| + | |||
| + | lc.setLed(add_prev, r_prev, c_prev, false); | ||
| + | lc.setLed(add_prev, r_prev, c_prev - 1, false); | ||
| + | lc.setLed(add_prev, r_prev, c_prev - 2, false); | ||
| + | lc.setLed(add_prev, r_prev, c_prev - 3, false); | ||
| + | |||
| + | lc.setLed(add, r, c, true); | ||
| + | lc.setLed(add, r, c - 1, true); | ||
| + | lc.setLed(add, r, c - 2, true); | ||
| + | lc.setLed(add, r, c - 3, true); | ||
| + | |||
| + | check1 = lc.getstatus(add, r - 1, c); | ||
| + | check2 = lc.getstatus(add, r - 1, c - 1); | ||
| + | check3 = lc.getstatus(add, r - 1, c - 2); | ||
| + | check4 = lc.getstatus(add, r - 1, c - 3); | ||
| + | left_check1 = lc.getstatus(add, r , c + 1); | ||
| + | right_check1 = lc.getstatus(add, r , c - 4); | ||
| + | |||
| + | add_prev = add; | ||
| + | r_prev = r; | ||
| + | c_prev = c; | ||
| + | ro_prev = ro; | ||
| + | |||
| + | |||
| + | break; | ||
| + | |||
| + | case 1: // Vertical Orientation | ||
| + | if (ro_prev == 0) { | ||
| + | lc.setLed(add_prev, r_prev, c_prev, false); | ||
| + | lc.setLed(add_prev, r_prev, c_prev - 1, false); | ||
| + | lc.setLed(add_prev, r_prev, c_prev - 2, false); | ||
| + | lc.setLed(add_prev, r_prev, c_prev - 3, false); | ||
| + | } | ||
| + | |||
| + | lc.setLed(add_prev, r_prev, c_prev, false); | ||
| + | lc.setLed(add_prev, r_prev - 1, c_prev, false); | ||
| + | lc.setLed(add_prev, r_prev - 2, c_prev, false); | ||
| + | lc.setLed(add_prev, r_prev - 3, c_prev, false); | ||
| + | |||
| + | lc.setLed(add, r, c, true); | ||
| + | lc.setLed(add, r - 1, c, true); | ||
| + | lc.setLed(add, r - 2, c, true); | ||
| + | lc.setLed(add, r - 3, c, true); | ||
| + | |||
| + | check1 = lc.getstatus(add, r - 4, c); | ||
| + | left_check1 = lc.getstatus(add, r , c + 1); | ||
| + | |||
| + | right_check1 = lc.getstatus(add, r , c - 1); | ||
| + | |||
| + | |||
| + | add_prev = add; | ||
| + | r_prev = r; | ||
| + | c_prev = c; | ||
| + | ro_prev = ro; | ||
| + | |||
| + | break; | ||
| + | |||
| + | } | ||
| + | |||
| + | } | ||
| + | |||
| + | //************************************ S BLOCK FUNCTION ************************************** | ||
| + | void S_block(int add, float r, int c, int ro) { | ||
| + | |||
| + | switch (ro) { | ||
| + | |||
| + | case 0: // Horizontal Orientation | ||
| + | if (ro_prev == 1) { | ||
| + | |||
| + | lc.setLed(add_prev, r_prev, c_prev, false); | ||
| + | lc.setLed(add_prev, r_prev, c_prev - 1, false); | ||
| + | lc.setLed(add_prev, r_prev - 1, c_prev - 1, false); | ||
| + | lc.setLed(add_prev, r_prev + 1, c_prev, false); | ||
| + | |||
| + | } | ||
| + | lc.setLed(add_prev, r_prev, c_prev, false); | ||
| + | lc.setLed(add_prev, r_prev, c_prev - 1, false); | ||
| + | lc.setLed(add_prev, r_prev - 1, c_prev, false); | ||
| + | lc.setLed(add_prev, r_prev - 1, c_prev + 1, false); | ||
| + | |||
| + | |||
| + | lc.setLed(add, r, c, true); | ||
| + | lc.setLed(add, r, c - 1, true); | ||
| + | lc.setLed(add, r - 1, c, true); | ||
| + | lc.setLed(add, r - 1, c + 1, true); | ||
| + | |||
| + | check1 = lc.getstatus(add, r - 2, c); | ||
| + | check2 = lc.getstatus(add, r - 2, c + 1); | ||
| + | check3 = lc.getstatus(add, r - 1, c - 1); | ||
| + | left_check1 = lc.getstatus(add, r , c + 2); | ||
| + | right_check1 = lc.getstatus(add, r , c - 2); | ||
| + | |||
| + | |||
| + | add_prev = add; | ||
| + | r_prev = r; | ||
| + | c_prev = c; | ||
| + | ro_prev = ro; | ||
| + | |||
| + | break; | ||
| + | |||
| + | case 1: // Vertical Orientation | ||
| + | if (ro_prev == 0) { | ||
| + | lc.setLed(add_prev, r_prev, c_prev, false); | ||
| + | lc.setLed(add_prev, r_prev, c_prev - 1, false); | ||
| + | lc.setLed(add_prev, r_prev - 1, c_prev, false); | ||
| + | lc.setLed(add_prev, r_prev - 1, c_prev + 1, false); | ||
| + | } | ||
| + | |||
| + | lc.setLed(add_prev, r_prev, c_prev, false); | ||
| + | lc.setLed(add_prev, r_prev, c_prev - 1, false); | ||
| + | lc.setLed(add_prev, r_prev - 1, c_prev - 1, false); | ||
| + | lc.setLed(add_prev, r_prev + 1, c_prev, false); | ||
| + | |||
| + | lc.setLed(add, r, c, true); | ||
| + | lc.setLed(add, r, c - 1, true); | ||
| + | lc.setLed(add, r - 1, c - 1, true); | ||
| + | lc.setLed(add, r + 1, c, true); | ||
| + | |||
| + | check1 = lc.getstatus(add, r - 1, c); | ||
| + | check2 = lc.getstatus(add, r - 2, c - 1); | ||
| + | left_check1 = lc.getstatus(add, r , c + 1); | ||
| + | right_check1 = lc.getstatus(add, r , c - 2); | ||
| + | |||
| + | add_prev = add; | ||
| + | r_prev = r; | ||
| + | c_prev = c; | ||
| + | ro_prev = ro; | ||
| + | break; | ||
| + | |||
| + | } | ||
| + | |||
| + | } | ||
| + | |||
| + | |||
| + | |||
| + | |||
| + | //**************************************** MAIN SETUP **************************** | ||
| + | void setup() { | ||
| + | //we have already set the number of devices when we created the LedControl | ||
| + | int devices = lc.getDeviceCount(); | ||
| + | //lc.line_break(); | ||
| + | // int che = lc.getstatus(add, r, c); | ||
| + | pinMode(SW_pin, INPUT); | ||
| + | digitalWrite(SW_pin, HIGH); | ||
| + | randomSeed(analogRead(0)); | ||
| + | Serial.begin(9600); | ||
| + | //we have to init all devices in a loop | ||
| + | for (int address = 0; address < devices; address++) { | ||
| + | /*The MAX72XX is in power-saving mode on startup*/ | ||
| + | lc.shutdown(address, false); | ||
| + | /* Set the brightness to a medium values */ | ||
| + | lc.setIntensity(address, 8); | ||
| + | /* and clear the display */ | ||
| + | lc.clearDisplay(address); | ||
| + | } | ||
| + | |||
| + | } | ||
| + | |||
| + | |||
| + | //***************************** MAIN LOOP FUNCTION **************************** | ||
| + | void loop() { | ||
| + | block = random(-1, 2); // Block selection by randomly picking value between 0 and 1 | ||
| + | r = 8; // Starting row for new block | ||
| + | c = 3; // starting column for new block | ||
| + | add = 0; // address is 0 if using only one 8x8 LED module | ||
| + | |||
| + | switch (block) { | ||
| + | |||
| + | //*********************** I_block Horizontal **************** | ||
| + | case 1: | ||
| + | do { | ||
| + | // int X = analogRead(X_pin); | ||
| + | // int Y = analogRead(Y_pin); | ||
| + | int Rot = digitalRead(SW_pin); | ||
| + | if (Rot == LOW) { | ||
| + | ro++; | ||
| + | if (ro == 2) { | ||
| + | ro = 0; | ||
| + | } | ||
| + | } | ||
| + | |||
| + | |||
| + | if (c >= -1 && c <= 8) { | ||
| + | |||
| + | switch (ro) { | ||
| + | case 0: | ||
| + | if (c == 2 || c == 1 || c == 0) { | ||
| + | c = 3; | ||
| + | } | ||
| + | if (c == 8) { | ||
| + | c = 7; | ||
| + | } | ||
| + | if (left_check1 == 1 && right_check1 == 0) { | ||
| + | c = Right_translate(c, true); | ||
| + | Left_translate(c, false); | ||
| + | Down_translate(r, true); | ||
| + | } | ||
| + | else if (left_check1 == 0 && right_check1 == 1) { | ||
| + | c = Right_translate(c, false); | ||
| + | Left_translate(c, true); | ||
| + | Down_translate(r, true); | ||
| + | } | ||
| + | else if (left_check1 == 1 && right_check1 == 1) { | ||
| + | c = Right_translate(c, false); | ||
| + | Left_translate(c, false); | ||
| + | Down_translate(r, true); | ||
| + | } | ||
| + | |||
| + | |||
| + | else if (left_check1 == 0 && right_check1 == 0) { | ||
| + | c2 = Right_translate(c, true); | ||
| + | c2 = Left_translate(c, true); | ||
| + | r2 = Down_translate(r, true); | ||
| + | } | ||
| + | |||
| + | |||
| + | break; | ||
| + | |||
| + | //*************************** I block_Vertical ************** | ||
| + | |||
| + | case 1: | ||
| + | if (c == -1) { | ||
| + | c = 0; | ||
| + | } | ||
| + | if (c == 8) { | ||
| + | c = 7; | ||
| + | } | ||
| + | |||
| + | if (left_check1 == 1 && right_check1 == 0) { | ||
| + | c = Right_translate(c, true); | ||
| + | Left_translate(c, false); | ||
| + | Down_translate(r, true); | ||
| + | } | ||
| + | else if (left_check1 == 0 && right_check1 == 1) { | ||
| + | c = Right_translate(c, false); | ||
| + | Left_translate(c, true); | ||
| + | Down_translate(r, true); | ||
| + | } | ||
| + | else if (left_check1 == 1 && right_check1 == 1) { | ||
| + | c = Right_translate(c, false); | ||
| + | Left_translate(c, false); | ||
| + | Down_translate(r, true); | ||
| + | } | ||
| + | |||
| + | |||
| + | else if (left_check1 == 0 && right_check1 == 0) { | ||
| + | c2 = Right_translate(c, true); | ||
| + | c2 = Left_translate(c, true); | ||
| + | r2 = Down_translate(r, true); | ||
| + | } | ||
| + | |||
| + | |||
| + | break; | ||
| + | |||
| + | |||
| + | } | ||
| + | |||
| + | } | ||
| + | r = r - 0.125; | ||
| + | I_block(add, r, c, ro); | ||
| + | if (check1 == 1 || check2 == 1 || check3 == 1) { | ||
| + | r = 0.8; | ||
| + | } | ||
| + | delay(225); | ||
| + | } while (r > 0.9 ); | ||
| + | add_prev = 100; | ||
| + | r_prev = 100; | ||
| + | c_prev = 100; | ||
| + | break; | ||
| + | |||
| + | //*****************S_Block case***************** | ||
| + | |||
| + | case 0: | ||
| + | do { | ||
| + | |||
| + | int Rot = digitalRead(SW_pin); | ||
| + | if (Rot == LOW) { | ||
| + | ro++; | ||
| + | if (ro == 2) { | ||
| + | ro = 0; | ||
| + | } | ||
| + | } | ||
| + | |||
| + | |||
| + | if (c >= 0 && c <= 7) { | ||
| + | |||
| + | switch (ro) { | ||
| + | case 0: | ||
| + | if ( c == 0) { | ||
| + | c = 1; | ||
| + | } | ||
| + | if (c == 7) { | ||
| + | c = 6; | ||
| + | } | ||
| + | if (left_check1 == 1 && right_check1 == 0) { | ||
| + | c = Right_translate(c, true); | ||
| + | Left_translate(c, false); | ||
| + | Down_translate(r, true); | ||
| + | } | ||
| + | else if (left_check1 == 0 && right_check1 == 1) { | ||
| + | c = Right_translate(c, false); | ||
| + | Left_translate(c, true); | ||
| + | Down_translate(r, true); | ||
| + | } | ||
| + | else if (left_check1 == 1 && right_check1 == 1) { | ||
| + | c = Right_translate(c, false); | ||
| + | Left_translate(c, false); | ||
| + | Down_translate(r, true); | ||
| + | } | ||
| + | |||
| + | |||
| + | else if (left_check1 == 0 && right_check1 == 0) { | ||
| + | c2 = Right_translate(c, true); | ||
| + | c2 = Left_translate(c, true); | ||
| + | r2 = Down_translate(r, true); | ||
| + | } | ||
| + | |||
| + | |||
| + | break; | ||
| + | |||
| + | //***************************S block************** | ||
| + | |||
| + | case 1: | ||
| + | if (c == -1) { | ||
| + | c = 0; | ||
| + | } | ||
| + | if (c == 8) { | ||
| + | c = 7; | ||
| + | } | ||
| + | if (left_check1 == 1 && right_check1 == 0) { | ||
| + | c = Right_translate(c, true); | ||
| + | Left_translate(c, false); | ||
| + | Down_translate(r, true); | ||
| + | } | ||
| + | else if (left_check1 == 0 && right_check1 == 1) { | ||
| + | c = Right_translate(c, false); | ||
| + | Left_translate(c, true); | ||
| + | Down_translate(r, true); | ||
| + | } | ||
| + | else if (left_check1 == 1 && right_check1 == 1) { | ||
| + | c = Right_translate(c, false); | ||
| + | Left_translate(c, false); | ||
| + | Down_translate(r, true); | ||
| + | } | ||
| + | |||
| + | |||
| + | else if (left_check1 == 0 && right_check1 == 0) { | ||
| + | c2 = Right_translate(c, true); | ||
| + | c2 = Left_translate(c, true); | ||
| + | r2 = Down_translate(r, true); | ||
| + | } | ||
| + | |||
| + | break; | ||
| + | |||
| + | |||
| + | } | ||
| + | |||
| + | |||
| + | |||
| + | } | ||
| + | r = r - 0.125; | ||
| + | S_block(add, r, c, ro); | ||
| + | if (check1 == 1 || check2 == 1 || check3 == 1) { | ||
| + | r = 1.8; | ||
| + | } | ||
| + | delay(225); | ||
| + | } while (r > 1.9 ); | ||
| + | add_prev = 100; | ||
| + | r_prev = 100; | ||
| + | c_prev = 100; | ||
| + | break; | ||
| + | |||
| + | |||
| + | } | ||
| + | |||
| + | |||
| + | |||
| + | lc.line_break(); // Line Break function called from LED control libraries | ||
| + | lc.gameover(); // Game Over function called from LED control libraries | ||
| + | |||
| + | |||
| + | } | ||