Skip to main content

For all you ping pong geeks out there here’s a little quick project I put together for fun at the office. The ping pong sensor pairs a smart phone with the Touch OSC app running and a processing sketch to help keep track of your score and capture your failures on camera. Basically our smartphone is sending accelerometer data via OSC to a laptop running our processing sketch. When someone hits the net the phone shakes causing the Z-value of our accelerometer to spike greater than 1 or -1 and triggering a photo to be taken from the laptop. Toggle buttons on the phone also help keep track of scoring and when the value is greater than 21 a win is detected. Simple but fun.

Note: Remember both your phone and laptop need to be on the same wifi network. TouchOSC will also need to have the IP address of your laptop while it’s attached to that network. Once you get that going the devices will be able to transfer data.

You’ll also need the oscP5 library installed.

Processing Code:

//import OSC library
import oscP5.*;
import netP5.*;

import codeanticode.gsvideo.*;
GSCapture cam;

float zAcc;  //variable to store accelerameter y position
int player1;
int player2;
PFont gameFont;

OscP5 oscP5;  //create new instance of OSC

void setup()
{
  oscP5 = new OscP5(this,8000);  //listen at port 8000. Make sure touchOSC on iPad is sending at this port
  size(800,500);
  gameFont = loadFont("AGSchoolbook-Medium-44.vlw"); //whatever font you want to use
  textFont(gameFont, 60);
  player1 = 0;
  player2 = 0;

 cam = new GSCapture(this, 640, 480);
}

void draw () {
  cam.start();
  fill(0,0,255);
  rect(0,0,width/2, height);
  fill(255,0,255);
  rect(width/2,0,width/2,height);

  fill(255);
  text(player1, 200, 250);
  fill(255);
  text(player2, 600, 250); 

  fill(255,255,0);
  pushStyle();
  textSize(30);
  text("ENERGY PONG", 25, 50);
  popStyle(); 

  if (zAcc < 1 && zAcc > -1) {
  } else {
  background(0,255,0);
  pushStyle();
  textSize(120);
  text("NET",width/2,height/2);
  popStyle();
  takePicture();
}
checkWin();
  // println("Z: "+ zAcc);
}

// look for incoming X Y from device accelerometer and store in variable
void oscEvent(OscMessage theOscMessage) {

   if(theOscMessage.checkAddrPattern("/accxyz")==true) {
   float thirdValue = theOscMessage.get(2).floatValue(); // get the second osc argument  

   zAcc = thirdValue;
   }

   if(theOscMessage.checkAddrPattern("/1/toggle1")==true) {
   player1++;
    println(player1);
   }

   if(theOscMessage.checkAddrPattern("/1/toggle2")==true) {
   player2++;
   println(player2);
   }

    if(theOscMessage.checkAddrPattern("/1/push1")==true) {
   player1 = 0;
   player2 = 0;
   }

}

void takePicture() {
    if (cam.available() == true) {
    cam.read();
    image(cam, 80, 10);

   saveFrame("images/game-###.jpg");
   println("Image Captured");
   delay(5000);
   }
}

void checkWin() {
 if(player1 >=21) {
   background(0,0,255);
   fill(255);
   text("Player 1 Wins", 200, height/2);

}if (player2 >= 21){
    background(255,0,255);
  fill(255);
   text("Player 2 Wins", 200, height/2);

}
}