Introduction: Arduino Dot Matrix Game Console

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

Comments

author
akasapu jaya sreelekha made it! (author)2017-03-02

a good project

author
shedboy71 made it! (author)2016-02-18

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

author
iLoveComputerz64 made it! (author)2016-02-11

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

author
kirarobotics made it! (author)kirarobotics2016-02-11

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

author
kirarobotics made it! (author)2016-02-09

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?

author
jhdeedar made it! (author)2016-02-09

It's a awesome project !!

author
kirarobotics made it! (author)2016-02-01

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.

author
taifur made it! (author)taifur2016-02-01

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

author
kirarobotics made it! (author)2016-02-01

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

author
taifur made it! (author)taifur2016-02-01

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

author
masteruan made it! (author)2016-01-24

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

author
taifur made it! (author)taifur2016-01-24

Here is the video link:

https://youtu.be/Z5Bd1mqNLE0

author
masteruan made it! (author)masteruan2016-01-31

Great!

author
techno maker made it! (author)techno maker2016-01-31

please respond

author
techno maker made it! (author)techno maker2016-01-29

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

author
mafiha made it! (author)2016-01-24

Nice game console, I like it

author
taifur made it! (author)taifur2016-01-25

thanks

author
techno maker made it! (author)2016-01-23

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

author
khairul-eee made it! (author)khairul-eee2016-01-24

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

author
khairul-eee made it! (author)khairul-eee2016-01-24

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

author
khairul-eee made it! (author)khairul-eee2016-01-24

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

author
khairul-eee made it! (author)khairul-eee2016-01-24

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

author
techno maker made it! (author)techno maker2016-01-23

"for all arduino projects" not arduino boards(last word)

author
khairul-eee made it! (author)2016-01-23

Very good project

About This Instructable

7,631views

123favorites

License:

Bio: I like to learn, like to make, like to share.
More by taifur:$5 IoT Pill BottlePortable ECG Machine Physical Pattern Lock
Add instructable to: