Introduction: Interactive Beer Pong (Beirut) Table

Have you ever played found yourself in a long, boring game of Beer Pong wishing there was a little more excitement in the game? I know I have so I decided to try and make pong games a little more exciting in our house by making this interactive beer pong table! The general idea behind the table is to make the table respond to the state of the game, and change as the game progresses. In the example I have made here a series of tri-color LED's in the middle of the table change colors as cups are removed. (if you don't know how to play pong, please check this out first!) The table's main parts are force sensitive resistors (to sense the cups), an arduino microcontroller, and lots of tri-color LEDs.

For time and expenses sake I have only made half of the table and with 6 cups instead of the traditional 10. However, as you will see there are endless customizable options to the table once you have the sensors built and arduino working. 

This project served as my final project for a course at Carnegie Mellon University taught by Mark Gross called "Making Things Interact". Class Blog


Step 1: Parts List

Note: All parts listed below are to build only half the table, you will have to double everything but the microcontroller. 

Materials needed:
(for electrical parts)
1 x Arduino Microcontroller
6 x Force Sensitive Resistors
18 x Tri Color RGB LEDs (buy in bulk on ebay)
3 x TIP 120 Transistors
1 x Breadboard
1 x 9v battery and connector
100 Ohm and 100Kohm resistors
lots of different color wires (definitely comes in handy...)

(for construction)
3'x4' 3/4" Plywood
Thick Foam or Mat Board - 2 pieces of 24"x36"
Balsa wood for LED bar

Tools required:
Soldering Iron and solder
Jigsaw
Drill
Electrical Tape
Hot Glue/Super Glue
Wirecutters
Boxcutter/utility knife

Step 2: First Make the Board

The best part about these projects for me is using the power tools so thats why I put building the board fist. Go to home depot/lowes and get yourself a nice thick 3/4" piece of ply. I used sanded cabinet plywood from home depot and just had it cut there into 3'x8' and then cut in half for ease of transportation.

There are a specific type of cups best suited for Pong called Solo cups (the red of blue ones). The base of these cups are have a 2.5" diameter. Make a circle template out of cardboard with a diameter of 2.75", cut cleanly with a boxcutter. Use the template to sketch out 6 circles on your 3'x4' piece of plywood as shown below. Also sketch out a 5" in from both ends of the width and 21" deep as shown by the white below.

Now first drill a hole in each of 6 circles sketched out with a 1/4" drill bit. Then use a jig saw to carefully cut out each of the circles from the board. Be careful to keep the jigsaw completely perpendicular to the board to ensure that your cuts are not angled. You should pop out circles like the one shown below. Then jigsaw out the rectangular 21"x26" piece as shown below. 

Note: this is for a 6 cup pong game with spaced out cups. If you like to keep your cups close to together (or touching) then please measure out desired locations for cups. I have left a big lip behind the cups in case players would like to play a 10 cup game. 

Step 3: Wire the Pressure Sensors

 Force Sensitive Resistors (FSR) are very fun, very sensitive sensors to use. When force is applied to the circle of the sensor, current is allowed to travel through the sensor depending on how much force is applied.

Wire each sensor as shown below. Be CAREFUL when soldering the wires to the leads of the FSR's because if you melt the plastic you risk ruining the FSR. (I ruined one...so my fourth cup doesnt work :( . Test them using a simple bit of screen output code shown below:

int fsrCup0 = 0; //force sensitive resitor for top cup
int fsrCup1 = 1; //fsr for middle left cup
int fsrCup2 = 2; //fsr for middle right cup
int fsrCup3 = 3; //fsr for bottom left cup
int fsrCup4 = 4; //fsr for bottom middle cup
int fsrCup5 = 5; //fsr for bottom right cup
int myCups [] = {0,1,2,3,4,5};

void setup(){
Serial.begin(9600);
}

void loop(){
for(int x = 0; x <= 5; x++)
  {
    Serial.print (analogRead(myCups[x])); //a print out of the 6 cups pressure for testing purposes
    Serial.print("\t"); 
    Serial.prinln();
}
}


While this program is running just push on the sensors to make sure that they are working. Aren't they awesome! Wire everything to the breadboard and get ready to attach everything to a board!

