Skip to the content.

LED Matrix Scoreboard

If you have ever played a basketball game at an arcade, this project is a perfect desktop version. I built an interactive basketball hoop that will count your score every time you make a basket, it will then display your score on the backboard. The way this works is that there are IR sensors in the hoop that detect when a ball goes in, it then relays that information to the circuit which then makes the score go up.

Engineer School Area of Interest Grade
Braeden P Sacred Heart Prep Electrical Engineering Rising Sophomore

headshot

Modifications

Summary

My vision for this project was to have a sturdy basketball hoop that I could play on with my siblings. It turned out that PLA plastic, a kind used in 3D printers, isn’t the most sturdy material to build a basketball hoop out of. I started thinking about what modifications I could do that would make the hoop more sturdy and playable while keeping all the main elements of the initial project functional. The idea that I came up with was putting it onto the back of a retail mini basketball hoop. I chose this because the retail hoop was already equipped to be shot on and to be dunked on. I then went into Tinkercad to design a 3D model that could attach onto the sides of the backboard and onto the RGB Matrix board. I came up with this model.

diagram

Figure 1: The figure above is my 3D model for my modifications.

Each piece took about five hours to print.When they came out, some holes didn’t fully match up with what I needed, so I drilled some new holes and that fixed that problem. Putting it together was relatively simple. I threaded the IR sensor wires, that detect when a shot has been made, through the loops meant for the net and zip-tied them to the hoop. I then took out one of the bolts holding the hoop to the backboard and threaded the IR sensor wires through that hole. I also created a mounting place for the button so it could sit there comfortably.

Challenges

The process to modify my project was somewhat challenging. One challenge I faced was 3D modeling. That was very time consuming; it ended up taking about two hours between the two. The other problem that I faced was that when the parts were printed, some of the holes didn’t overlap on the slots that I needed to put the screws into. I ended up drilling new holes that would fit into the 3D printed parts.

Conclusion

In the end, I was able to complete the modifications and they hold my RGB Matrix board and button onto the back of the hoop. I’m really happy about my project because of the struggle and triumphs of it all. No success came without its problems and I really appreciate that.

Final Milestone

This milestone finally marks the completion of my project. What I’ve accomplished since my previous milestone is that I calibrated the scoring algorithm. Specifically, the sensitivity of the sensors via the delay. The sensor that I use in this project is an IR break beam sensor. The way the sensor works is that the transmitter sensor sends an infrared beam between the two sensors. When that beam is broken, a signal is sent to the board. In Python, the delay is read as time.sleep() with the delay in the parentheses, and it is situated near the end of my main loop.

diagram

Figure 2: The figure above depicts how a IR break beam sensor works.

Figure Reference: ZDSPB Tech

The sensors now count all baskets made, and the score doesn’t go up by more than two anymore. I did this because initially my sensors were very sensitive because the delay was too short. Then my sensors weren’t sensitive enough because the delay was too long. I had to find the perfect median for my sensors to have the right kind of sensitivity. To find this perfect median, I followed a calibration routine.

My calibration routine was:

  1. Check the score
  2. If it went up by more than 2, increase delay
  3. If it didn’t sense, decrease delay
  4. Repeat steps 1-3 diagram

Figure 3: The figure above shows my calibration routine.

The biggest challenge I faced through this process was figuring out the code. It was very confusing to figure out what was wrong with the code because the developers of the project used the given code and it worked for them but not for me. My biggest triumph was figuring out what was wrong with the code. It was that I had to make a line of code that counted the score into a string. A string is an array of characters and incorporates a wide variety of data types. The other triumph was finding the perfect delay in the code to make the sensors the right sensitivity. In the future, I hope to learn more about computers and the ideas behind code.

Second Milestone

Summary

Since my first milestone, I have worked on the software aspect of my project. There was a sample code that the developers of the project provided that I used, but some of the code didn’t work. I have been troubleshooting their code and I have made it functional, but there are some aspects that I want to change. For example, I need to change the delay so that the project will properly count the score. The purpose of the delay in this specific project is not to overload the Feather with too much input from the sensor. It also controls the sensitivity of the sensor because while the delay is happening, the code isn’t running. Any input that the sensor receives while the code is stopped, the Feather will ignore. When I set the delay very low, for instance at 0.01 seconds, the score would start auto-counting and go up eight with just one basket. This would happen because the delay in the code was less than the time it took for the ball to pass through the hoop. When I put the delay higher, however, it wouldn’t detect the ball some of the time. This would happen because if the delay is high, the program does a lot of waiting. The state of the sensor isn’t constantly being checked, so if I were to make a basket in that state of waiting, it wouldn’t sense the ball go through. So I have to troubleshoot to find the perfect median between sensitive and not.

diagram

