Automatic Scoring for a Small Skee-Ball Game

2,465

21

4

Introduction: Automatic Scoring for a Small Skee-Ball Game

Home-made Skee-Ball games can be great fun for the entire family, but their drawback has always been the lack of automatic scoring. I have previously constructed a Skee-Ball machine that funneled the game balls into separate channels based on the scoring ring they passed through. Others have also chosen this construction design. This allowed the player to track their game score manually by adding up the balls in each channel. It would be nice to be able to count your Skee-Ball score electronically so this elaborate channel system could be avoided. I also wanted to design a holding chamber for the game balls. When a new game is started, a door will drop down, allowing the regulation 9 skee balls to be played.

I did not want this game to have a big footprint, so my original idea was to construct a game that used golf balls to play. However, I did not like the way golf balls launched of the game ramp, so I switched to 1-1/2” wooden balls that can be purchased from Woodpecker Crafts. This is the web address:

https://woodpeckerscrafts.com/1-1-2-round-wood-bal...

The final dimensions of the game are 17 inches wide by 79 inches long by 53 inches tall at its highest point (scoreboard). In this Instructable I will concentrate on explaining the electronic components and code needed to implement automatic scoring on a home-made Skee-Ball machine. My previous Instructable entitled “Another Skee-Ball Machine” gives more detailed instructions on the woodworking techniques needed to fabricate a Skee-Ball machine.

Supplies

Game Itself:

· ½” plywood (sides and target board assembly)

· 2 x 4 pine studs (cut to smaller widths for ramp frame)

· ¾” plywood (ramp)

· 1/8” plywood (ramp sides)

· 1 x 4 pine (sides of target assembly)

· 2 x 8 construction framing (launch)

· 4” diameter PVC pipe (scoring rings)

· Acrylic paint set (scoreboard)

· 1/8” thick clear plexiglass (scoreboard)

· Numeral decals (scoring rings)

· Plastic pail top (large scoring ring)

· 4” tall white vinyl tile edge molding (bottom ring of target board)

· Sports netting (protective cage)

