Ping Pong Game using Arduino and Accelerometer

Published  August 23, 2016   21
User Avatar Aswinth Raj
Author
Ping Pong Game using Arduino and Accelerometer

Augmented Reality and Virtual Gaming has become a recent trend in the gaming industry. The times of using a keyboard/Joystick and a mouse to play a computer game has gone behind. Now every gaming console comes with a Virtual Controller that helps us to play the game using our body movements and gestures, this way the gaming experience has increased a lot and user feels more involved into the game.

In this project let's try to have fun as we learn through the project. Let us create a game (Yes you heard me correct we are goanna create a game) and play it using your hand’s movement. We are creating the classic Ping Pong Ball Game using Arduino and Accelerometer.

 

Overview:

There are tons of open source software's available these days which has brought loads of happiness for hobbyists like us, and Processing is one of them. With this JAVA based application we can build out own software (.exe format) and also an android application (.apk file). So we are going to use this software to build our game, we have previously used Processing in creating Arduino Chat Room.

The hardware part will consist an Arduino which will fetch the input from an Accelerometer to feed it serially to our computer / Laptop.

So let's go shopping!!!!

 

Components Required:

  • Arduino (any version or model)
  • Accelerometer
  • Connecting wires
  • Interest (Lolz)

Accelerometer-and-Arduino-nano

Accelerometer and Arduino Nano

 

Circuit Explanation:

Ping-pong-game-using-Arduino-and-accelerometer-fritzing-diagram

Ping Ball Game using Arduino and Accelerometer circuit-diagram

Circuit of Arduino Ping Pong Ball Game Project does not involve any complex connections.  I have used an Arduino Nano with an Accelerometer. But there is few things to be taken care of as mentioned below:

1. Your Accelerometer cannot handle 5V, so always connect the Vcc of accelerometer to your 3.3V pin of Arduino.

2. Every Accelerometer suffers from the effect of gravity which has to be handled while programming (simply using a filter).

 

With this in mind let's look into the working of an Accelerometer and how we use it.

 

Working of Accelerometer:

An Accelerometer is a device which can convert acceleration in any direction to its respective variable voltage. This is accomplished by using capacitors (refer image), as the Accel moves, the capacitor present inside it, will also undergo changes (refer image) based on the movement, since the capacitance is varied, a variable voltage can also be obtained.

Accelerometer-working capacitive-Accelerometero 

So, as mentioned above every accelerometer suffers from the problem of gravity effect. No matter how accurate your sensor is calibrated (even your apple phones Accel.), it will be affected by gravity. A more technical explanation for this problem is given below.

"Conceptually, an acceleration sensor determines the acceleration that is applied to a device (Ad) by measuring the forces that are applied to the sensor itself (Fs) using the following relationship:

Ad = - ∑Fs / mass

However, the force of gravity is always influencing the measured acceleration according to the following relationship:

Ad = -g - ∑F / mass

For this reason, when the device is sitting on a table (and not accelerating), the accelerometer reads a magnitude of g = 9.81 m/s2. Similarly, when the device is in free fall and therefore rapidly accelerating toward the ground at 9.81 m/s2, its accelerometer reads a magnitude of g = 0 m/s2. Therefore, to measure the real acceleration of the device, the contribution of the force of gravity must be removed from the accelerometer data. This can be achieved by applying a high-pass filter. Conversely, a low-pass filter can be used to isolate the force of gravity."

Source: Android developers

 

Now, in Arduino we can reduce the effect of gravity by using a Simple Filter. This filter will consist of two arrays, one is used to store the sample values from sensor and the other is used to sort the sample values, and find the most repeated value. Let us implement this algorithm in our Arduino and get our hardware ready. 

 

Programming Arduino:

The Arduino program is given below in Code section. There is no critical data that has to be modified.  But you might want to consider the following:

 

Increase the sample size if your Accel still shows random values.

#define Samplesize   13              // filterSample number

 

Play with the 9600 baud rate to increase the speed of communication between Arduino and Processing. But make sure you change them in both the software (Programs).

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

 

