DIY Gaming console with Arduino

Fill The Board Game using Arduino

Materials Required

  • 8x8 Neopixel LED boards
  • 1602A LCD Display 16x2
  • Arduino Uno board
  • Ten Pin Momentary Push Buttons (12x12x7.3mm)
  • Jumper wires
  • Breadboard
  • PCB
  • Multimeter
  • Resistors and Potentiometer
  • Switches
  • Bluetooth chips (optional)
  • Analog joystick (optional)

Tools Required

  • Soldering Iron
  • Glue gun
  • Paper cutters and Scissors
  • Plier

Software Required

  • Arduino IDE (Linux or windows)

The documentation of our work will be posted in parts.

Team

  • Robin KP
  • Darsan TI
  • Nishanga P
  • Adish Illikkal

3 Likes

Arduino + Neopixel

Circuit Diagram

Getting started with adafruit neopixel

Adafruit Library installation:

  • via the Library Manager interface.
    From the Sketch menu, > Include Library > Manage Libraries… In the text input box type in “NeoPixel”.

  • Look for “Adafruit NeoPixel by Adafruit” and select the latest version by clicking on the popup menu next to the Install button. Then click on the Install button.

  • After it’s installed, you can click the “close” button.

3 Likes

Understanding the Code

Libraries required:

  • Adafruit_Neopixel
  • LedControl.h
  • avr/pgmspace.h

Global variables:
You’ll first set up some global variables for the pins your LED will connect to. This will make it easier to differentiate which one is red, green, and blue in the main part of your program

Setup:
The setup() function is called when a sketch starts. Use it to initialize variables, pin modes, start using libraries, etc. The setup() function will only run once, after each powerup or reset of the Arduino board.

Functions:

  • Serial
    Used for communication between the Arduino board and a computer or other devices.
  • PinMode
    configure the pins as outputs in setup()
    eg:
    pinMode(redPin, OUTPUT);
    pinMode(greenPin, OUTPUT);
    pinMode(bluePin, OUTPUT);

Progmem

Store data in flash (program) memory instead of SRAM.

Serial Communication:

Serial communication is the process of sending one bit of data at a time sequentially from one place to another. The serial library has functions like serial begin, read, available, parseInt, parseString, parseFloat, print, etc.

The serial receive buffer can hold 64 bytes. The data you send from your computer to your Arduino will end up in the serial receive buffer. Serial.read is a function of the Arduino Serial Library and what it does is read out the first available byte from the serial receive buffer.

We can use the available function to check how many bytes are available to be read in the serial receive buffer. Serial.available will return the number of bytes currently stored in the serial receive buffer.

Using Serial.parseInt() to separate the data by commas, read the information into your variables
eg:
int red = Serial.parseInt();
int green = Serial.parseInt();
int blue = Serial.parseInt();

Loop:
The loop() function does precisely what its name suggests and loops consecutively, allowing your program to change and respond. Use it to control the Arduino board actively.

Arduino pull-up function:
pull-up means the pushbutton’s logic is inverted. It goes HIGH when it’s open and LOW when it’s pressed.

References:

3 Likes

Toy models

Initially we tried to model a traffic light with time delay to understand the basics. It was then possible to move on to more complicated settings.
In order to understand the working of neopixel board and address position (i,j) of each LED, we initially worked with a few toy models.

Moving coloured dot on display using switch

We will use letters (a,d,w,s) as keyboard inputs to move left, right, up, and down. This way we are able to control position of a dot(object).

Plan:
We can extend this to longer objects (size=2,3 or 4 ships). We will also use additional keyboard input to lock the object. We will add a constraint to avoid the overlap of objects.

Code:


#include <Adafruit_NeoPixel.h>
#ifdef __AVR__
#include <avr/power.h>
#endif

int pin         =  2; 
int numPixels   = 64; 
int pixelFormat = NEO_GRB + NEO_KHZ800;
int x;

Adafruit_NeoPixel *pixels;