Note that all 6 analog inputs available on the Arduino will be used for just these 6 sensors. There are many way to expand the analog inputs on an Arduino, but I would recommend using a 16:1 multiplexer giving you 16 analog inputs out of one (and 3 digital inputs). 

Step 4: Attach the FSR's to a Board

 Cut out a 15" x 27" piece of foam or mat board. Tape the board to the back of the plywood you had cut earlier, making sure to cover up all six holes. Using a pencil trace out the 6 cup holes onto the foam board. Detach the foam board from the ply.

Now cut a slit at the bottom edge of each whole. This slit is for the FSR to slide through so that the sensor is visible on top of the board but the leads are hidden underneath. Cut the slit using a box cutter. When sliding the FSR into it try and widen the slit as much as possible to reduce the bend in the FSR. The FSR should bend as little as possible. 

Tape down both the sensor and the leads with celophane tape. Be sure to cover the entire sensor with the tape as this will be the last defense against any leaking beer, so try to keep it airtight. The sparkfun FSR sensors have a sticky side that you can use to attach the FSR to anything, I did not use this but you are welcome to if you find it simple. 

Attach the board to the wood temporarily using pushpins (might require a hammer). Make sure the sensors are lines up perfectly so that there is a sensor at the bottom of every hole for a cup.
Flip the board over so the wood side is up.

Now attach the breadboard to the same foam board and wire the sensors up! Check to make sure everything is working fine again using the code in step 3. 

Step 5: Understand Your LEDs

 Tri color LEDs are not as simple as your regular 2 pin diodes. First you will notice that there are 4 pins. The longest pin is most likely the ground and the three other pins control the red, green, and blue colors individually. You have to test these LEDs before jumping into production to ensure that you didn't get a bunch of duds.

Test by making the circuit below. The LEDs I ordered ended up being reversed from the norm so power was actually sent to each individual RGB pin and the long pin was the ground. Just use a 9V battery and touch the end to the pins and try and make combinations between the colors.

Specifically try:
Red+Green = Yellow
Red+ Blue = Purple
Blue + Green = Cyan
Red+Blue+Green = White

Write down somewhere the arrange of your pins to make sure you know whats red and blue and green. 


Step 6: Wire Up the LED Bar

This is where you are welcome to vary it up. I used a nice LED bar of 18 LED's housed in two pieces of balsa wood because I wanted a lot of soldering practice as it was my first time. And I wanted something very bright but still easily powered by just a 9V battery. If you want to try something else go ahead and skip this step but the transistor information in the next step will still be needed.

So wiring this mess as you can see below was no simple task. Not only did it require a great amount of time it would have been near impossible without a half decent soldering iron.  

First cut two 20" long pieces of balsa wood and make 9 equally spaced holes through the middle of each board. I made the holes by first poking a small hole using a mechanical pencil then widen the hole using a chopstick. Be sure to not make the holes bigger the the base of the LEDs. Now squeeze an LED into each hole and hot glue it in place. MAKE SURE ALL PINS ARE PARALLEL (reds with reds, ground with ground, etc.). 

its soldering time. The led's will be wired up according to the sketch below. I only showed the red led pins here but every pin will have to be the wired the same as the top section of these LEDs (the resistor part). You should use wire covers at the base of the LEDs instead of the electrical tape I used, but if you happen to forget as well then go ahead and tape up exposed sections to make sure there is no interference. 

When everything is connected, wire together all the reds, greens, blues, and power so that there are long 4' extensions. at the end of the wires somehow notify what pin that wire controls. I used colored tags. 

Attach the two board together on a long edge at an angle using hot glue and tape. 

Step 7: Controlling the LEDs

 To control the LEDs we will need a transistor. Since we want to be able to change colors we will need to control each color (pin) of the LEDs meaning 3 total transistors. For this job TIP 120 transistors should work fine. Wire them up according to the sketch below. wire them to the same breadboard already attached to the foam board with the sensors. 

Make sure to connect the collector pins of the transistors to PWM pins on the arduino as we want to change the intensity of the lights and can only do so with pulse width modulation. 

Step 8: Put It All Together

Below is a circuit diagram. Make sure your connections match what's below and then we're ready to throw the code on! 

Step 9: The Code

