Arduino Dot Matrix Game Console

10,781

128

25

Introduction: Arduino Dot Matrix Game Console

About: I like to learn, like to make, like to share.

Smart phone & iPad gaming is great and all love Candy Crush & Angry Birds, but nothing can touch the charm of making a game console by own and play with it. It was 2003 when I got a Nokia 3310 mobile phone and I used to play Snake game of Nokia which was very popular that time. I made the game console using ATmega328P and bi-color dot matrix display and I was inspired by the game of Nokia phone. I think you will like it. So, let's start to make it.

If you like it don't forget to give a kind vote.

Step 1: What You Need...

Components:

  1. Arduino Uno (1) (sparkfun)
  2. ATmega328P Microcontroller (1) (sparkfun)
  3. MAX7219CNG (2) (sparkfun)
  4. 2.379" Bi-color dot matrix display (1) (sparkfun)
  5. Push buttons or tactile switch (7) (sparkfun)
  6. Buzzer (1)
  7. 5mm LED (5)
  8. Resistor (15)
  9. Capacitor (6)
  10. 165mm X 73mm PCB board
  11. IC base (optional)
  12. Li-ion battery (1) (sparkfun)

Tools:

  1. Soldering Iron & solder
  2. Glue gun
  3. PCB drill (for hand made pcb only)

Skills:

  1. Good soldering & prototyping skill is required

Arduino Uno is used to program ATmega328P. ATmega328P is the main microcontroller of Arduino Uno board and I used it alone for my project. For knowing how to use standalone ATmega328P you can follow "From Arduino to a Microcontroller on a Breadboard".

MAX7219CNG is used to drive dot-matrix display. The MAX7219CNG is a compact, serial input/output common-cathode display driver that can interface microprocessors to 7-segment numeric LED displays of up to 8 digits, bar-graph displays, or 64 individual LEDs. Included on-chip are a BCD code-B decoder, multiplex scan circuitry, segment and digit drivers, and an 8x8 static RAM that stores each digit. Communication with the MAX7219 is achieved through a convenient 4-wire serial interface (supports SPI). Individual digits may be addressed and updated without rewriting the entire display. Only one external resistor is required to set the segment current for all LEDs. The IC also includes a 150μA low-power shutdown mode, analog and digital brightness control, a scanlimit register that allows the user to display from 1 to 8 digits, and a test mode that forces all LEDs on. Details are available in the datasheet.

If you are new in soldering you can follow the instructable: How to solder - the secrets of good soldering

Sparkfun.com guide: How to Solder - Through-hole Soldering

Step 2: Circuit Design

The circuit is designed using Eagle Layout Editor and schematic file is attached. Four tactile switch S2-S5 is used to control UP, DOWN, LEFT & RIGHT control. Switch S6 & S7 is used for option menu and game selector. S1 is used here as reset switch of microcontroller. Resistors R4 - R9 is used as pull up resistor any value may be 10K - 100K. Five LED LED1 -LED5 is used for indicating the level for a game and the value of series resistors connected to LEDs should be 220ohm - 330ohm. As I used bi-color dot matrix display for that I used two MAX7219CNG driver IC. You can use RGB matrix and that time three driver IC will be required. Two resistors R1 & R2 is connected to the ICs for controlling the brightness of the matrix display.

Step 3: PCB Design

PCB is designed using Eagle and board layout is attached. You can design your own PCB or may designed it. I designed it for making my PCB using toner transfer method and for that I used 24mil trace size. For the top layer I used jumper wires because making two sided PCB using toner transfer method is not so easy but you may try it yourself. I tried to keep the board size comfortable for me but every one has his own choice.

Step 4: Programming the Console

To work the Arduino Sketch properly you need LedControl library attached in this step. I upload the complete Arduino Sketch for Snake Game of Nokia phone. You can develop your own game. To upload the sketch first add the library to your arduino environment, just upload the sketch to your arduino, remove the microcontroller from the board and put it to your game console. I will upload more game for the console in future. . Just it.

#include "LedControl.h"
// connection to MAX7219 (data, clik, load, #of dispplay)
LedControl lc = LedControl(11,13,10,1);

// direction
const int TOP    = 0;
const int RIGHT  = 1;
const int BOTTOM = 2;
const int LEFT   = 3;
// Snake length
const int MAX_SNAKE_LENGTH = 16;

// Variables
//Adafruit_8x8matrix matrix = Adafruit_8x8matrix();  // Display
int direction = RIGHT;                               // direction of movement
int snakeX[MAX_SNAKE_LENGTH];                      // X-coordinates of snake
int snakeY[MAX_SNAKE_LENGTH];                      // Y-coordinates of snake
int snakeLength = 3;   
int score = 3;// 
unsigned long prevTime = 0;                        // for gamedelay (ms)
unsigned long delayTime = 500;                     // Game step in ms

int fruitX, fruitY;
unsigned long fruitPrevTime = 0;
unsigned long fruitBlinkTime = 100;
unsigned long bonusTime = 0;
unsigned long bonusPrevTime = 0;
int fruitLed = true;
int bonusLed = true;
int bonusX, bonusY;


void setup(){
  ////wake up the MAX72XX from power-saving mode
  lc.shutdown(0,false);
  //set a medium brightness for the Leds
  lc.setIntensity(0, 15);
  //Switch all Leds on the display off.
  lc.clearDisplay(0);
  Serial.begin(9600);
  
  randomSeed(analogRead(0));
  pinMode(0,INPUT);
  //pinMode(17,INPUT);
  pinMode(1,INPUT);
  pinMode(2,INPUT);
  pinMode(3,INPUT);
  pinMode(4,INPUT);
  pinMode(5,INPUT);
  //buzzer
  pinMode(12,OUTPUT);
  
  
  snakeX[0] = 0;
  snakeY[0] = 4;
  for(int i=1; i<MAX_SNAKE_LENGTH; i++){
    snakeX[i] = snakeY[i] = -1;
  }
  makeFruit();
  
}
  
void loop(){
    delay(10);
    checkButtons();  // if any button is pressed or not
   
    unsigned long currentTime = millis();
    if(currentTime - prevTime >= delayTime){
    nextstep(); 
    
    prevTime = currentTime;
  }
  draw(); // make snack & food
}

void checkButtons(){
  if(digitalRead(3)==0)
     direction = TOP;
  else if(digitalRead(4)==0)
     direction = RIGHT;
  else if(digitalRead(5)==0)
     direction = LEFT;
  else if(digitalRead(2)==0)
     direction = BOTTOM;
}

void draw(){
  lc.clearDisplay(0);
  drawSnake();
  drawFruit();

}
void drawSnake(){
  for(int i=0; i<snakeLength; i++){
    lc.setLed(0,snakeX[i], snakeY[i], true);
  }
}
void drawFruit(){
  if(inPlayField(fruitX, fruitY)){
    unsigned long currenttime = millis();
    if(currenttime - fruitPrevTime >= fruitBlinkTime){
      fruitLed = (fruitLed == true) ? false : true;
      fruitPrevTime = currenttime;
    }
    lc.setLed(0,fruitX, fruitY, fruitLed);
  }
}
boolean inPlayField(int x, int y){
  return (x>=0) && (x<8) && (y>=0) && (y<8);
}
void nextstep(){
    for(int i=snakeLength-1; i>0; i--){
    if((direction == RIGHT)&&(snakeX[0]-snakeLength == 7))
    snakeX[0] = -1;
    else if((direction == LEFT)&&(snakeX[0]+ snakeLength == 0))
    snakeX[0] = 8;
    else snakeX[i] = snakeX[i-1];
    if((direction == TOP) && (snakeY[0]+snakeLength == 0))
    snakeY[0]=8;
    else if((direction == BOTTOM) && (snakeY[0]-snakeLength == 7))
    snakeY[0]=-1;
    else snakeY[i] = snakeY[i-1];      
  }
  switch(direction){
    case TOP:
      snakeY[0] = snakeY[0]-1; 
      break;
    case RIGHT:
      snakeX[0] = snakeX[0]+1;
      break;
    case BOTTOM:
      snakeY[0] = snakeY[0]+1;
      break;
    case LEFT:
      snakeX[0]=snakeX[0]-1;
      break;
   }
  if((snakeX[0] == fruitX) && (snakeY[0] == fruitY)){
    snakeLength++;
    score++;
    tone(12,4500,50);
    if(snakeLength < MAX_SNAKE_LENGTH){      
      makeFruit();
    } 
    else {
      fruitX = fruitY = -1;
    }
    if(score%8==0)
      {
        snakeLength = 3;
        delayTime = delayTime - 100;
     }
  }
  snakeItSelf();  
}
void makeFruit(){
  int x, y;
  x = random(0, 8);
  y = random(0, 8);
  while(isPartOfSnake(x, y)){
    x = random(0, 8);
    y = random(0, 8);
  }
  fruitX = x;
  fruitY = y;
}

