Introduction: VGA Pong With Arduino Uno

Picture of VGA Pong With Arduino Uno

I have repruduced a color version of the classic Pong running for a VGA monitor, using a bare Arduino Uno.

It is for two players and it has sound too. It has four colors and a resolution of 120 x 60 pixels.

My goal was to avoid any special shield or support IC!

I just used few resistors, a DSUB15 connector, a pair of potenziometers and buttons. The Arduino board and the others components are placed in two wood boxes. The second player paddle is connected to the main block by means of a recycled USB cable. Pictures of the whole "console" and a simple schematic are shown at the beginning of this video:

In the past I have reproduced the B&W version for TV, using the TVout libraries...

...but now, insted of the TVout library, the color Pong is done using the VGAx library recently written by Smaffer.

You can read further the details in this Arduino forum

Instructions to built your own Color Pong with Arduino

In brief, here you can download the latest code version, then you need the VGAx libraries from Smaffer on github published here.

NB it seems that the VGAx library is fully compatible only with Arduino IDE 1.6.4. Older or newer versions may not work properly or work at all.

Once you have the code uploaded an an Arduino Uno (I have Rev. 3) without errors, you can start to build your own console.

You need:

  1. an Arduino Uno Rev. 3
  2. DSUB15 Connector, i.e. a VGA female connector or a VGA cable to be cut.
  3. four resistors: 2 x 68 Ohm and 2 x 470 Ohm
  4. two 10 kOhm potentiometers
  5. two buttons
  6. other two resistors (from 1 to 2 kOhm are fine)
  7. some piece of cable
  8. facoltative: an USB female plug and an USB cable for the second player, or any other connector/cable with four wires

The schematic is reported at the beginning of this Instructable, together with an overview of the finished consolle and how the game looks on my TV.

I placed the Arduino board with the VGA connector in a wood box, which holds also the first player potentiometer and button. I used a second smaller wood box for the second player and I decided to connect it to the main one by means of an USB female plug and an USB cable. You can use any other connector/cable wich contains at least four separated wires.



Pruthvi_96 (author)2017-04-05


We have uploaded the code to the Arduino board but the monitor is showing no signal

Rob Cai (author)Pruthvi_962017-04-07

Dear Pruthvi_96, which Arduino IDE do you have? it seems that the VGAx library is fully compatible with IDE 1.6.4

abomin (author)2016-12-11


Nice projects, thank you!

Is it possible to put 4 your games in one sketch? It would be great!!!

Rob Cai (author)abomin2016-12-12

Thank you for the compliment!
I think it is not possible, almost each game uses all the available memory for the variables and simply putting two or more games together would overtake the 100% of it.
But it would be possible to built a single "consolle" with four buttons and two wheels compatible with all the games, one has just to re-map buttons an potenziometers in the code. I plan to do that as soon as I have time, may be during the Christmas holidays. You just need then to upload the code in the same device.

abomin (author)Rob Cai2016-12-12

It`s true, but if we choose ONE game in start menu (when it powered up or by pressing a reset) - we don`t need a room for variables of ANOTHER games.

About "consolle": I think, it needs one universal connector for 2 types of the manipulators - pot-s or buttons.

Rob Cai (author)abomin2016-12-16

well, it is not so simple. If you join two games in the same sketch (each one with its own variables), the Arduino memory is occupied from the whole variables as soon as they are defined, even if you do not really use the ones for the first game when you play to game two.

The good news is that many variables can be used for one game or the other, you just need to assign theme one value or another, and this save space.

I have a working sketch now where one can choose between pong or breakout, and I plan to add more, but it will take time.

Rob Cai made it! (author)2015-09-21

I tryed to upload the same code on an Arduino NANO ATmega328 and it works as well!

TomášM42 (author)Rob Cai2016-10-30

So, are the resistors required or not? or, would it work without resistors?

Rob Cai (author)TomášM422016-11-01