void setup() {
#if defined(__AVR_ATtiny85__) && (F_CPU == 16000000)
  clock_prescale_set(clock_div_1);
#endif
  pixels = new Adafruit_NeoPixel(numPixels, pin, pixelFormat);
  pixels->begin(); 
  pixels->clear();
  pixels->setBrightness(10);
  Serial.begin(9600);
  x = 0;
}

void loop() {
  char y;
  y = Serial.read();
//pixels->clear();
pixels->setPixelColor(x, pixels->Color(0, 0, 255));
if(y == 'd'){
  if((x+1)%8 == 0){
    x = x-7;
  }
  else{
      x =x+1 ;
  } }
if(y == 'a'){
  if((x)%8 == 0){
    x = x +7;
  }
  else{
      x = x-1;
      
  }}
if(y == 's'){
  
      x = (x+8)%64;
     
  }
  if(y == 'w'){
  if ((x%64)>7){
      x = (x-8)%64;}
  else{
    x = (56+x)%64; 
  }
      
  }
pixels->show();
}

3 Likes

Console

Day 2:

A console consists of five switches (up, down, left, right, enter).
We will use a breadboard to implant the switches.

Precautions:

  • Place switches such that they do not short. You may use a multimeter for this.
  • Provide necessary grounding.

Code to test switch:

const int UP_PIN = 10;
const int DOWN_PIN = 8; 
const int LEFT_PIN = 9; 
const int RIGHT_PIN = 11; 
// const int ENTER_PIN = 3; 
// const int LED_PIN = 2;


void setup(){
    pinMode( UP_PIN, INPUT );
    pinMode( DOWN_PIN, INPUT );
    pinMode( LEFT_PIN, INPUT );
    pinMode( RIGHT_PIN, INPUT );
    Serial.begin( 9600 );
}

void loop(){
    int value_u,value_d,value_l,value_r;
    
    value_u = digitalRead( UP_PIN );
    value_d = digitalRead( DOWN_PIN );
    value_l = digitalRead( LEFT_PIN );
    value_r = digitalRead( RIGHT_PIN );
    // To see if switches are actually working
    Serial.println( value_u  + value_d  + value_l + value_r );
    

    delay(10);
}

References:

https://create.arduino.cc/projecthub/Alojz/arduino-pocket-game-console-a-maze-maze-game-63c225

3 Likes

LCD Interface

16x2 LCD 1602A module can be used as the interface to display messages regarding game to the user.

Libraries used:

  • LiquidCrystal Library - Will available in Arduino IDE by default - For the first method.

Pin description:

Pin number Name Description
1 VSS (0v) Ground potential
2 VDD (5V) Positive voltage
3 V0 (Contrast) Contrast adjustment; 0v: Max contrast; 5v: Mincontrast
4 RS Register select
5 RW Read write select
6 E Enable pin to enable LCD module
7 D0-D7 LCD Data bus line
15 A Back light source anode
16 K Back light source cathode

Circuit:

Code (Example):


#include <LiquidCrystal.h>

const int rs = 12, en = 11, d4 = 5, d5 = 4, d6 = 3, d7 = 2;
LiquidCrystal lcd(rs, en, d4, d5, d6, d7);

void setup() {
  lcd.begin(16, 2);
  lcd.print("First line");
  lcd.setCursor(0,1);
  lcd.print("Second line");
}

void loop() {
}

3 Likes

FILL THE BOARD GAME WITH CONSOLE

Game:

Code (with keyboad):

#include <Adafruit_NeoPixel.h>
#ifdef __AVR__
#include <avr/power.h>
#endif

int pin         =  2; 
int numPixels   = 64; 
int pixelFormat = NEO_GRB + NEO_KHZ800;
int x;
int x2;
int g[64] = {};
int b[64] = {};
int y[250] = {};
int k = 0;
int j = 0 ;
int l = 0;
int i;
int m = 0;
int n =0;
int h;
int o =0;

Adafruit_NeoPixel *pixels;