Figure 4: The figure above is a finite state machine representation of my code.

Challenges

This milestone has been challenging, especially since my computer didn’t work with the software halfway through the process. For instance, it would keep giving me error codes saying that it couldn’t read information in a number of the files, even though my computer worked perfectly with the files earlier in the process. The other, very persistent wire snapping issue that I had, has still been an issue. The project is at a point where every wire is either tinned or has a more sturdy solid core wire soldered onto it.

Next Steps

I hope to finish troubleshooting my code by the end of the week so I can start working on modifications.

First Milestone

What My Project is

My project is a mini basketball hoop with a RGB matrix scoreboard. It has IR sensors in the hoop that will detect when a ball goes through. The hoop will then make the score on the scoreboard go up by two, just like basketball. It also has a button that starts a new game and resets the score. This milestone was mainly hardware. I put together the entire hoop and connected all the wires. I also soldered all of the parts together. Some things that I soldered were all the wires to the pins on the feather express and featherwing, and the wires connecting to the button. Every time a wire snapped, I soldered a solid core wire onto the tip of it or I tinned it. Tinning a wire is when you apply solder onto the end of a multicore wire to bind the multiple strands together essentially creating a solid core wire. There were also connectors that I soldered onto the featherwing and Feather Express so that the feather express could rest on top of the Featherwing.

hardware

Figure 5: The figure above is a picture of my project built and wired. The arrows point towards the most important parts of the project. schematic

Figure 6: The figure above is a schematic of all the wiring that I did.

Figure Reference: Adafruit

Challenges

The main challenge that I faced in building the hoop was the process of altering multiple mechanical aspects of my project for it to work. For instance, I used a dremel, which is a tool that has a very fast spinning, rough tip, to sand down the acrylic covering of the matrix board because it was too big. I also had to reprint the legs of the hoop as they were too small. The biggest annoyance was that the wires kept snapping off of my circuit boards, so I either soldered solid core wires onto them or tinned them. On top of all that, the matrix board that I have right now is broken, so we have to get a new one. What came with this was a lot of debugging because I initially thought that something was wrong with my circuit board or my wiring. I ended up using a different, bigger, matrix board that was proven to work to hook everything up.

Next Steps

The next step I want to take in my project is to get all of my software working. This includes getting my sensors working, the button, and the speaker all to work. None of this is working right now, so I hope to figure all of this out.

Code

void setup() {
  // put your setup code here, to run once:
 # SPDX-FileCopyrightText: 2020 Liz Clark for Adafruit Industries
#
# SPDX-License-Identifier: MIT

import time
import board
import audioio
import audiomp3
import framebufferio
import rgbmatrix
import displayio
import adafruit_imageload
import digitalio
from adafruit_display_shapes.rect import Rect
from adafruit_bitmap_font import bitmap_font
from adafruit_display_text import label

#  matrix setup
displayio.release_displays()
matrix = rgbmatrix.RGBMatrix(
    width=64,
    height=32,
    bit_depth=4,
    rgb_pins=[board.D6, board.D5, board.D9, board.D11, board.D10, board.D12],
    addr_pins=[board.A5, board.A4, board.A3, board.A2],
    clock_pin=board.D13,
    latch_pin=board.D0,
    output_enable_pin=board.D1,
)
display = framebufferio.FramebufferDisplay(matrix)

#  display groups
start_group = displayio.Group()
score_group = displayio.Group()

#  text & bg color setup for scoreboard
score_text = "      "
font = bitmap_font.load_font("/Fixedsys-32.bdf")
yellow = (255, 215, 0)
navy = 0x000080

score_text = label.Label(font, text=score_text, color=0x0)
score_text.x = 23
score_text.y = 15

score_bg = Rect(0, 0, 64, 32, fill=yellow, outline=navy, stroke=3)

#  start splash screen graphic
start, start_pal = adafruit_imageload.load("/pixelHoops.bmp",
                                           bitmap=displayio.Bitmap,
                                           palette=displayio.Palette)

start_grid = displayio.TileGrid(start, pixel_shader=start_pal,
                                width=64, height=32)
#  adding graphics to display groups
start_group.append(start_grid)
score_group.append(score_bg)
score_group.append(score_text)

#  start by showing start splash
display.root_group = start_group

#  setup for break beam LED pin
break_beam = digitalio.DigitalInOut(board.A1)
break_beam.direction = digitalio.Direction.INPUT
break_beam.pull = digitalio.Pull.UP

#  setup for button pin
button = digitalio.DigitalInOut(board.D4)
button.direction = digitalio.Direction.INPUT
button.pull = digitalio.Pull.UP

#  setup for speaker pin
speaker = audioio.AudioOut(board.A0)

#  mp3 decoder setup
file = "/hoopBloop0.mp3"
mp3stream = audiomp3.MP3Decoder(open(file, "rb"))

#  state machines used in the loop
score = 0
hoops = False
button_state = False
beam_state = False
sample = 0

}

