LED Pong
Pong was the start of a new ear. Though it was not the first video game ever invented, it is certainly the one that is credited with starting the video game craze. Its first appearance at a consumer level was with the release of the Magnavox Odyssey in 1972. The Odyssey shipped 12 different games on the console, but Table Tennis (pong) was by far the most popular of them. Later, the concept of video table tennis was refined by Atari into the version we all know and love and given it's new name pong. I have had a slight obsession with this game for a few years. I’ve had the idea of recreating the game using a simple LED matrix. The idea seemed like it would be a lot of fun to build. I wanted to build it in a way where it pays tribute to its roots while putting my own spin on it.
Supplies
These are affiliate links
Parts List
128 X 3v 5mm leds
2X rotary encoders
1X arduino uno (used in early prototyping not in finale build)
ribbon cable (I got my ribbon cable from old computers)
Thin gage wire (i get mine from old ethernet cables)
3d printing filament (I used black PLA+ from esun and gray from hatchbox but the brand really doesn't matter)
Tools that I use
this is just what i used by by no mean are these exact brands required
3d printers (PRUSA I3 MK3S, Creality Ender3 )
Early Testing
I knew that this was going to be a bit of an under-taking, so I started off slow. At first, I wanted to just make sure that my coding skills would be good enough to just and get a handful of LEDs flashing in a certain pattern. So, it started off with just a single row of 16 red LEDs. I took two shift registers that where registers daisy chained together and hooked them up to an audio uno. My goal was just to light up one at a time from left to right.
This wasn't the first time I’ve worked with shift registers, so this wasn't too hard. Using a bread board, I hooked up the latch, clock, and data from the arduino to the first shift register. Then only hooked up latch and clock from the arduino to the second register. Data is sent to the second shift register through pin 9 of the first shift register to pin 14 of the second. The data is sent to the shift registers as bits. So sending 1 or (00000001) to it will result in pin 15 of the register going high while pins (1-7) (11111110) stay low. Sending 2 or(00000010) turns pin 1 high; all the rest are low. Send 128 or (100000000) pin 7 high; all others low. Sending 13 or (00001101) pins 15,2,3 go high, all others low. Now for this test I was using 2 shift registers dasy changed together. This means that if you want to send data to the second register, you have to send two commands. The first command that is sent goes to the first register; then you need to send another command to the registers to push the fist command to the second register. Its not very hard once you get the hang of it. I hooked up 16 LEDs to make sure the shift registers were working properly, then moved onto the next step.
Making the LED Matrix
Normally I don’t like making any type of enclosure until after all the electronics of working properly. I don’t like spending a whole lot of time designing something in fusion360, then building it and then having it turn out that I need to add more electronics than having the redesigned circuit no longer fitting in the enclosure that I made. Then you have to waste time remaking the enclosure.
But, for this build, it was going to be much easier to build the matrix of 128 LEDs with an enclosure, than hooking the LEDs to a bread board for testing. The LED enclosure is 2 pieces of 3d printed plastic. The first piece is made with 128 holes sized to be pressure fit for the LEDS. Each LED is placed into a hole one at a time, then I went back over each LED with a drop of super glue just to make sure that they won’t move anywhere. Next, each positive lead of each LED is soldered to the positive lead of the LED right below it. So, you’ll end up having 16 columns of 8 LEDS with their positive leads soldered together. Then, using some ribbon cable, I attached 16 wires, one to each of the columns.
Next, the second 3d printed plastic plate is attached to the back. This plastic plate has 8 vertical slots in it. Every negative lead of the LED needs the thread into the slots. The ribbon cable is threaded through the bottom, making sure that none of the wires are being pitched. Once done hold the two plastic parts together using 4 4-40 nuts and 4 4-40 screws. Then I soldered each of the negative leads together horizontally. Ending with 8 rows of 16 LEDS soldered together with their negative leads. The slots on the plastic piece ensure that the LEDs will never short out. Then, using some more ribbon cable, I attached 8 wires to each of the negative leads.
Writing the Code
With the matrix done it was now time the write the pong code. The first thing I did was solder 24 header pins to each of the ribbon cable wires and attached them to a bread board. After that, I attached resistors to the 16 positive header pins of the matrix. Then I attached 2 daisy changed shift registers to the resistors. Lastly, I attached a third shift register to the 8 negative header pins.
We already went over how the 2 daisy changed shift registers work, but the third shift register works in the opposite way. It is used to sink the LEDs to ground. So, if we wanted all the led off, we would send 255 or (11111111) and to have them all on we would send 0 or (00000000). So if you wanted to sink each row to ground one at a time, you would send (11111110) then (11111101) then (1111011), ECT.
The way I have the code set up is every is controlled from a 2-dimensional array.
[1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}
A zero represents an off led while a one means the LED is on. This pong game has 3 different items that move, player1, player 2, and the ball. Each time one of them moves, the array is updated to show the current location. The data from the array is sent to the shift register one row at a time. So, for the array above, what we would do is send nothing to the daisy-chined shift register because that controls the last 8 columns and those are all zeros in the first row. Then send 1 or (00000001) to the other shift register because the first LED is lit up. Then the third shift register gets sent 254 or (01111111) so only the first row is grounded.
This process is repeated for each row.
Movement
There are two players in this game of pong, so we are going to need to have a way to control each of them. For this I am using 2 rotary encoders (one for each player). The player is represented by 3 LEDs on each side of the screen. Twisting the rotary encoder clock-wise moves the 3 LEDs down and turning the encoder counter-clockwise moves the LEDs up.
The ball updates its location every 40th loop; it felt like a good speed for testing but if I wanted to make the game harder, I could make the ball update in a fewer number of loops, thus speeding up the ball movement.
When the ball hits a player, it changes direction based on what section of the player’s LEDs the ball hits. When the ball hits the bottom player LED the ball will be given an upward trajectory, if it hits the center LED there is no vertical movement, and if it hits the top the ball will be given a downward trajectory.
Downloads
Soldering the Board
Soldering the board;
For the testing of the software, I was using an Arduino uno because it is easy to use for rapid testing. Because the uno has header pins, it’s very quick and easy to add a new component. But I felt that an Arduino uno was far too big for this application. So, I made the switch to an Arduino nano. This board has the same pinout as the uno, so there is no part of the code that needs to be changed to get it to work with the nano.
I started off by soldering the Arduino nano and the shift registers. Followed by the header pins and the 16 resistors. Then came the rat’s nest of wires. I’m sure if I took a bit more time I could have made it look a bit nicer but when working with a board this small and with this many components on its almost always going to end up looking like a little bit of a mess. Lastly, I soldered in the 2 rotary encoders. Once everything was soldered together, I hooked it back up to power to give it a final test. Everything worked well on the first try, to my surprise.
Designing and Printing the Unit/ Fusion 360
Now with all the electronics working properly now I was able to make the full unit in Fusion 360. (Design Tip: A lot of items in this are pressure fit. Whenever I am making a hole or slot that is pressure fit, I always add 0.01 inches of empty space.) Because I had already built the LED matrix, the first thing I worked on was a way to attach that to the main body. All that required was building another bracket that goes behind the matrix. This also serves as a way to cover the wires and LED leads. 4 4-40 nuts are inserted and pressure fit into the openings than the screws from the matrix are tightened onto those nuts.
The next plastic part to design is the main body. The main body holds the circuit board, power socket, and the 2 rotary encoders. This also has a slot for 2 4-40 nuts. Once the LED matrix bracket is pressed into place screws will be pressed into the bracket and threaded into those nuts.
The next pieces I printed were the knobs for the 2 rotary encoders. These were printed on my ender 3 using gray Hatchbox filament. These knobs are pressure fit with the rotary encoders, but I did use a drop of super glue on the inside of the knob to ensure a strong long-lasting bond with the encoders.
Then the final piece that was printed was a lid that goes over the main body. This is just a simple pressure fitting cover for the electronic. No screws or glue is used for this piece and it fits snug. When I was designing the lid, I though the pressure fit wouldn’t work and would either be too tight to fit properly or be too loose and would constantly come off. But it turned out to be perfect. I could through this unit against a wall and it wouldn’t pop out, and when I wanted to take it apart I just pulled it in the right way and it would come out.
Final Assembly
This part was very easy and straight forward. First thing I did was pop the 4-40 nuts into the hexagonal holes on the matrix bracket and Main body total of 6 nuts. Then I screwed the circuit board into the main body. Because of the way I laid out the components onto the circuit board, I was only able to use 2 Screws to hold it in place, which is good enough but if I were to resolder the board, I would have left more space for the screws. Next, I popped the rotary encoders into place and slid on the knobs. After that, pressed the lid into place. Then pressed to LED matrix and bracket onto the main body and screwed it together. And that was it for the assembly.
Game Play and Final Thoughts
Now the only thing left to do is plug it in and start playing. So how is the gameplay? Honestly not great. The unit works perfectly; each player is easy to control the ball bounces exactly as intended; the rotary encoders work great. The only problem is, it is WAY too easy. The matrix is only 8 LEDs tall, which means that in order to score a point the ball needs to go into a spot which the other player is not occupying. But the player’s paddle is 3 LEDs tall. So at any point in time each player is covering almost 40% of their side of the play field. So it is very hard to miss the ball.
All in all I am very happy with this build. It was very fun to make, it looks good, and I am happy with the final product.