My Accelerometer on X-axis gives 193 on far left end and 280 on far right end, measure them for your Accel and update the value.

toSend = map (smoothData1, 193, 280, 0, 255);

The values are mapped into a single byte of data for serial communication.

Further check the Comments in the below given Code to understand it clearly.

 

Programming Processing:

Processing-code-of-Ping-pong-game-using-Arduino

Processing is open source software which is used by artists for Graphics designing. This software is used to develop software and Android applications. It is quite easy to develop and very much similar to the Android Development IDE. Hence I have shortened the explanation.

The Processing Code for the Ping Pong Game is given here:

Right click on it and click on ‘Save link as..’ to  download the code file. Then open the file in 'Processing' software and click on ‘Run’ button to play the Game. You need to install 'Processing' software to open *.pde files. Comment section is open for queries and also check the comments in the Program to better understand it.

 

Below line, in the void setup() function of Processing code is important,  as it decides from which port to data from.

port = new Serial(this,Serial.list()[4],9600);    //Reads the 4th PORT at 9600 baudrate

Here I have read data from the 4th port from my Arduino.

So for Example if you have COM[5] COM[2] COM[1] COM [7] COM[19]

Then the above code will read data from COM[7].

 

Testing:

Now since our Processing and Arduino sketch is ready, just upload the below given program to Arduino and connect your Arduino to user PC thorough programming cable and launch the game by Run the Processing code file (.pde). That's it! Move your Accelerometer and play your Ping Pong Game. The Video will guide you through the complete project.

 

Once you have understood the program you can create many similar games and play them using your Arduino, Further the Y-axis and Z-axis may also be included for gaming.  

Code

/*
 * Program for filtering the X-axis values of accel and transmitting it serially
 * Programmed by B.Aswinth Raj
 * Dated: 21-08-206
 */

#define AccelPin      A0         // A0 is connected to X-axis of Accel
#define Samplesize   13         // filterSample number
int Array1 [Samplesize];           // array for holding raw sensor values for sensor

int rawData1, smoothData1;      // variables for sensor data

int toSend;

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

void loop()
{     
  rawData1 = analogRead(AccelPin);                              // read X-axis of accelerometer
  smoothData1 = digitalSmooth(rawData1, Array1);  

  toSend = map (smoothData1, 193, 280, 0, 255);             // the data from accelerometer mapped to form a byte
  Serial.write (toSend);
  delay(100);
}

  int digitalSmooth(int rawIn, int *sensSmoothArray){         // "int *sensSmoothArray" passes an array to the function - the asterisk indicates the array name is a pointer
  int j, k, temp, top, bottom;
  long total;
  static int i;
  static int sorted[Samplesize];
  boolean done;

  i = (i + 1) % Samplesize;                  // increment counter and roll over if necc. -  % (modulo operator) rolls over variable
  sensSmoothArray[i] = rawIn;           // input new data into the oldest slot

  for (j=0; j<Samplesize; j++){           // transfer data array into anther array for sorting and averaging
    sorted[j] = sensSmoothArray[j];
  }

  done = 0;                    // flag to know when we're done sorting              
  while(done != 1){        // simple swap sort, sorts numbers from lowest to highest
    done = 1;
    for (j = 0; j < (Samplesize - 1); j++){
      if (sorted[j] > sorted[j + 1]){        // numbers are out of order - swap
        temp = sorted[j + 1];
        sorted [j+1] =  sorted[j] ;
        sorted [j] = temp;
        done = 0;
      }
    }
  }

  bottom = max(((Samplesize * 15)  / 100), 1); 
  top = min((((Samplesize * 85) / 100) + 1  ), (Samplesize - 1));   // the + 1 is to make up for asymmetry caused by integer rounding
  k = 0;
  total = 0;
  for ( j = bottom; j< top; j++){
    total += sorted[j];         // total remaining indices
    k++; 

  }

  return total / k;            // divide by number of samples
}

Video

Have any question realated to this Article?

Ask Our Community Members

Comments

Submitted by Emma on Tue, 01/17/2017 - 15:21

Permalink