void loop() {
  // put your main code here, to run repeatedly:

while True:
    #  button debouncing
    if not button.value and not button_state:
        button_state = True
    #  debouncing for break beam LED
    if not break_beam.value and not beam_state:
        beam_state = True
    #  if a game hasn't started and you press the button:
    if not button.value and not hoops:
        #  game starts
        hoops = True
        button_state = False
        #  display shows scoreboard
        display.root_group = score_group
        print("start game!")
        time.sleep(0.1)
    if hoops:
        #  if the break beam LED detects a hoop:
        if not break_beam.value and beam_state:
            #  score increase by 2 points
            print(break_beam.value)
            print(score)
            score += 2
            #  an mp3 plays
            file = "/hoopBloop{}.mp3".format(sample)
            mp3stream.file = open(file, "rb")
            speaker.play(mp3stream)
            print("score!")
            #  resets break beam
            beam_state = False
            #  increases mp3 file count
            #  plays the 3 files in order
            sample = (sample + 1) % 3
        #  score text x pos if 4 digit score
        if score >= 1000:
            score_text.x = -1
        #  score text x pos if 3 digit score
        elif score >= 100:
            score_text.x = 7
        #  score text x pos if 2 digit score
        elif score >= 10:
            score_text.x = 16
        elif score >= 0:
            score_text.x = 23
        #  updates score text to show current score
        score_text.text = str(score)
        time.sleep(0.1556486497655)
    #  if a game is in progress and you press the button:
    if not button.value and hoops:
        #  game stops
        hoops = False
        button_state = False
        #  score is reset to 0
        score = 0
        score_text.text = str(score)
        #  display shows the start splash graphic
        display.root_group = start_group
        print("end game!")
        time.sleep(0.5)

}

Bill of Materials

Part Note Price Link
Adafruit Feather M4 Express Holds all the code. $22.95 Link
Adafruit RGB Matrix Featherwing Kit Controls the RGB matrix board. $7.50 Link
64x32 RGB LED Matrix - 4mm pitch The display of the project. $39.95 Link
Adafruit STEMMA Speaker Plays the sound when you make a basket. $5.95 Link
Mini LED Arcade Button - 24mm Translucent Clear Starts and resets games $2.50 Link
IR Break Beam Sensor - 5mm LEDs Senses if you make a basket $5.95 Link
JST PH 2-Pin Cable - Female Connector 100mm Connector wire $0.75 Link
JST PH 2-Pin Cable – Male Header 200mm Connector wire $0.95 Link
STEMMA JST PH 2mm 3-Pin to Female Socket Cable - 200mm Connector wire $1.25 Link
Silicone Cover Stranded-Core Ribbon Cable - 10 Wire 1 Meter Long Connector wire $3.95 Link
Header Kit for Feather - 12-pin and 16-pin Female Header Set Goes onto the feather to connect it to the Featherwing $0.95 Link
Black Nylon Machine Screw and Stand-off Set – M2.5 Thread Screws to connect things onto the board $16.95 Link
5V 4A (4000mA) switching power supply - UL Listed Power supply $14.95 Link

Starter Project: Calculator

Link to my Starter Project

Summary

I chose the calculator for my starter project because I wanted something that I will actually use and have an everyday use for. The way it works is that there is the integrated circuit, or IC, which performs all the calculations. The IC receives the input from the buttons when the buttons are pushed because the button closes a switch which connects the circuit, providing voltage to the IC. When the buttons are in their unpushed position, the switch is open so there is no current between the battery and the IC, but when the button is pushed, it closes the switch onto the circuit which connects a current with voltage to the IC. A switch is an electrical component that disrupts the current in a wire. The IC then displays the number then finished calculation on the seven segment display. The assembly process was pretty simple, the majority of the building process was soldering. Screenshot 2024-06-11 at 3 50 14 PM

Figure 7: The figure above shows how switches function on an electrical circuit. The left shows an open switch and the right shows a closed switch, so the left would be an unpushed button and the right would be a pushed button. The difference between the two is that the left is an open circuit and the right is a closed circuit which means that the right can provide current to the light to light it up while the left can not.

Figure Reference: Research Gate

Components Used

Challenges

Some challenges I faced were soldering and putting the case on. Soldering was somewhat challenging due to the fact that the majority of the project was soldering and some parts were small which made it harder to be precise while keeping the project clean. Another challenge I faced was the case. In the beginning of putting the case on, the battery didn’t fully fit into the slot and the charger didn’t fit into the slot for the charger.

Next Steps

I am very excited to start on my main project and to see what I can learn from it.