Arduino-Powered Ping Pong Scoreboard With 3D-printed Enclosure
by dlehman in Circuits > Arduino
2366 Views, 23 Favorites, 0 Comments
Arduino-Powered Ping Pong Scoreboard With 3D-printed Enclosure
My twenty-something son came up with a great idea for a gift he wanted to give this Christmas -- a digital scoreboard for Ping Pong matches. A little electronics, a little 3D-printing, it would be great!
Dad, you could help me build this, right? Wanting to retain and bolster my dad-cred, and having just-enough-experience-to-be-dangerous with electronics, I naively agreed. I mean, there was a whole 10 days before Christmas...
I had an old Arduino laying around somewhere, so my son orders two cheap LED matrix displays from Amazon that look promising, confident that "Dad will be able to figure out how to make everything work together." Dad, now feeling the pressure to deliver, starts feverishly googling for helpful tutorials on Arduino display libraries.
Here's a summary of our efforts, in case it may help a future adventurer.
Project Goals
- Enclosure for LED matrix display, which could be hung on the wall
- Box for two arcade buttons, connected to main enclosure via a long cable, used to increment score for each player
- Display would show current score, count up to 21, have to win by 2 points
- Declare a winner!
- Reset so you can play again
Project Accomplishments
The project was heavily influenced by this great Instructables article for a thankfully-similar project. However, there were a few key differences, so I thought it was still worth sharing.
- Stacked LED matrix displays (two-high 32x8 displays), for a final display size of 32x16
- Custom-designed 3D-printed enclosures for main LED display and "remote" two-button enclosure
- Custom-designed fonts for LED display, both a thin 3x7 font for regular-height messages, and a thin "double-high" set of numerals for main score display that would fit two 2-digit scores (eg. "20-19") on the main display without scrolling
Buzzer/Speaker
Our initial project plan was to have a little speaker/buzzer for some basic sound effects (ie. on startup, when you press a button, when someone wins), and the enclosure has room for a piezo buzzer like this, but unfortunately we ran out of time to implement the sound effects. If you get sound effects working, let me know!
Disclaimer: I'm not an electronics expert, or a C++ expert, but this is what worked in our project. But the very nature of Arduino is that--by design--it's very safe and experimentable, even if you're not an expert!
Supplies
The linked parts are just for example. Arduino projects use 5V, which is very low voltage, and therefore extremely accomodating of whatever you have lying around, or can find at the store. We even used a length of Ethernet CAT5 cable for the wire to the "remote" button enclosure, which is a bit fiddly because of the thin wires, but worked just fine!
- Arduino UNO
- LED Matrix Display (2): Any "MAX7219" 8x32 display should work with the supplied code, but the Parola Library we used supports other displays as well.
- Sanwa 30mm arcade buttons (2): Any old buttons will work as Arduino inputs, this is just what my son managed to steal from an arcade stick project i'm working on.
- Electronics wiring: Any 22-26 AWG wire should work fine. I used a length of CAT5 ethernet cable for the buttons, which obviously isn't designed for carrying power, but for low voltage/current, works just fine!
- Soldering iron: You don't need anything fancy, very basic soldering skills required. The cheapest 60W soldering kit you can find will likely work great.
- Resistors (2): I used some 1K resistors I had lying around as pull-down resistors; I think anything up to 10K-20K would work fine
Arduino and Breadboarding
I always start my Arduino projects using a breadboard, so you can quickly try different things out to see what works, and what doesn't. I always do a ton of experimenting by trial & error before the final design is accomplished. Ideally, get a big breadboard with lots of jumper wires.
Hook Up LED Display
We chose this LED display from Amazon, in green, mainly because it was available for quick shipping at the time. It's an MAX7219 32x8 LED Matrix Display. They turn out to be quite common, and there is lots of documentation and library support for Arduino. The single 32x8 display is really four individual 8x8 displays cascaded (wired) together on a board, and you can daisy-chain several of these units in various configurations to make a larger display. For example, you can hook two of them together to make a long 64x8 display, stack them (like we did) for a 32x16 display, or even do both for a four-unit 64x16 display.
This maker guide has good instructions for how to hook up the display to an Arduino:
Connect MAX7219 LED display to Arduino
Arduino SPI (Serial Peripheral Interface)
Arduino uses SPI to communicate with peripheral devices (such as this LED display). It supports hardware SPI, which uses specific pins to do the SPI communication. Arduino can also use software SPI, using whatever pins you want, but it is slower than using the hardware interface. So if possible, use the hardware SPI pins.
To control a MAX72XX device, you only need 3 connections:
- MOSI → DIN: The master line for sending data to the display
- SCK → CLK: Clock pulse which synchronizes data transmission
- SS → CS: Pin used to enable/disable a device
For Arduino UNO, the Serial Clock (CLK) pin is 13, Master Out Slave In (MOSI) pin is 11. I used pin 3 for the CS pin, for no particular reason. So you connect the display like this:
- UNO → Display
- Pin 13 → CLK (serial CLocK)
- Pin 11 → DIN (Data IN)
- Pin 3 → CS
The other two pins on the display panel (VCC, GND) are connected to 5V and ground.
Test the Display with Arduino
I recommend hooking the display to your Arduino and running some example sketches to make sure it's working properly. The Parola library comes with a bunch of helpful examples to try the display, which you can find in your Arduino IDE under the "File > Examples > MD_Parola" menu (after you've installed the library, see Step 4).
Connecting Multiple LED Panels
To connect two (or more) LED panels together, connect the matching pins from the "out" side of one display to the "in" side of the other.
Our LED panel came with an angled female 1x5-pin header, so I soldered it to the "out" side of the one display, and used jumper wires to connect each pin to the matching one on the "in" side of the other. The panel also came with a helpful 5-wire jumper cable but it was too short to work to stack the displays horizontally (cable had to run diagonally from "OUT" side in lower-left to "IN" side in top-right, so we had to extend the cables to make it work.
You can connect multiple panels together, and then in your code, configure how you want to treat them, as extended or stacked into a single display, and/or create multiple zones to display text on different areas of the display.
Parola Library for Arduino
Fortunately for me, it turned out there is already a great Arduino library written for the MAX72XX display. It includes support for defining a custom display as many units wide and high as you want, support for creating multiple zones, scrolling and animation effects, custom fonts, and more. Open source for the win!
To use the library in the Arduino IDE, use the "Tools > Manage Libraries" menu. Search for "md_max" and install both the "MD_MAX72XX" and "MD_Parola" libraries.
This site explains all the functionality available with this library. My project barely scratches the surface of what it can do, including scrolling and animation effects of all kinds, and much more. Very impressive what it can all do.
Parola Library for Arduino - Class Reference
The ArduinoPlusPlus blog has a ton of helpful articles for using the MD_Parola library.
Note: Due to the way LED matrix displays work, you cannot print text to a specific coordinate location on the display, you have to add it to a specific zone, and then you can configure how the text flows in/out of that zone.
Push Buttons
Functionally, a push-button simply connects a wire which sends 5V to an input pin on the Arduino, which can be read as a signal to do something.
I used a pull-down resistor for each button. By putting a resistor before ground, it ensures that when the button is not pressed (open), the input pin on the Arduino will read 0V, but when it is pressed, the input pin will read 5V. To say it another way, when the button is open, the input pin is connected to ground through the resistor as "LOW". When you press the button, it closes the wire and creates an "easier" (no resistance) path to 5V, changing the input pin to read "HIGH".
More info on using pull-up and pull-down resistors with Arduino input pins.
Note: In doing some additional reading afterwards, it appears Arduino may have built-in pull-up resistors that can be accessed from software, so I likely did it the hard way. Also, a push-button can be implemented using either a pull-up or a pull-down resistor configuration, each which has pros/cons that i'm not sure I fully appreciate, but using a pull-down setup worked in our project.
3D Printed Enclosures
My son has some skills with Fusion 360, so he whipped up a model for the enclosure and the button "remote" box. The button openings are 30mm to accommodate the Sanwa arcade buttons and allow them to clip-in. We printed a few tests to ensure the opening in the main enclosure was just the right size to fit the stacked LED displays. We hot-glued everything onto the case. Hot-glue is great for sticking things together, but can still be removed (with some effort) if you need to fix/change something.
Pro top: be aware the hot end of the glue gun can easily melt your PLA model in certain spots if you're not careful where you wave it around.
Solder It Together
You could do without any soldering--just rely on twisted wires and eletrical tape--but soldering makes sure it won't twist apart and stop working at some point, and is a great project to learn to solder on!
I did use some jumper wires to easily connect to the existing header pins on the Arduino. I just hot-glued them on to ensure they wouldn't work themselves out.
Here's a shot of the inside of the enclosure. It looks like a bit of a mess, but it's not as complicated as it looks. Note that each element (display, 2 buttons, buzzer) needs both a red 5V wire and a black ground, so I just made a "pigtail" by twisting together five wires of each color so I could run one to the appropriate pin on the Arduino, and then use one to each element.
Designing Custom Fonts
The default fonts that come with the MD_Parola Arduino library weren't quite what I was looking for. I wanted to display a certain amount of static text at one time on the display, without having to scroll it, so I needed a slim font. After finding a great font editor tool on Github, I ended up making my own fonts, mostly just to try it out and see if I could make it work.
Just save the font files in the same folder as your Arduino project, and include them at the top of the file.
Arduino Coding
The existing Ping Pong Scoreboard project I found here on Instructables provided a great start to the Arduino coding part of the project, especially understanding how to debounce button presses. (Debouncing is adding a short timeout between reading each button press, so you don't get multiple accidental triggers each time a button is pressed.)
I added a bunch of comments to the code, so hopefully you can follow the flow. If you have any questions about how the code works, i'd be glad to try and explain in more detail.
As I was breadboarding with the display and buttons, I frequently uploaded small example code to the Arduino, just to make sure each element was working as intended. Verifying that each element is working, one by one, is a much easier way to test and troubleshoot, rather than hooking everything together, uploading the full code, and then trying to figure out any issues when it doesn't work. Besides, if you write and upload sample and example code as you go, you'll be much more comfortable with how everything works.
- Hook up the display and test that it works with example code
- Test the double-high fonts are working on the display (ie. the custom font files loaded properly)
- Test the buttons work to signal the Arduino
- Run everything!