· ¾” wood dowels (protective cage

Electronic Components:

· (7) Arcade coin door microswitches with straight wire

· Small machine screws

· ½” x 8 wood screws

· (14) 1” metal right angle brackets

· Arduino Mega

· Various LED lights (built in resistors – used on target board)

· LED lights (for scoreboard)

· 2.3” single digit 7-segment LED (E-Bay)

· 1.2” tall, 4-digit, 7-segment LED (Adafruit Industries)

· Various solder boards

· 220 ohm resistors (for LED lights and tall 7-segment LED)

· Momentary switch (reset switch)

· Servo motor (drop down door for game ball release)

· Misc. wiring and connectors

Step 1: Target Board Assembly

The size of the target board is 16 inches wide by 24 inches long and fabricated from ½” thick plywood. The scoring holes were laid out on the plywood and cut with a 4” diameter hole saw connected to my drill. I used 4” diameter PVC pipe for the scoring rings. They were glued in place with construction glue to be centered over the cut holes.

The larger ring that surrounds the 20-, 30- and 40-point scoring rings was cut from the top of a laundry pail. It was centered and glued into place also. The bottom ring was made from vinyl edging and was glued to the target board after a ¼” router bit was used to form a channel to accept it (so would hold the curve).

A bottom enclosure (box) was built to contain and channel the thrown skee ball to the exit chute. Both the target board and the bottom of the enclosure were lined with a soft mat material to “deaden” the bounce of the solid wooden balls. This is the yoga mat used:

https://www.amazon.com/gp/product/B01IZDFWPG/ref=p...

Once the target board assembly was completed, the sides and top that surround the target assembly were designed, cut out and attached. The target assembly was mounted at a 45 degree angle.

Step 2: Target Board Electronics

An arcade microswitch with a long straight wire was used to detect the skee ball as it drops through a scoring ring. I needed to find someway to attach the microswitch to the underside of the target board. A home-made bracket was designed and fabricated using 1/8” thick hardboard and small right-angle brackets: See below:

https://www.amazon.com/gp/product/B01IZDFWPG/ref=p...

The switch had to be attached to the underside of each scoring hole so as not to interfere with a falling ball, but it also had to be centered so it would not “miss” any balls falling through. The long wire had to be shaped and centered so it would be “tripped” by the ball no matter where it passed through the scoring hole.

I also wanted to add lights to the target board. Small LED lights were mounted to the understand of each scoring hole to illuminate the opening. To accomplish this, a hole had to be countersunk just outside the rim of the scoring hole. A 1” diameter Forstner drill bit was used to drill to a depth on 3/8 inches. The LEDs was then secured with a 1/4” cable clip. The scoring holes were color coded by scoring values. The 10- and 20-point scoring rings were illuminated in red, the 30-, 40- and 50-point scoring rings were illuminated in blue and the two 100-point scoring rings were illuminated in green. As we will see later, this color scheme will match the colors that display on the scoreboard.

Once all switches and LED lights were mounted, they had to be wired and soldered to a centralized perforated wafer board with a standard connector. The wire connections would ultimately run to the mounted scoreboard. All loose wires were tacked down and attached securely against the inside of the target board to not interfere with the game balls as they fell through the scoring rings and traveled to the exit chute.

Step 3: Ramp Assembly

The ramp frame was fabricated from construction studs that were ripped to a 1-1/2” x 2” dimension. The frame was built with cross members about 16 inches apart. The frame had a slight slant to it so the skee balls would roll naturally, by gravity, to their holding area.

Integral to the ramp assembly is the ball return chute and holding area. The played skee balls will accumulate behind a drop-down door mechanism. This mechanism is controlled by a micro servo motor that is wired to the Arduino microprocessor and is programmed to drop down and release the 9 game balls whenever the reset button is pressed.

The micro servo motor was mounted to the frame so the plastic servo arm braces the back of the drop-down door. This door is attached to a freely movable hinge. Once the servo arm is instructed, in code, to swing down 90 degrees, the slant of the ball track and the weight of the wooden balls cause the door to drop down into a flush recess. The balls then move freely to the open bay playing area where they can be retrieved one at a time.

I didn’t show much detail, but the sides of the ramp assembly are framed and covered with thin 1/8 inch plywood to give room for the free movement of the game balls underneath, as described in the previous paragraph. The design simulates how a real arcade size Skee-Ball game would work once you put money in to start the game.

The ramp assembly was completed by milling a ¾ inch cabinet grade plywood bowling lane to fit on top of the frame. Pine 2 x 4 inch studs were used to fabricate legs for the game to raise it off the ground to the proper height for playing the game. To make the game mobile, 2 inch industrial wheels were attached to these legs.

Step 4: Launch Fabrication

I first tried to make a non-solid ball launch using a rib and frame technique. I used thin plywood strips (1/8 inch) glued to some ¾” frame pieces cut in the outline of the launch. I tested this launch with the wood balls and found that it did not work very well. It didn’t feel solid and did not launch the wooden balls as hoped. I decided not to use this launch.

I went back to the launch construction technique I have used previously. The launch was made out of individual pieces of 2 inch thick construction lumber that was glued together to obtain the correct width of the launch. The pattern was traced and cut out on my band saw. All imperfections were filled in with auto body filler. The curves were sanded to the final shape of the launch. This was the final step in completing the ramp assembly.

Step 5: Protective Screen/Cage

The protective screen I fabricated was kind of an afterthought. I thought I would need some protection for the basement with my grand kids playing the game. I did not take any photos of the steps involved. I couldn’t find a material I could work with successfully (PVC pipe, metal pipe, conduit) so I decided to make it out of wood. I used ½” thick plywood and ¾” dowels to make it. It was painted black and then covered with a soccer sports type net. The net material was stapled to the wood. This protective cage was then fastened to the game.

Step 6: Electronic Bench Set-Up

The electronic trail bench set-up is shown in the following photos. I used a 4-line LDC monitor on my test bench to track variables and verify the Arduino code controlling the scoreboard is working correctly. I used this in place of the serial monitor. Pull-up momentary buttons were used to mimic the long-wire coin door arcade switches mounted in the target board. I have one extra long wire arcade switch hooked up just to assure myself that the buttons will work. I also tested some of the LED lights that will be functioning on the scoreboard. The red light that is illuminated in this photo will come on to indicate the “Red Ball” is being rolled. In normal Skee-Ball, this is the ninth or last ball rolled and is worth double the point score of whatever scoring ring it passes through. There will be a green LED that indicates the reset button has been pushed and a new game is starting. There will also be a “Game Over” LED that will light up once all nine balls have been rolled.

There will be six LEDs across the top of the scoreboard. The one that is illuminated at any one time will indicate the scoring ring the last ball rolled went through. Remember, the color of these LEDs will be color coded to the color light illuminating the scoring rings.

Finally, the 7-segment LED displays were wired up and tested. First, a large generic oversize (2.3”) single digit 7-segment LED was purchased on E-Bay. Any oversize display would work. The one I used was a common cathode type and was placed on a small breadboard so the 220-ohm resistors could be soldered in place for each individual LED segment of the display. A wire from each LED segment was terminated on a common male 7-pin (2.54mm) connector. The connector will make it easier to connect to the Arduino Mega board. This oversize 7-segment display will be mounted in the middle of the scoreboard and show the number of balls rolled in the game.

Also mounted in the middle of the scoreboard, above the balls rolled display, is a 4-digit, 7-segment display that will add up the score as each ball is rolled. This 4-digit, 7-segment LED is from Adafruit Industries. It is called a “1.2” 4-Digit 7-Segment Display with 12C Backpack – Red”. The Product ID is 1269. See below:

https://www.adafruit.com/product/1269

The beauty of this display is that it uses a I2C bus controller on the back of the PCB so only two pins are needed to control it. These are the SDA (data line) pin and the SCL (clock line) pin. You will also need a power and ground line to this display. But that is just a total of 4 lines compared to 16 lines needed without this I2C bus controller.

The Arduino code was written and debugged. Once everything was found to be working on the bench, it was time to design and build the scoreboard.

Step 7: Scoreboard Design and Assembly

The wooden enclosure for the scoreboard was made from ½” finished plywood. It will be the same width as the rest of the finished game (17”). It will have a depth of 7” and a height of 9”. A custom painted Plexiglas header overlay will be fabricated to fit on the front of this enclosure. The main mounting board for all the electronic components was cut from 1/4” plywood. It will be positioned right behind the Plexiglas overlay. The lights and 7-segment displays will line up with the corresponding artwork on the Plexiglas overlay. The dimension for this mounting board was cut slightly less than the wooden enclosure. The mounting board was stabilized with a ¾” plywood base attached at the bottom. This made it easier to mount the components.

All the LED lights were positioned on small perforated breadboards with the 220-ohm resistors soldered to the positive terminal. This made it easier to attach the LED’s to the mounting board. At first, I was going to arrange the point value lights in a curve or semi-circle along the top of the scoreboard. However, it turned out to be too difficult to evenly space the lights, so I decided to arrange the point value lights in a straight line across the top with the “New Game” green lighted star in the middle. As mentioned before, the scoring display and the ball count display were centered in the mid-line as the original Skee-Ball arcade games were. On the left side of the 7-segment displays I placed the “Game Over” LED light and on the right side I placed the “Red Ball” LED light. All these components were secured on the mounting board as seen in the photo.

Now that the scoreboard layout was finalized, the Plexiglas overlay header had to be designed and painted to match. Part of the design was based on photos of old classic arcade Skee-Ball machines. The yellow diagonal arrows were an inspiration from these classic games. Other icons were added to indicate what each illuminated LED represented. The design was painted on the Plexiglas using artist type acrylic paints. I am not much of an artist, but I think it came out ok. I had traced a lot of the design on the Plexiglas so I could paint in the design correctly. I also used some magic markers and paint pens, in certain areas, to finish the overlay.

Step 8: Finishing the Electronics

From the rear of the game you can see how I wired all the components together. The last step was to secure all the components to the input and output pins on the Arduino Mega. This processor board was secured on the mounting board base (right side). The perforated breadboard that accepted the arcade micro-switch connections from the target board scoring rings and other connections was also mounted on the mounting board base (left side). There is also a perforated breadboard secured on the mounting board itself that distributed all the 5 VDC power and ground feeds to all the components. This was the main power distribution board. You can see the LED light connections and 7-segment display connections going to their corresponding output pins on the Arduino Mega. This whole component mounting board assembly fits just inside the scoreboard wooden enclosure box and sits behind the Plexiglas overlay where it is secured in place.

Finally, the AC power supply and distribution had to be hooked up. A power transformer with 5-volt DC output was used to power the LED lights that were secured under the target board. They required constant power because they were always on when the game switch was on. A specialized 9-volt DC output transformer was used to power the Arduino Mega board. These transformers were both powered by a regular 110-volt AC power line. A single-pole AC toggle switch was placed in this power line and mounted on the left side of the cabinet to turn the game on and off.

Step 9: Arduino Code

The last thing to discuss is the Arduino code that controls the flow of the game (scoreboard). The Arduino code file is attached. In the code you will see that you must include all Libraries that are needed. Also remember, I used a 4-line LCD monitor to check and debug my code so you will still see references to this code present. It can just be ignored.

First, the arcade micro-switches are assigned pins 43-53. The reset button is attached to pin 9. Next, functions are declared to display digits in the large single 7-segment display, to control the update of the game score and balls rolled displays, and to control which scoring light value is displayed across the top of the scoreboard.

The setup() function first initiates the servo motor. Next, it sets the pin mode to output for all the LEDs that are on the scoreboard and that make up the 7-segment large display. Then the pin mode is set to input for all the arcade micro-switches and the reset button. The internal resistor on the Arduino board is used so separate resisters are not needed for each switch. Finally, the displays are synchronized to zero for the start of the game.

The code in the loop() function is executed many thousand of times per minute; in other words, continuously. Essentially, all it does is check to see if and when a switch has been activated and then executes the corresponding code for that switch. The code will add the game score, count the number of balls rolled, activate the last scoring ball LED and then display all this information on the scoreboard. There are statements to check when 9 balls have been rolled and the game is over or when 8 balls have been rolled and the next ball rolled (Red Ball) will be worth double points. Finally, if the reset button is pushed, the game stops, everything gets put back to zero (variables and displays) and the servo motor arm drops down, so the game balls are released to start play once again.

Step 10: Final Thoughts

The electronic scoreboard seems to function as designed. Only on a rare occasion, will a skee ball not activate the long wire arm of the micro-switch as it falls through the scoring ring. I obtained a copy of a set-up manual for an actual full-size arcade style Skee-Ball machine. It shows the machine is made with Infrared (IR) sensors to detect game balls falling through the scoring rings. If I was to fabricate another Skee-Ball game I think I would use IR break-beam sensors to detect the falling balls. I would use a product from Adafruit Industries called a “IR Break Beam Sensor – 3 mm LEDs” (product ID 2167)

https://www.adafruit.com/product/2167

I used these in another game I designed that was published on Instructables entitled “Electronic Scoring for a Bean Bag Baseball Game” and they worked flawlessly.

Be the First to Share

    Recommendations

    • Halloween Contest

      Halloween Contest
    • Back to School: Student Design Challenge

      Back to School: Student Design Challenge
    • Organization Contest

      Organization Contest

    4 Comments

    0
    mwemaxxowner
    mwemaxxowner

    9 months ago

    This is great!

    I am in the process of working out plans for my own skeeball game. Instructables has been invaluable! I can handle the carpentry, but the programming is new territory for me.

    You mentioned that you'll attach the code you used, but I don't see it. Is there any way we could see that?

    0
    gcall1979
    gcall1979

    Reply 9 months ago

    Thanks, I was able to open the sketch but I will copy it here:

    // File = Skeeballgolfball5.ino
    //**************************************************************
    // 1/20/2020 Covert to basic 1-player after wrote 2-player version
    // 1/26/2020 Added 100 point light
    // 4/17/2020 Start modify to golfball size game.
    // Used internal resistors on all switches (Push = LOW).
    // 4/23/2020 Got single large 7-segment LED working (# of balls)
    // 5/1/2020 Added LED light for each point hole (match LED in hole)
    // 5/4/2020 Almost completed code, adapted well from oneplayerskeeball
    // Added servo for drop down release of balls for new game.
    // 5/2/2020 - Start building score board for top of machine.
    //***************************************************************
    #include <Wire.h> // Enable this line if using Arduino Uno, Mega, etc.
    #include <Adafruit_GFX.h>
    #include "Adafruit_LEDBackpack.h"
    Adafruit_7segment matrix = Adafruit_7segment();
    #include<Wire.h>
    #include<LiquidCrystal_I2C.h>
    LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);
    //==============================Declare Servo======================
    #include <Servo.h>
    int servoPin = 12;
    Servo Servo1;
    //=================================================================
    int switch10Pin = 43;
    int switch20Pin = 45;
    int switch30Pin = 47;
    int switch40Pin = 49;
    int switch50Pin = 51;
    int switch100Pin = 53;
    int switchresetPin = 9;
    int button10State = 1;
    int button20State = 1;
    int button30State = 1;
    int button40State = 1;
    int button50State = 1;
    int button100State = 1;
    int buttonresetState = 1;
    int totalscore;
    int noballs;
    int redball;
    //============================Large 7-segment=================================
    byte seven_seg_digits[10][7] = { { 1,1,1,1,1,1,0 }, // = 0
    { 0,1,1,0,0,0,0 }, // = 1
    { 1,1,0,1,1,0,1 }, // = 2
    { 1,1,1,1,0,0,1 }, // = 3
    { 0,1,1,0,0,1,1 }, // = 4
    { 1,0,1,1,0,1,1 }, // = 5
    { 1,0,1,1,1,1,1 }, // = 6
    { 1,1,1,0,0,0,0 }, // = 7
    { 1,1,1,1,1,1,1 }, // = 8
    { 1,1,1,0,0,1,1 } // = 9
    };
    void sevenSegWrite(byte digit) {
    byte pin = 2;
    for (byte segCount = 0; segCount < 7; ++segCount) {
    digitalWrite(pin, seven_seg_digits[digit][segCount]);
    ++pin;
    }
    }
    //========================================================================
    void displayprogress() //===1st user defined function 1/10/2020
    {
    //-- add single 7 -segment (noballs)
    matrix.print(totalscore);
    matrix.writeDisplay();
    //=========================7segment===============
    sevenSegWrite(noballs);
    //================================================
    lcd.setCursor(0,1);
    lcd.print(" Score = ");
    lcd.print(totalscore);
    lcd.setCursor(0,2);
    lcd.print("Played = ");
    lcd.print(noballs);
    delay(300);
    }
    int controlscoreled(int pinnum){
    digitalWrite(31, LOW);
    digitalWrite(33, LOW);
    digitalWrite(35, LOW);
    digitalWrite(37, LOW);
    digitalWrite(39, LOW);
    digitalWrite(41, LOW);
    digitalWrite(pinnum, HIGH);
    }
    void setup()
    {
    Servo1.attach(servoPin);
    Servo1.write(25);
    //============================Large 7-segment=============
    pinMode(2, OUTPUT);
    pinMode(3, OUTPUT);
    pinMode(4, OUTPUT);
    pinMode(5, OUTPUT);
    pinMode(6, OUTPUT);
    pinMode(7, OUTPUT);
    pinMode(8, OUTPUT);
    //========================================================
    //=============================Hole Value LED Light========
    pinMode(31, OUTPUT); //10
    pinMode(33, OUTPUT); //20
    pinMode(35, OUTPUT); //30
    pinMode(37, OUTPUT); //40
    pinMode(39, OUTPUT); //50
    pinMode(41, OUTPUT); //100
    pinMode(A1, OUTPUT); //=== Game over LED
    pinMode(A0, OUTPUT); //=== Red Ball next LED
    pinMode(A2, OUTPUT); //=== New Game LED
    //=========================================================
    //==============================Use internal resistor============
    pinMode(switch10Pin, INPUT_PULLUP);
    pinMode(switch20Pin, INPUT_PULLUP);
    pinMode(switch30Pin, INPUT_PULLUP);
    pinMode(switch40Pin, INPUT_PULLUP);
    pinMode(switch50Pin, INPUT_PULLUP);
    pinMode(switch100Pin, INPUT_PULLUP);
    pinMode(switchresetPin, INPUT_PULLUP);
    //===============================================================
    matrix.begin(0x70);
    noballs = 0;
    totalscore = 0;
    redball = 1;
    lcd.begin(20,4);
    lcd.setCursor(3,0);
    lcd.print("New Game!");
    matrix.print(0);
    matrix.writeDisplay();
    //======================================== 7-segment single digit====
    sevenSegWrite(0);
    //===================================================================
    }
    void loop()
    {
    button10State = digitalRead(switch10Pin);
    button20State = digitalRead(switch20Pin);
    button30State = digitalRead(switch30Pin);
    button40State = digitalRead(switch40Pin);
    button50State = digitalRead(switch50Pin);
    button100State = digitalRead(switch100Pin);
    buttonresetState = digitalRead(switchresetPin);
    //============================================= Check which button pushed above
    if (buttonresetState == LOW)
    {
    totalscore = 0;
    noballs = 0;
    redball = 1;
    digitalWrite(A1, LOW); //==Game Over LED
    digitalWrite(A0, LOW); //==Red Ball LED
    controlscoreled(48); //==Dummy pin-all point LEDs off
    lcd.begin(20,4);
    lcd.setCursor(3,0);
    lcd.print(" New Game!");
    matrix.clear();
    matrix.print(0);
    matrix.writeDisplay();
    //======================================== 7-segment single digit====
    sevenSegWrite(0);
    //===================================================================
    //===================================Drop door for balls=============
    Servo1.write(90);
    for (int i = 0, i < 6, i++) { // ---- flicker light
    digitalWrite(A2, HIGH);
    delay(500);
    digitalWrite(A2, LOW);
    delay(500);
    }
    Servo1.write(25); // - door back up after 6 seconds
    //===================================================================
    digitalWrite(A2, HIGH); //==New Game LED at Top Middle
    }
    if (button10State == LOW && noballs < 9)
    {
    delay(50);
    controlscoreled(31);
    totalscore = totalscore + (10 * redball);
    noballs = noballs + 1;
    displayprogress();
    }
    if (button20State == LOW && noballs < 9)
    {
    delay(50);
    controlscoreled(33);
    totalscore = totalscore + (20 * redball);
    noballs = noballs + 1;
    displayprogress();
    }
    if (button30State == LOW && noballs < 9)
    {
    delay(50);
    controlscoreled(35);
    totalscore = totalscore + (30 * redball);
    noballs = noballs + 1;
    displayprogress();
    }
    if (button40State == LOW && noballs < 9)
    {
    delay(50);
    controlscoreled(37);
    totalscore = totalscore + (40 * redball);
    noballs = noballs + 1;
    displayprogress();
    }
    if (button50State == LOW && noballs < 9)
    {
    delay(50);
    controlscoreled(39);
    totalscore = totalscore + (50 * redball);
    noballs = noballs + 1;
    displayprogress();
    }
    if (button100State == LOW && noballs < 9)
    {
    delay(50);
    controlscoreled(41);
    totalscore = totalscore + (100 * redball);
    noballs = noballs + 1;
    displayprogress();
    }
    if (noballs == 8) //*******************************
    {
    lcd.setCursor(0,3);
    lcd.print(" Red Ball Next!");
    redball = 2;
    digitalWrite(A0, HIGH); //=====Red Ball LED
    delay(150);
    }
    if (noballs == 9) //*******************************
    {
    digitalWrite(A0, LOW); //==Red Ball LED turned off
    digitalWrite(A1, HIGH); //==Game Over LED on
    digitalWrite(A2, LOW); //==New Game LED turned off
    controlscoreled(48); //==Dummy pin-all point LEDs off
    lcd.setCursor(2,0);
    lcd.print("Game Over!! ");
    lcd.setCursor(0,1);
    lcd.print("Final Score = ");
    lcd.print(totalscore);
    lcd.setCursor(0,2);
    lcd.print(" ");
    lcd.setCursor(0,3);
    lcd.print("Press Reset New Game");
    }
    } //loop
    //==============================================================

    0
    mwemaxxowner
    mwemaxxowner

    Reply 9 months ago

    Thank you very much!

    I'm viewing on a mobile platform, which may be part of my problem.

    At any rate, after I sent that message, I discovered if I downloaded the PDF Instructable, it did give me the file for the code which I do have downloaded.

    I very much so appreciate you taking the time to respond and help me out. I hope I can study your work and use this to come up with my own scoreboard.

    I plan to build my game in such a way that it can be easily scored manually, but I think classic arcade-style electronic scoring really takes it over the top and will make game night that much more fun. I'm currently working my way through a free online course for Python 3.

    0
    cornbread ninja
    cornbread ninja

    1 year ago

    This is fantastic! Do you have a video of it in action?