Feedback!

Arduino Pong

Views: 13496 Difficulty: 3 Status: Deprecated
Pong_joy_main

Play pong on a little LCD screen with two big joysticks.

Pong made chucky-cheese's more than just a deranged mouse-filled funhouse. Now we can play it with an Arduino, LCD screen, and joysticks. We use the nice thumb joysticks from Sparkfun, we like them because they come with a push-button. The screen is the rich TFT LCD Screen available at Adafruit. The logic is simple: each joystick (y-axis) controls a paddle. The ball bounces from side to side of the screen. If it gets pass a paddle the other side wins. One of our LCD Pong PCBs has LED's to represent the score. The newer PCB has a piezo buzzer and a vibration motor, instead of the LEDs. You can tell that one by the Islamic mosaic pattern silkscreened on its front. You can download that silkscreen and a bunch more to put on your boards at our EAGLE bitmap tutorial.

Plexi Enclosure

Screen_shot_2013-02-14_at_9.35.43_am
The LCD pong board has a strong plexiglass enclosure. Two laser cut circular holes give access to the joysticks. Notice the hand silkscreened under the left joystick. This board is being powered by usb but it also works from a battery.

Video

Watch a pong came in double speed. The red and green LEDs keep score. You can play your left hand vs. your right hand or against your friends, enemies, and frenemies.

LCD Pong Arduino code

This code lets you control a tft LCD screen and two joysticks so you can play pong! It uses the ST7735 TFT LCD Screen library from adafruit (click the zip button to download the whole library. And we also use the Arduino SPI library to communicate with the TFT LCD Screen.
// Pins SCLK and MOSI are fixed in hardware, and pin 10 (or 53) 
// must be an output
//#define sclk 13    // for MEGAs use pin 52
//#define mosi 11    // for MEGAs use pin 51
#define cs 10   // for MEGAs you probably want this to be pin 53
#define dc 9
#define rst 8  // you can also connect this to the Arduino reset

// Color definitions
#define	BLACK           0x0000
#define	BLUE            0x001F
#define	RED             0xF800
#define	GREEN           0x07E0
#define CYAN            0x07FF
#define MAGENTA         0xF81F
#define YELLOW          0xFFE0  
#define WHITE           0xFFFF

#include <ST7735.h>
#include <SPI.h>

// Option 1: use any pins but a little slower
//ST7735 tft = ST7735(cs, dc, mosi, sclk, rst);  

// Option 2: must use the hardware SPI pins 
// (for UNO thats sclk = 13 and sid = 11) and pin 10 must be 
// an output. This is much faster - also required if you want
// to use the microSD card (see the image drawing example)
ST7735 tft = ST7735(cs, dc, rst);
float p = 3.141592; // value for pi
int tft_width = 128;
int tft_height = 160;
int x1 = 60;
int y1 = 60;
int x2 = 20;
int y2 = 80;
int ballx = 60;
int bally = 60;
int deltay = 1;
int deltax = 1;

int ball_speed = 24;

int left_score = 4;
int right_score = 4;

int background_color = 0x00;
void setup(void) {
  tft.initR();               // initialize a ST7735R chip

  tft.writecommand(ST7735_DISPON);
  tft.fillScreen(background_color);
  delay(700);
  for(int i = 0; i < 9; i++){
    pinMode(i,OUTPUT);
  }
  for(int i = 0; i < 9; i++){
    digitalWrite(i,HIGH);
  }
  delay(500);
  
}

void loop() {  
  for(int i = 0; i < left_score; i++){
    digitalWrite(i,HIGH);
  }
  for(int i = 0; i < right_score; i++){
    digitalWrite(i+4,HIGH);
  }
  int cur_r = random(20,32);
  int cur_g = random(55,64);
  int cur_b = random(10,32);
  int color = cur_r  | (cur_g << 5) | (cur_b << 11); 
  int radius = 4;
  draw_paddles();
  draw_ball(color);
  delay(ball_speed);
}
void draw_input_text(){ 
  int cur_x2 =  analogRead(2);
  int cur_y2 =  analogRead(3);  
  String xs = String(cur_x2);
  String ys = String(cur_y2);
  char cx[4];
  cx[0] = xs.charAt(0);
  cx[1] = xs.charAt(1);
  cx[2] = xs.charAt(2);
  cx[3] =0;
  char cy[4];
  cy[0] = ys.charAt(0);
  cy[1] = ys.charAt(1);
  cy[2] = ys.charAt(2);
  cy[3] =0;
  tft.fillRect(10,20,40,40,background_color);
  tft.drawString(12,22,cx ,YELLOW);
  tft.drawString(12,40,cy ,YELLOW);
}
void draw_paddles(){
  int cur_x =  analogRead(0);
  int cur_y =  analogRead(1);  
  int hval = 620;
  int lval = 350;
 
  if ( y1 < tft_height - 20  && cur_y > hval) y1++;
  else if ( y1 > 0 && cur_y < lval ) y1--; 
 
  int cur_x2 =  analogRead(2);
  int cur_y2 =  analogRead(3); 

  if ( y2 < tft_height - 20 && cur_y2 > hval ) y2++;
  else if (y2 > 0 && cur_y2 < lval ) y2--; 
  tft.fillRect(2, y1-3, 5, 27, background_color);
  tft.fillRect(3, y1, 3, 20, YELLOW);
  tft.fillRect(tft_width-3, y2-3, 5, 27,background_color);
  tft.fillRect(tft_width-3, y2, 3, 20, YELLOW);
}
void draw_ball(int color){
   int bradius = 6;
    tft.fillCircle(ballx, bally, bradius , color);
    ballx += deltax;
    bally += deltay;
    if ( ballx < 7 && bally > y1 && bally < y1+20) deltax *= -1;
    else if ( ballx > tft_width-7 && bally > y2 && bally < y2+20) deltax *= -1;
    else if ( bally <= bradius || bally >= tft_height - bradius ) deltay *= -1;
    if (ballx <=  0 ) {
      left_score--;
      tft.drawString(2,42, "Right Won!" ,~background_color,2);
      tft.drawString(2,62, "Get Ready!" ,CYAN,2);
      for (int i = 0; i <250; i++){
        delay(10);
        draw_paddles();
      }
      int cur_r = random(0,26);
      int cur_g = random(0,30);
      int cur_b = random(0,18);
      background_color = cur_r  | (cur_g << 5) | (cur_b << 11); 
      tft.fillScreen(background_color);
      ballx = 64;
      bally = 80;
      if (ball_speed > 1) ball_speed--;
      digitalWrite(left_score,LOW);
    } else if (ballx >= tft_width  ) {
      right_score --;
      tft.drawString(2,42, "Left Won!" ,YELLOW,2);
      tft.drawString(2,62, "Get Ready!" ,GREEN,2);
      for (int i = 0; i <250; i++){
        delay(10);
        draw_paddles();
      }
      int cur_r = random(0,26);
      int cur_g = random(0,30);
      int cur_b = random(0,18);
      background_color = cur_r  | (cur_g << 5) | (cur_b << 11); 
      tft.fillScreen(background_color);
      ballx = 64;
      bally = 80;
      if (ball_speed > 1) ball_speed--;

      digitalWrite(4+right_score,LOW);


    }
}

Parts

Title Description # Cost Link Picture
LCD and joystick PCB This PCB holds two joysticks and an LCD display. 1 $10.0 Link Screen_shot_2013-02-15_at_6.35.08_pm
TFT LCD Screen 1.8 inch 160 x 128 pixels LCD screen. ST7735R driver. JDT-1800. 1 $9.95 Link Id618_lrg
Joystick Thumb joystick with push button. 2 $3.95 Link 09032-03-l
ATMEGA328P-AU Integrated Circuits (ICs) MCU AVR 32K FLASH 32TQFP Value: 1.8 V ~ 5.5 V 20MHz 1 $3.05 Link Screen_shot_2012-12-28_at_7.31.33_pm
Crystal CRYSTAL 16.00000 MHZ 20PF SMD Value: 16MHz 1 $0.53 Link Ecs-270-20-3x-en-tr
Voltage Regulator 3v3 SMD IC REG LDO 3.3V .15A SOT23 Up to 6V input output 3.3V 150mA (Max) Value: 3.3V 1 $0.46 Link Sot-23-3_pkg
CD4050 IC BUFF/CONVERTER HEX 16SOICN 8mA, 48mA Value: 3 V ~ 18 V 1 $0.45 Link 16-soic_(7.5mmwidth)

    Comments:

    20120519_163335
    sam
    Pong in your palm :)
    Thu, May 08 2014 1:11AM
    20120519_163335
    sam
    You will need an ISP programmer to re-program... check out our tutorial on ISP Programming.
    Sun, Jun 02 2013 9:54AM
    20120519_163335
    sam
    Links were added to the code description. In the Arduino IDE choose TOOLS -> BOARD -> Arduino Duemilanove w/ ATmega328
    Sun, Jun 02 2013 9:54AM
    Missing_profile
    dperry
    The source file above does not include the .h include files. Where can we get those? (ST7735.h and SPI.h)
    Mon, May 20 2013 7:16PM
    Missing_profile
    dperry
    If programming is possible, what is the correct board choice in the Arduino IDE? (Under TOOLS->BOARD)
    Mon, May 20 2013 7:11PM
    Missing_profile
    dperry
    Can I program this Arduino board using the standard USB cable? If not what is the name of the cable I need?
    Mon, May 20 2013 7:09PM
Permalink: http://lucidtronix.com/tutorials/7
Handheld gaming machine, based on the Arduino Leonardo, equipped with joystick, SD card and more....
Our take on the classic bouncing ball, paddle game....
Coupling the HMC5883L Compass with our color library turns the Wearable Wayfinder into a handy naviga...
Display bitmap images and text files and folders with this TFT LCD screen and SD Card navigator....
The Wearable Wayfinder is a totally programmable, beautiful little computer for your wrist packed wit...
Control the hue, value and saturation on this pocket-sized joystick drawing machine....
Standalone programmable Heart-Shaped LED display....
Print bitmaps, cellular automata, drawings and text.....