yes, the resistors are required as well.

TomášM42 (author)Rob Cai2016-11-04

Ok thanks

Pladask (author)2016-10-18


I love Pong and decided to build this as my first Arduino project.

I want to make a table with a screen in so to players can sit on each side and play.

I have got it working but I want to changes, maby someone can help me?

1: I want the green bar to go the oposite way when i turn the knob/potentiometer. Where do I change the code?

2: I have a 4:3 LCD. Is there a way to change screen resolution? Or even better, expand the borders of this pong code?

Rob Cai (author)Pladask2016-10-19

Dear Pladask, for question 1: the easiest way should be to change in

void processInputs() {
buttonOneStatus = digitalRead(BUTTON_ONE_PIN);
buttonTwoStatus = digitalRead(BUTTON_TWO_PIN);
wheelOnePosition = analogRead(WHEEL_ONE_PIN);
wheelTwoPosition = analogRead(WHEEL_TWO_PIN);
buttonStatus = buttonOneStatus || buttonTwoStatus;


void processInputs() {
buttonOneStatus = digitalRead(BUTTON_ONE_PIN);
buttonTwoStatus = digitalRead(BUTTON_TWO_PIN);
wheelOnePosition = 1023 - analogRead(WHEEL_ONE_PIN);
wheelTwoPosition = analogRead(WHEEL_TWO_PIN);
buttonStatus = buttonOneStatus || buttonTwoStatus;

I cannot test it at the moment, let me know if it works.

For question 2 I have no answer. One of the main issues with the VGAx libraries is to center the picture, the best way is to use the center feature of the monitor, when available. The resolution (120 x 60 pixels) is more or less the maximum for the Arduino Uno capabilities, and it is not possible to use all the monitor surface. The yellow borders are the maximum extension available.

When you finish your project I would really appreciate if you can publish here a picture!

Pladask (author)Rob Cai2016-10-28

Hello Rob Cai !

I have finally tested your code and it works perfect! Thank you!

I have so many projects (non-arduino related) going on at the moment and I'm not great with wood, but i hope I can start with the box to put it in soon. I will post a picture when it's ready ;-)

tejanihiren1991 made it! (author)2016-05-02

hello i'm from india and in my country the supply voltage is 230v,50Hz so is there any effect due to this?because right now i got output on Monitor but the word and image display in screen is not proper , the output is like we stretch the all screen. and if this problem is due to supply voltage than please help me where i have to make the change.

Thank You.

Rob Cai (author)tejanihiren19912016-05-03

Dear tejanihiren1991, I am from Italy and we have the same supply voltage, thus I do not think the problem you have is due to that.

I had a similar behaviour while using the VGAX libraries, and at the end it was related to the Arduino software version (IDE), as shown in this video:

I am using now IDE 1.6.4 and I had glitches with IDE 1.0.5 (I haven't tried the latest one).

You should also take care of the groundings, if one is missing you may have unpredictable behaviours. And finally, try with a different monitor. I hope one of these suggestions work for you!

tejanihiren1991 (author)Rob Cai2016-05-05

i want to display small size font on screen, so is there any tool or method that help me.Thank you

Rob Cai (author)tejanihiren19912016-05-09

Well, in principle you can create your own fonts, but on the other hand the actual font resolution is already quite low (vertical x horizontal = 5 x 4 pixels), thus if you shrink it even more I doubt you can obtain something that can be read.

By the way, to create your fonts you have to modify the "glyph" part, such as the lines:

{ 5, 128, 64, 32, 16, 8, 0, }, //glyph '\' code=59

In this example, "5" means that you have a font done by 5 columns (most are only 4), thus here it is 5 raw x 5 columns.

Now every number (from 128 to 8) generate a row (from top to bottom)

128 = 1 0 0 0 0

64 = 0 1 0 0 0

32 = 0 0 1 0 0

16 = 0 0 0 1 0

8 = 0 0 0 0 1

Can you see the glyph "\"? another example

{ 5, 136, 168, 168, 168, 80, 0, }, //glyph 'W' code=54

136 = 1 0 0 0 1 = 128 + 8

168 = 1 0 1 0 1 = 128 + 32 + 8

168 = 1 0 1 0 1

168 = 1 0 1 0 1

80 = 0 1 0 1 0 = 64 + 16

Can you see the glyph "W"?

I hope with these examples you can see the principle.

tejanihiren1991 made it! (author)Rob Cai2016-05-18

Again Thank you so much, i follow your steps and work good,and now i try to make font more bigger than your font, and than i realize that it print only 8 Dot of Horizontal line, Why that happen? If i want to print all word than what i have to do? And is ant Method to decrease pixel size, like normal small font display in Monitor.Sorry for my poor English.

Rob Cai (author)tejanihiren19912016-05-22

Dear tejanihiren1991, I believe there is no simple way to reduce the pixel size! In my understanding the actual resolution (120 x 60 pixels) is already obtained pushing the limit of the Arduino performance. An higher definition means more instructions per unit time! I am not expert since I have not written these libraries, I am just an user. If you read some of the description provided by Smaffer on github (the link is above in the instructables) you may get more information about the working principle and its limits.

tejanihiren1991 (author)Rob Cai2016-05-03

Thank you so much Rob Cai, i update Arduino IDE and now it work Fine.Again Thanks For Help.

rileyborgard (author)2016-04-27

My code compiles and uploads, but my monitor still says no signal. What could be wrong?

Nevermind, I made a simple wiring mistake. It works great! Thanks for this tutorial!

NicolaC22 (author)2016-04-19

Worked perfectly! Thank you so much dude! Just one question: in order to increase the speed of the game, do I just need to edit this lane

#define MAX_Y_VELOCITY 0.1


Thank you so much, tonight I and my friends felt like a 70's friends group *__*

Rob Cai (author)NicolaC222016-04-22

Hi NicolaC22

I am glad to know you have fun with it!

No, to increase the speed you have to modify the line

ballVx = random(50., 80.)/500. + (scoreL + scoreR)/35;

the first part is a random number between 0.1 and 0.16 and the second part is an increment related to the total score (left player + right player) i.e. when the score is 2 vs 5 the ballVx is a random number between 0.3 and 0.36...

...WRONG! I am realizing right now that this formula is wrong! scoreL and scoreR are integers (and < 7) then the second term is always zero!!!

It should be modified like (if I am right):

ballVx = random(50., 80. + 5.*((float) scoreL + (float) scoreR))/500.;

Now, ballVx should go from { 0.1 to 0.16 (score 0 vs 0) } to { 0.1 to 0.3 (score 7 vs 7) }

I cannot test it at the moment, I will come back to this soon...

NicolaC22 (author)Rob Cai2016-04-22

nice, thank you!! will try it asap :) otherwise I'll have a "talk" with the formula xD

Samo2121 (author)2016-01-05

why isnt the code working for me??? halp

Rob Cai (author)Samo21212016-01-07

hi Samo 2121, honestly I think the description you gave of the problem is a bit insufficient...

Samo2121 (author)Rob Cai2016-01-09

oh yea well nvm now its fixed...

MehmetÖ2 (author)2016-01-01

hello rob. i made all of it, codes compiled with no errors but my monitor says no signal?

MichalJ3 (author)MehmetÖ22016-01-07

I think, like was my Problem - you looks on bad side of vga connector. In Scheme is it from rear side, not from front...try it ;)