The Arduino Sketch is below and attached:

 /* Interactive Pong Table - by Rohit Kabra
Following is the code for an interactive pong table I designed for a class called Making Things Interact at Carnegie Mellon University. 
The table was built to change the game of Beer Pong (Beirut) so that the table reacts to the current state of the game. 
A 3'x8' table was built that housed holes for 6 cups on either end. The following code controls only one side (6 cups).
Force Sensitive Resistors were mounted underneath each cup and wired to an Arduino. 
The program below tells whether or not there is a cup on the resistor and depnding on how many cups have been removed a series of RGB LEDs change color. 
The RESET button is especially curious as it is just the top cup on the table pressed down a little harder. 
*/

int fsrCup0 = 0; //force sensitive resitor for top cup
int fsrCup1 = 1; //fsr for middle left cup
int fsrCup2 = 2; //fsr for middle right cup
int fsrCup3 = 3; //fsr for bottom left cup
int fsrCup4 = 4; //fsr for bottom middle cup
int fsrCup5 = 5; //fsr for bottom right cup

 //the 6 force sensitive resistors are controlled by analog pins 0-5. 
 //the following array will hold the input of the 6 sensors
int myCups [] = {0,1,2,3,4,5}; 
boolean isCupHit [] = {false, false, false, false, false, false}; //array that tells whether cup has been removed or not
int numberOfCupsHit = 0; //a variable that tells the program how many cups have been removed from the table

int redLED = 3; //all red's of the RGB LEDS controlled by pin 3
int greenLED = 5; //all greens's of the RGB LEDS controlled by pin 5
int blueLED = 9; //all blue's of the RGB LEDS controlled by pin 9
int redValue; //the current value of the red LED's, helps to change colors
int blueValue; //the current value of the blue LED's, helps to change colors
int greenValue; //the current value of the green LED's, helps to change colors

void setup()
{
  pinMode(redLED, OUTPUT); //initiated the red LEDs as outputs
  pinMode(greenLED, OUTPUT); //initiated the green LEDs as outputs
  pinMode(blueLED, OUTPUT); //initiated the blue LEDs as outputs
  Serial.begin(9600); //starts up the sketch
}

void loop()
{
  if(analogRead(myCups[0]>>1100)) reset(); //if the top cup is pushed down the program resets, and lights go back to initial state
  for(int x = 0; x <= 5; x++)
  {
    Serial.print (analogRead(myCups[x])); //a print out of the 6 cups pressure for testing purposes
    Serial.print("\t"); 
    if(isCupHit[x] == false) //checks to make sure only looping through cups that have NOT been hit
    {
      if(analogRead(myCups[x])>300) //checks cup's fsr, if cup has been removed then force should drop below 300
      {
        numberOfCupsHit++; //adds 1 to total number of cups hit thus far in the game
        interact(numberOfCupsHit); //run the method interact with the specific number of cups hit
        isCupHit[x] = true; //makes sure the cup that was just hit isnt checked again for being hit or not
      }
    }
  }
  Serial.println();//space the testing printouts
}