void setup() {
#if defined(__AVR_ATtiny85__) && (F_CPU == 16000000)
  clock_prescale_set(clock_div_1);
#endif
  pixels = new Adafruit_NeoPixel(numPixels, pin, pixelFormat);
  pixels->begin(); 
  pixels->clear();
  pixels->setBrightness(2);
  Serial.begin(9600);
  x = 0;
  x2 = -1;
  int green = pixels->Color(0,255,0);
  int red  = pixels->Color(255,0,0);
  int blue = pixels->Color(0,0,255);
  int no = pixels->Color(0,0,0);

}


void loop() {
  char s;
  s = Serial.read();
pixels->setPixelColor(x, pixels->Color(0,255,0));
for(n=0;n<250;n++) {
    pixels->setPixelColor(y[n], pixels->Color(198,198,198));
}
for(k=0;k<64;k++) {
    pixels->setPixelColor(b[k], pixels->Color(102,0,102));
  }
for(i=0;i<64;i++) {
    pixels->setPixelColor(g[i], pixels->Color(255,0,0));
  }

  
pixels->setPixelColor(0,pixels->Color(198,198,198));

if(s == 'd'){
  pixels->setPixelColor(x,(0,0,0));
  if((x+1)%8 == 0){
    x = x-7;
  }
  else{
      x =x+1 ;
  } }
if(s == 'a'){
  pixels->setPixelColor(x,(0,0,0));
  if((x)%8 == 0){
    x = x +7;
  }
  else{
      x = x-1;      
  }}
if(s == 's'){ pixels->setPixelColor(x,(0,0,0));
  
      x = (x+8)%64;     
  }
if(s == 'w'){pixels->setPixelColor(x,(0,0,0));
  
  if ((x%64)>7){
      x = (x-8)%64;}
  else{
    x = (56+x)%64; 
  }
   }

if(s == 'g'){
  if (o%2 == 0){
    g[j] = x;
    j = j+1;
    o = o+1;
  }
  else if(o%2 == 1){
    b[l] = x;
    l = l+1;
    o = o+1;
  }
  if((x+1) % 8 == 0){
    y[m]=x-1;
    y[m+1] = x+7;
    y[m+2] = x+8;
    y[m+4] = x-9;
    y[m+3] = x-8;
    m = m+5;
  }
  else if ((x)%8 == 0){
    y[m+1] = x+1;
    y[m+2] = x+8;
    y[m] = x+9;
    y[m+4] = x-7;
    y[m+3] = x-8;
    m = m+5;
  }
  else{
  y[m]=x-1;
  y[m+1] = x+1;
  y[m+2] = x+8;
  y[m+3] = x-8;
  y[m+4] = x+7;
  y[m+5] = x+9;
  y[m+6] = x-7;
  y[m+7] = x-9;
  m = m+8;
  }
}
pixels->show();
}

Code (with console):

#include <Adafruit_NeoPixel.h>
#ifdef __AVR__
 #include <avr/power.h>
#endif
#include <LiquidCrystal.h>

const int rs = 12, en = 11, d4 = 5, d5 = 4, d6 = 3, d7 = 2;
LiquidCrystal lcd(rs, en, d4, d5, d6, d7);

int enter = 6, right = 7, left = 10, up = 8, down=9;
int enterstate = 1, rightstate = 0, leftstate = 0, upstate = 0, downstate=0;

int pin         =  13; 
int numPixels   = 64; 
int pixelFormat = NEO_GRB + NEO_KHZ800;
int x;
int g[64] = {};
int b[64] = {};
int y[250] = {};
int k = 0, j = 0, l = 0, i = 0, m = 0, n =0, o = 0, h = 0;


Adafruit_NeoPixel *pixels;

void setup() {
#if defined(__AVR_ATtiny85__) && (F_CPU == 16000000)
  clock_prescale_set(clock_div_1);
#endif
  pixels = new Adafruit_NeoPixel(numPixels, pin, pixelFormat);
  pixels->begin(); 
  pixels->clear();
  pixels->setBrightness(2);
  Serial.begin(9600);
  x = 0;
  lcd.begin(16, 2);
  lcd.setCursor(0,0);
  lcd.print("Press Enter");
  lcd.setCursor(0,1);
  lcd.print("to Start");
  delay(1000);

  
  pinMode(enter, INPUT);
  pinMode(right, INPUT);
  pinMode(left, INPUT);
  pinMode(up, INPUT);
  pinMode(down , INPUT);
  
  digitalWrite(enter,HIGH);
  digitalWrite(right,HIGH);
  digitalWrite(left,HIGH);
  digitalWrite(up,HIGH);
  digitalWrite(down,HIGH);

}