MehmetÖ2 (author)MichalJ32016-01-08

but i used same scheme with different example and i got signal

Rob Cai (author)MichalJ32016-01-07

Dear MichalJ3, thanks for the suggestion given to MehmetO2. A further hint: the VGA plug pins have always a little numeration (from 1 to 15). You may need a magnifying lens to see them (or a very good view!). In case of doubt, you can follow the - hardly visible - numeration written on the DSUB 15 connector in the schematics above, thus, for instance, RED is on PIN 1, green is 2, etc...

damianlee84 (author)2015-12-08

Hey Rob! I need help! I'm getting an error when compiling the code:

pong_VGAx_v1.3.cpp.o: In function `drawMenu()':

/Applications/pong_VGAx_v1.3.ino:237: undefined reference to `VGAX::printPROGMEM(unsigned char*, unsigned char, unsigned char, unsigned char, unsigned char, char const*, char, char, unsigned char)'

/Applications/pong_VGAx_v1.3.ino:238: undefined reference to `VGAX::printPROGMEM(unsigned char*, unsigned char, unsigned char, unsigned char, unsigned char, char const*, char, char, unsigned char)'

pong_VGAx_v1.3.cpp.o: In function `drawStartScreen()':

/Applications/pong_VGAx_v1.3.ino:303: undefined reference to `VGAX::printPROGMEM(unsigned char*, unsigned char, unsigned char, unsigned char, unsigned char, char const*, char, char, unsigned char)'

/Applications/pong_VGAx_v1.3.ino:304: undefined reference to `VGAX::printPROGMEM(unsigned char*, unsigned char, unsigned char, unsigned char, unsigned char, char const*, char, char, unsigned char)'