boolean isPartOfSnake(int x, int y){
  for(int i=0; i<snakeLength-1; i++){
    if((x == snakeX[i]) && (y == snakeY[i])){
      return true;
    }
  }
  return false;
}
void snakeItSelf(){  // check if snack touch itself
    for(int i=1;i<snakeLength;i++){
      if((snakeX[0] == snakeX[i]) && (snakeY[0] == snakeY[i]))
       gameOver();
     }
}
void gameOver(){
  // game over sound
  tone(12,1000,100);
  delay(100);
  tone(12,1500,200);
  delay(200);
  tone(12,2000,300);
  delay(300);
  tone(12, 494,500);
  delay(500);
  lc.clearDisplay(0);
  for(int r = 0; r < 8; r++){
        for(int c = 0; c < 8; c++){
            lc.setLed(0, r, c, HIGH);
            delay(50);
        }delay(50);
    }
  delay(300);
  score = 3;  
  snakeLength = 3;
  direction = RIGHT;
  snakeX[0]=3;
  snakeY[0]=4;
  delayTime = 500;
  loop();
}

void drawBonus(){
  if(inPlayField(fruitX, fruitY)){
    unsigned long bonusTime = millis();
    if(bonusTime - bonusPrevTime >= 300){
      bonusLed = (bonusLed == true) ? false : true;
      bonusPrevTime = bonusTime;
    }
    lc.setLed(0,bonusX, bonusY, bonusLed);
  }
}
void makeBonus(){
  int x, y;
  x = random(0, 8);
  y = random(0, 8);
  while(isPartOfSnake(x, y)){
    x = random(0, 8);
    y = random(0, 8);
  }
  bonusX = x;
  bonusY = y;
}

Step 5: Assemble All the Things

Complete the PCB and assemble all the thing together. It is good practice to use IC base for prototyping board without soldering the IC directly to the PCB board. It remove the risk to burn the IC during soldering and create a way to remove IC any time without de-soldering.

Step 6: Complete Game Console

Image of my complete game console is uploaded, I apologize for the quality of the image. All images are taken by my smart phone.

Step 7: Specification

Full Spectrum Laser Contest 2016

Participated in the
Full Spectrum Laser Contest 2016

Homemade Gifts Contest 2015

Participated in the
Homemade Gifts Contest 2015

Arduino All The Things! Contest

Participated in the
Arduino All The Things! Contest

Be the First to Share

    Recommendations

    • The 1000th Contest

      The 1000th Contest
    • Battery Powered Contest

      Battery Powered Contest
    • Hand Tools Only Challenge

      Hand Tools Only Challenge

    25 Discussions

    0
    nolte919
    nolte919

    2 years ago

    This is a really neat project. Two things. You said, "I will upload more game for the console in future." Have you made any more games for it? Also you posted a link to a video in the comments but that video is unavailable. Is there a video of this project that works? Thanks.

    0
    shedboy71
    shedboy71

    4 years ago

    Q1 is the crystal (xtal). If its based on an UNO then 16Mhz

    0
    iLoveComputerz64
    iLoveComputerz64

    4 years ago

    This is awesome little project to make! i might even make a shell for it.

    0
    kirarobotics
    kirarobotics

    Reply 4 years ago

    hey! any idea what Q1 in bottom left corner stands for?

    0
    kirarobotics
    kirarobotics

    4 years ago

    Hello! What is Q1 in the bottom left corner of the circuit design? There are no directions for transistors and I seem to be missing whatever Q1 entails. Please elaborate on this function and what it is. Also is it important to use ceramic capacitors?

    0
    jhdeedar
    jhdeedar

    4 years ago

    It's a awesome project !!

    0
    kirarobotics
    kirarobotics

    4 years ago

    Do you have any tips if I were to use four separate breadboards instead of one big one? I do not have the ability to make one, so instead I am going to connect four of the Perma-Proto 1/2 sized breadboards.

    0
    taifur
    taifur

    Reply 4 years ago

    May be used. It is your creativity which one you will use.

    0
    kirarobotics
    kirarobotics

    4 years ago

    Hey thanks for the awesome tutorial. Just wondering what value of capacitors do you use? Thanks!

    0
    taifur
    taifur

    Reply 4 years ago

    Capacitor value can be 1 to 10 uF. See the datasheet for MAX7219CNG

    0
    masteruan
    masteruan

    4 years ago

    Good tutorial! Have you got a video of this game?

    0
    taifur
    taifur

    Reply 4 years ago

    Here is the video link:

    https://youtu.be/Z5Bd1mqNLE0

    0
    masteruan
    masteruan

    Reply 4 years ago

    Great!

    0
    techno maker
    techno maker

    Reply 4 years ago

    please respond

    0
    techno maker
    techno maker

    Reply 4 years ago

    which programming language is best for arduino programing c or c++

    0
    mafiha
    mafiha

    4 years ago

    Nice game console, I like it

    0
    taifur
    taifur

    Reply 4 years ago

    thanks

    0
    techno maker
    techno maker

    4 years ago

    great project............ can I use the programmed microcontroller (atmega 328) eliminating the arduino board for all arduino boards..

    0
    khairul-eee
    khairul-eee

    Reply 4 years ago

    Yes, you can use programmed ATmega328 eliminating the arduino board for all arduino projects.