//the interact method is meant to act like a finite state machine. With each cup initing a different state of the lights. 
void interact(int state)
{
  //state 1 - after first cup is hit
  //color will fade into bluish green as the bar moves 
  if (state == 1) 
  {
    blueValue = 255; //sets starting values of blues
    greenValue = 0; //sets starting value of greens
    for(int x = 0; x <= 125 ; x++)
    {
      analogWrite(blueLED, blueValue--); //fades out blue to desired brightness
      analogWrite(redLED, 0); //sets value of red input to 0 or no red
      analogWrite(greenLED, greenValue++); //fades green to desired brightness
      delay(10);
    }
  }
  //state 2 - after second cup is hit
  //color will fade into green as the bar moves 
  if (state == 2) 
  {
    blueValue = 125; //sets starting value of blues before fading
    greenValue = 125; //sets starting value of greens before fading
    for(int x = 0; x <= 125 ; x++) 
    {
      analogWrite(blueLED, blueValue--); //dims out blue to off
      analogWrite(redLED, 0); //sets value of red input to 0 or no red
      analogWrite(greenLED, greenValue++); //fades green to full brightness
      delay(10);
    }
  }
  //state 3 - after third cup is hit
  //color will fade into CYAN as the bar moves 
  if (state == 3) 
  {
    blueValue = 0; //sets starting value of blues before fading
    greenValue = 255; //sets starting value of greens before fading
    for(int x = 0; x <= 255 ; x++) 
    {
      analogWrite(blueLED, blueValue++); //fades in blue so color turns cyan
      analogWrite(redLED, 0); //sets value of red input to 0 or no red
      analogWrite(greenLED, greenValue); //stays green throughout movement
      delay(5); //only 5 delay because of longer loop
    }
  }
  //state 4 - after fourth cup is hit
  //color will fade into PINK as the bar moves. 
  if (state == 4) 
  {
    blueValue = 250; //sets starting value of blues before fading
    greenValue = 250; //sets starting value of greens before fading
    redValue = 0; //sets starting value of reds before fading
    for(int x = 0; x <= 125 ; x++)
    {
      analogWrite(blueLED, blueValue--); //fades in blue so color turns cyan
      analogWrite(redLED, redValue++); //sets value of red input to 0 or no red
      analogWrite(greenLED, greenValue-2); //stays green throughout movement
      delay(10);
    }
  }
  //state 5 - after fifth cup is hit
  //color will fade to red and start pulsing
  if (state == 5) 
  {
    for(int x = 0; x <= 125 ; x++) //loop to fade to red
    {
      analogWrite(blueLED, blueValue--); //fades in blue so color turns cyan
      analogWrite(redLED, redValue++); //sets value of red input to 0 or no red
      delay(10);
    }
    do{ //pulsing loop
       for (int intensity = 255; intensity >=0; intensity++)
       {
         analogWrite(redLED, intensity);
         delay(2);
       }
       for(int intensity=0;intensity<=255;intensity++) 
       {  analogWrite(redLED,intensity);
          delay(2);
       }
    }while(state!=6); //break once state 6 is reached
  }
   //state 6 - after final cup has been removed
   //colors will quickly start flashing and then reset after 2 seconds of being off 
   if (state == 6)
    { 
      for(int flashing = 0; flashing<=10;flashing++)
      {
        //pulse red fast
       for(int intensity=0;intensity<=255;intensity++) 
       {  analogWrite(redLED,intensity);
          delay(1);
       }
       for (int intensity = 255; intensity >=0; intensity++)
       {
         analogWrite(redLED, intensity);
         delay(1);
       }
       //pulse green fast
       for(int intensity=0;intensity<=255;intensity++) 
       {  analogWrite(greenLED,intensity);
          delay(1);
       }
       for (int intensity = 255; intensity >=0; intensity++)
       {
         analogWrite(greenLED, intensity);
         delay(1);
       }
       //pulse blue fast
       for(int intensity=0;intensity<=255;intensity++) 
       {  analogWrite(greenLED,intensity);
          delay(1);
       }
       for (int intensity = 255; intensity >=0; intensity++)
       {
         analogWrite(greenLED, intensity);
         delay(1);
       }
      }
      analogWrite(blueLED, 0); //shuts off blue LED for 2 seconds
      analogWrite(redLED, 0); //shuts off red LED for 2 seconds
      analogWrite(greenLED, 0); //shuts off green LED for 2 seconds
      delay(2000); //wait 2 seconds
       reset(); //run the reset program
    }   
}
//reset program sets variables back to default state and puts LED's back to blue    
void reset()
{
  for(int z = 0; z<6 ; z++)
  {
    isCupHit[z] = false; //refills the array with false's, telling the program that no cups have been hit. 
  }
  numberOfCupsHit = 0; //no cups of have been hit
  analogWrite(redLED, 0); //red leds are off
  analogWrite(greenLED, 0); //green leds are off
  analogWrite(blueLED, 255); //blue leds on high
  redValue = 0; //store red led value as off or 0
  blueValue = 255; //store blue led value as high
  greenValue = 0; //store green led value as 0
}

Step 10: Pimp It Out!

So the best part about this project is once you've got the sensors wired and ready to go, you can quickly code and make anything! Some future projects I am thinking about is an 8x8 led matrix that changes states with the sensors. The best part would be each cell of the matrix would be housed in a bottle inside the table! Other ideas is to make special games like death cup where the lights only change on one specific cup, adding some kind of incentive to finding the cup (like a treasure hunt).

Also, if you find FSR's to be too expensive then you can easily make switches or use other kinds of pushbuttons or sensors that could work. Especially since for this program a digital switch is really all that's required.

Anywho, this was my first instructable and  I hope you enjoyed it. I would appreciate any criticism or comments you have.