/Applications/pong_VGAx_v1.3.ino:305: undefined reference to `VGAX::printPROGMEM(unsigned char*, unsigned char, unsigned char, unsigned char, unsigned char, char const*, char, char, unsigned char)'

pong_VGAx_v1.3.cpp.o:/Applications/pong_VGAx_v1.3.ino:306: more undefined references to `VGAX::printPROGMEM(unsigned char*, unsigned char, unsigned char, unsigned char, unsigned char, char const*, char, char, unsigned char)' follow

collect2: error: ld returned 1 exit status

Error compiling.

Rob Cai (author)damianlee842015-12-09

Hi damianlee84, it looks like a library problem. Do you have the latest version?

At some point the "old" command vga.print had to be changed in vga.printPROGMEM

see this link

Furthermore I have Arduino IDE 1.6.4

Which version are you using?

damianlee84 (author)Rob Cai2015-12-13

Rob! It finally works! Thanks for your help. It was the VGA cable that was very old. I replaced it and it works. But I have another problem now. I started building the circuit and when I added the first potentiometer, it moves both players. I thought it was because I was missing the other potentiometer. I added the second one and now it starts glitching.

Rob Cai (author)damianlee842015-12-14

Hi Damianlee84. When only one potentiometer is connected (on A1) and the other pins are disconnected (A2, A3 and so on) it is normal to have some floating voltage on them that gives unwanted behaviour (such as the second paddle moves following the first one). If you want to temporary test the circuit before it is finished, you should at least ground the unconnected analog pins.

If this does not solve the glitch issue, please try v.1.2. The version 1.3 has just a faster "analogRead()" function, but it is not really needed and I did not tested too much this version.

damianlee84 (author)Rob Cai2015-12-13

Hi Rob, i fixed the library issue. Now, it compiles and uploads the code just fine (although sometimes it gives me a warning: "Low memory available, stability problems may occur"). But it doesn't show me anything on the screen. I haven't set up the buttons and the potentiometers, yet, because I wanted to make sure that it works for me. My IDE is 1.6. and I'm using the latest code (v.1.3). Thanks a lot for your help!

Sunr4 made it! (author)2015-12-05

Hey Rob

Mate its working a treat now ..Thank you so much for your time :)

I made a copy of the original Pong Cab to put it in ...

Will look at how to get sound now ..Really enjoying this one ;)

If you have time in the future iwould like to add sound i will have a play

Rob Cai (author)Sunr42015-12-06

Hi Sunr4, this is really AWESOME! You make me proud of having done this project!