void loop() {

  rightstate = digitalRead(right);
  leftstate = digitalRead(left);
  upstate = digitalRead(up);
  downstate = digitalRead(down);
  enterstate = digitalRead(enter);

char s;
s = Serial.read();

for(n=0;n<250;n++) {
    pixels->setPixelColor(y[n], pixels->Color(198,198,198));}
for(k=0;k<64;k++) {
    pixels->setPixelColor(b[k], pixels->Color(102,0,102));}
for(i=0;i<64;i++) {
    pixels->setPixelColor(g[i], pixels->Color(255,0,0));}
pixels->setPixelColor(x, pixels->Color(0,255,0));
delay(100);
pixels->setPixelColor(0,pixels->Color(198,198,198));

if(rightstate == LOW){
  pixels->setPixelColor(x,(0,0,0));
  if((x+1)%8 == 0){
    x = x-7;}
  else{
      x =x+1 ;}
  lcd.clear();
  lcd.print("right "); 
  lcd.setCursor(0, 0); }

if(leftstate == LOW){
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("left "); 
  pixels->setPixelColor(x,(0,0,0));
  if((x)%8 == 0){
    x = x +7;}
  else{
      x = x-1;      }}

if(downstate == LOW){ 
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("down ");
  pixels->setPixelColor(x,(0,0,0));
  x = (x+8)%64;     }

if(upstate == LOW){
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("up ");
  pixels->setPixelColor(x,(0,0,0));
  if ((x%64)>7){
      x = (x-8)%64;}
  else{
    x = (56+x)%64; }}

if(enterstate == LOW){
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("Hello, "); // to test enter button
  lcd.setCursor(0,1);
  lcd.print("pls wait");
  if (o%2 == 0){
    g[j] = x;
    j = j+1;
    o = o+1;}
  else if(o%2 == 1){
    b[l] = x;
    l = l+1;
    o = o+1;}
  if((x+1) % 8 == 0){
    y[m]=x-1;
    y[m+1] = x+7;
    y[m+2] = x+8;
    y[m+4] = x-9;
    y[m+3] = x-8;
    m = m+5;}
  else if ((x)%8 == 0){
    y[m+1] = x+1;
    y[m+2] = x+8;
    y[m] = x+9;
    y[m+4] = x-7;
    y[m+3] = x-8;
    m = m+5;}
  else{
  y[m]=x-1;
  y[m+1] = x+1;
  y[m+2] = x+8;
  y[m+3] = x-8;
  y[m+4] = x+7;
  y[m+5] = x+9;
  y[m+6] = x-7;
  y[m+7] = x-9;
  m = m+8;}}
pixels->show();}
3 Likes

Tinkercad simulations

Challenges

  • Hardware - We soldered many wires onto boards but nonetheless the possibility of weak connections could not be avoided. We had to add potentiometer to make sure there was no voltage issue.
  • Software - Debugging an algorithm takes time!
  • Design - All the boards, wires and screens made it very bulky and it ws difficult to fit it into one compact box. We later decided to just fit LCD, LED screens and switch board onto a facade leaving wires, battery, etc externally kept in a rectangular box. This will allow people to see the connections.

Warning:

  • Codes may contain bugs, please make sure you understand the logic. We will be looking into it and updating the code in future.
  • The product might face hardware issue. Please make sure voltage potential and current through the circuit is maintained.
3 Likes

Miscellaneous

3 Likes

Future Add-ons

4 Likes

The documentation done in this thread is so good that I am encouraged to do this project at home very soon. Very inspiring! keep it up.

3 Likes