I wish to make this project using the same accelerometer i.e. adxl335, but with Arduino Mega2560.

But when I tried sending Serial data to my Arduino before (2 years back, when I was working on a different project), it entered an infinite loop, & I could not reset it in any way whatsoever.
Are there any methods to reset such an Arduino stuck in infinite loop?

Hi Emma,

Which software did you use to send serial data?

You have two ways to do it. 

1. Send data based on a condition (for example after every 100ms)

2. Get an ACK from the Mega before sending the next data.

 

Show us the code if possible, We can guide you from there

Thanks

 

Submitted by Savitha Suresh on Thu, 04/06/2017 - 10:54

Permalink

bottom = max(((Samplesize * 15) / 100), 1);
top = min((((Samplesize * 85) / 100) + 1 ), (Samplesize - 1));
Why is this being done?
Can i sort the array and find the median and work with the median?

Hi Savitha,

bottom = max(((Samplesize * 15) / 100), 1);
top = min((((Samplesize * 85) / 100) + 1 ), (Samplesize - 1))

These two lines are used to find the highest and lowest values in the array, after its been sorted. Yes, you can also think on your own way to smooth the data from the accelerometer. Sometimes mere averaging might also work out. Let me know how the program responds if we use a median as you suggested.

 

Thanks,

Aswinth 

Submitted by King Fai on Thu, 04/27/2017 - 15:04

Permalink

Hi sir.
Is there a change here if I use ADXL 345?
Can you get the 345 code

Submitted by Zerseus on Sun, 09/24/2017 - 16:57

Permalink

Hey, I've done all the connections and used the proper code and it's reading the accelerometer values from the board to the serial monitor but the problem is that it's not sending the serial data to the game so the bar in the game doesn't move when I move the accelerometer, can you help me with this ASAP? Thanks!

Sure I can help,

But what is the problem you facing with processing?

Are you able to launch the sketch? Or do you get any errors while launching it?

If you are able to launch it but cant move the rectangular bar, then most likely you have selected the wring COM port in your processing sketch, use your device manager to check for your arduios COM and edit the sketch according.

A snap shot of your device manager and the edited line (code) will help me to poin out the exact problem. Perhaps you can use the forum for this

 

Thanks for replying!
Yes, I'm able to launch the sketch (it had errored at the start but I changed the port and it worked), the problem was that the bar didn't move. I tested it and it seemed like the "data=port.read();" wasn't being executed, so I changed "if (port.available()>0 && port.available()<30)" to "if (port.available()>0 )" and then it began getting executed, but the new problem is that the serial data input isn't steady i.e. not filtered which makes the bar vibrate (it becomes filtered in the Serial Monitor of the accelfilter program though), so my guess is that the accelfilter smooth output data isn't being sent to Processing, it seems like Processing is just reading the raw data from the port that's connected to my Arduino+Accelerometer. Any ideas on how to fix it? Also, how does the accelfilter actually connect to the game? And do you need to see/know anything else? (I haven't made any significant changes to your code)
(Sorry for replying here, I'm new, would the forum be better for this?)

Yes the forum would have been a much better place for this. Also I can help only if can see where you have made the changes to code.

Anyway, to give a rough idea. You can try the following. First use Arduino serial monitor and try reading the Accel value. Check if they are smooth and filtered. Once you are satisfied with your reading move to processing.

In the processing sketch as soon as you receive the data check if it being received in the correct format by using the print function in processing. These values will be printed in the console of the processing sketch.

Kindly use the forum for you next post thanks!

Submitted by Deepika Gunasekaran on Thu, 01/11/2018 - 09:54

Permalink

Hello Sir,
There is a problem when the accelerometer is connected on the bread board , the bar shown in the game is not moving could you please help us.

Hello Sir,

Thank you for the great game. I'm trying to make an y-axis variant of the moving balk. However I have some difficulties in coding this. Do you have any tips of suggestions?

Thanks a lot in advance

Hello Aswinth,  

I was wondering how you found those values in the map() function for your accelometer, I understand the 0-255 (one byte) but where does the 193 and 280 come from?