The sound is already implemented in the game code, you just need to connect a speaker to Pin A0 (and to ground of course). Let me know if it does not work!

Sunr4 (author)Rob Cai2015-12-07

Cheers ! :) ... I will work on the sound during the week me and my son have been having little tournaments on it ..Simple game but i think we are having more fun with this than the playstation at the moment :)

Rob Cai (author)2015-11-15

Hi Sunr4, you can connect a further button on digital pin 2 (D2), same way as for the other buttons, then you should modify the sketch as follows (the differences are in Bold) :

1) add the last line

#define WHEEL_ONE_PIN 3 //analog
#define WHEEL_TWO_PIN 1 //analog
#define BUTTON_ONE_PIN A4 //digital
#define BUTTON_TWO_PIN A2 //digital
#define BUTTON_ZERO_PIN D2 //digital

2) modify this part as follows

void processInputs() {
buttonOneStatus = digitalRead(BUTTON_ONE_PIN);
buttonTwoStatus = digitalRead(BUTTON_TWO_PIN);
buttonStatus = digitalRead(BUTTON_ZERO_PIN); // this is the START button
wheelOnePosition = analogRead(WHEEL_ONE_PIN);
wheelTwoPosition = analogRead(WHEEL_TWO_PIN);
//buttonStatus = buttonOneStatus || buttonTwoStatus;

I think it should work, but I cannot test it at the moment. Let me know...

Sunr4 (author)Rob Cai2015-11-17

Changed the new button to A5 seems to work but was wondering if it can start on that button and auto serve for each player until the end of the game ..Like the arcade version ?

Any way only if you have the time :)

Rob Cai (author)Sunr42015-11-30

Hi Sunr4,

sorry for the late reply. What you ask needs a simple modification of the sketch: At the end you have two almost identical parts, a bit after the comments

// ball out from left ----------


// ball out from right ----------


while(buttonOneStatus == 0){
ballY = ((wheelOnePosition / 8) * (VGAX_HEIGHT-PADDLE_HEIGHT-1))/ 128 + 4;
PaddleHit = 0;

you need for both to comment the "while" instruction, and eventually to add a little delay, i.e.

//while(buttonTwoStatus == 0){
ballY = ((wheelTwoPosition / 8) * (VGAX_HEIGHT-PADDLE_HEIGHT-1))/ 128 + 4;
PaddleHit = 0;

Sunr4 (author)Rob Cai2015-11-15

Hey thanks :) Sorry this is my first ever Arduino project so i have lots to learn :)

I have edited what you said and see what you are doing but i am getting an error

D2 was not declared in this scope ?


Rob Cai (author)Sunr42015-11-16

Hi Sunr4, yes, you are right!

1) Modify the first correction of before like this (i.e. "2" instead of "D2")

#define BUTTON_ZERO_PIN 2 //digital

2) now this pin (digital 2) must be decleared as an input in void setup, i.e.:

void setup() {

At least now I can compile without errors, even if I cannot test it yet!

I am happy you have choosen this project as your first ever with Arduino. I hope it works now.

Sunr4 (author)Rob Cai2015-11-22

Hi Rob

Sorry finally got back to this .. I did what you said and the game just jumps straight into the game and severs automatically .. No start screen and the game just keeps looping hehehe :) Getting closer

Really keen to get this finished and show you the final build :)

nodoubtman (author)2015-11-29

no schematic :-(

Rob Cai (author)nodoubtman2015-11-30

Hi Marc. Yes, there is a schematic! Just click the small left picture below the main one on the top!

The two buttons are used to start the game. The ball is assigned to the player that lost the last point, thus he can choose when to throw it.

nodoubtman (author)2015-11-29

Hi. nice instructable :-)

Why are the two button are for?

thank you.


Sunr4 (author)2015-11-15

Is it possible to have a one button start (insert coin) like if it were in a arcade ?

About This Instructable




Add instructable to: