Project tutorial
Smart Basketball Scoreboard

Smart Basketball Scoreboard © GPL3+

What if an Arduino/Android solution was added to a regular basketball board to track my basketball training workouts? Let's go for it!

  • 1,497 views
  • 4 comments
  • 12 respects

Components and supplies

Apps and online services

About this project

I use to do basketball training workouts regularly and I always track the sections statistics (number of shots, scores, misses, training time, etc). Track these numbers is kind of boring and hard to accomplish. The smart balls can be used to this but they have some drawbacks:

  • If you want to train with multiple balls you'll need to buy several (expensive) smart balls.
  • The accuracy isn't so good.
  • The durability of the ball.

In my project smart basketball scoreboard prototype done previously I used the Avnet SmartEdge device to test a method to track my basketball workouts. I used the acceleration sensor to detect the shots and the proximity sensor to detect the scores. This time, the idea of this project is to develop a definitive solution for the basketball scoreboard task.

Step 1: Arduino development

Hardware

Some considerations about the hardware used in this project:

  • Arduino Mega 2560: I just used this board because I'd one available at the moment, you could use any other less expensive one like Uno or Nano, for example.
  • Bluetooth Shield: The same here, I just used it because it was available, a HC-05 Bluetooth module, for example, is a less expensive option.
  • E18-D80NK Infrared Proximity Sensor: Several others proximity sensors could be used in this project, but have in mind that it's better to use one that doesn't suffer from sunlight interference.
  • Rechargeable Li-ion Power: use any source of power you have available.

The schematics is available at the end of the project.

Software

I used the Arduino IDE to develop the Arduino code, programmed with the following strategy:

  • After the initialization (variables, LED, Bluetooth, etc) it stays continuously monitoring the sensors status.
  • If the proximity sensor detects the presence of the ball, it means a shot has just happened and it's a score.
  • If the vibration sensor detects some movement, it means a shot has just happened but it waits for 3 seconds (maximum) to make a decision.
  • In this time, if the proximity sensor detects the presence of the ball, it (immediately) knows it's a score.
  • At the end of the 3 seconds time, if the proximity sensor didn't detect the presence of the ball, it knows it's a miss.
  • The Arduino informs the Android through Bluetooth that a shot (score or miss) has just happened.
  • The process restarts.

The code is available at the end of the project.

Step 2: Android development

I used the MIT App Inventor to develop the Android code, programmed with the following strategy:

  • After the initialization (shots, scores, misses, Bluetooth, etc) it waits for the "Start" button to be pressed.
  • When the "Start" button is pressed it stays continuously monitoring the Bluetooth connection.
  • Every time it receives a shot information it increases the appropriate counter (score or miss) and plays the correct notification sound.
  • Then it calculates the percents and updates the board.
  • The process repeats until the "Pause" or the "Reset" buttons are pressed.

The code is available at the end of the project.

Step 3: Basketball board setup

This is my original basketball board that I regularly use to do basketball training workouts.

First I removed the plastic cover under the hoop and made a hole to the proximity sensor.

Then I made a small hole to fix the vibration sensor.

I could not attach the sensor directly to the plastic cover because of its curvature so I built an internal sensor support using MDF.

I fixed the proximity and vibration sensors using some bolts and a nut.

Them I packed the rest of the electronics in a box.

It's time to a smoke test.

Smart basketball scoreboard test

Finally I installed everything in the basketball board.

Step 4: Basketball workout test

Now it's time to test everything.

The smart basketball scoreboard in action

And finally the grand finale... it's show time!

The smart basketball scoreboard in action

Step 5: Final considerations

  • The system proved to be very accurate, with very few false positives and really rare false negatives.
  • It's really nice to play with the system to know the workout statistics in real-time and after the training.

Now I'll work in some improvements to add some features like:

  • Time management.
  • Memory function.
  • Show more data (shots/min, temperature, etc)
  • Goal notification.

Stay tuned!

Have fun...

Code

Scoreboard.inoArduino
Arduino code
//----------------------------------------------------------------------------//
// Filename    : Scoreboard.ino                                               //
// Description : Smart Basketball Scoreboard                                  //
// Version     : 1.1.0                                                        //
// Author      : Marcelo Avila de Oliveira <marceloavilaoliveira@gmail.com>   //
//----------------------------------------------------------------------------//

//----------------------------------------------------------------------------//
// DEFINITIONS                                                                //
//----------------------------------------------------------------------------//

// TURN ON DEBUG MODE
// #define DEBUG
// #define DEBUG_PROX
// #define DEBUG_VIBR

//----------------------------------------------------------------------------//
// CONSTANTS                                                                  //
//----------------------------------------------------------------------------//

// PINS
const int prox_pin = 2;
const int vibr_pin = 3;
const int led_r_pin = 4;
const int led_g_pin = 5;
const int led_b_pin = 6;

// TIME
const unsigned long wait_interval = 3000;

// MATH
const float percent_to_bright_factor = 100 * log10(2) / log10(255);

//----------------------------------------------------------------------------//
// VARIABLES                                                                  //
//----------------------------------------------------------------------------//

// TIME
unsigned long wait_time;

// STATUS
boolean prox = false;
boolean vibr = false;
boolean wait = false;

//----------------------------------------------------------------------------//
// FUNCTIONS (SETTINGS)                                                       //
//----------------------------------------------------------------------------//

void setup() {
    // INITIATE PINS
    pinMode(prox_pin, INPUT);
    pinMode(vibr_pin, INPUT);
    pinMode(led_r_pin, OUTPUT);
    pinMode(led_g_pin, OUTPUT);
    pinMode(led_b_pin, OUTPUT);

    set_led(5, 100);

    // INITIATE SERIAL COMMUNICATION
    Serial.begin(9600);

    // INITIATE BLUETOOTH COMMUNICATION
    setup_bluetooth();

    set_led(4, 100);

    #ifdef DEBUG
        Serial.println("Board is alive");
        Serial.println();
    #endif
}

void setup_bluetooth() {
    #ifdef DEBUG
        Serial.println("Setting Bluetooth");
        Serial.println();
    #endif

    Serial1.begin(38400);                   // Set baud rate
    Serial1.print("\r\n+STWMOD=0\r\n");     // Set to work in slave mode
    Serial1.print("\r\n+STNA=Arduino\r\n"); // Set name
    Serial1.print("\r\n+STOAUT=1\r\n");     // Permit Paired device to connect me
    Serial1.print("\r\n+STAUTO=0\r\n");     // Auto-connection should be forbidden here
    delay(2000);                            // This delay is required.
    Serial1.print("\r\n+INQ=1\r\n");        // Make the slave inquirable 
    delay(2000);                            // This delay is required.
    while (Serial1.available()) {           // Clear data
        delay(50);
        Serial1.read();
    }
}

//----------------------------------------------------------------------------//
// FUNCTIONS (LIGHT)                                                          //
//----------------------------------------------------------------------------//

int percent_to_bright(int percent) {
    // PERCENT:
    // 0..100
    // RETURN BRIGHT
    // 255..0

    return 256 - pow(2, percent / percent_to_bright_factor);
}

void set_led(int color, int bright) {
    // COLOR:
    // 0 = GREEN
    // 1 = YELLOW  
    // 2 = RED
    // 3 = CYAN
    // 4 = BLUE
    // 5 = MAGENTA
    // 6 = WHITE
    //
    // BRIGHT:
    // 0 = OFF
    // ..
    // 100 = MAX

    #ifdef DEBUG
        Serial.println("Setting LED");
        Serial.println();
    #endif

    if (color < 0 || color > 6 || bright < 0 || bright > 100) {
        return;
    }

    int led_r_bright = 255;
    int led_g_bright = 255;
    int led_b_bright = 255;
    int bright_aux = percent_to_bright(bright);

    switch (color) {
        case 0:
            // GREEN
            led_g_bright = bright_aux;
            break;
        case 1:
            // YELLOW
            led_r_bright = bright_aux;
            led_g_bright = bright_aux;
            break;
        case 2:
            // RED
            led_r_bright = bright_aux;
            break;
        case 3:
            // CYAN
            led_g_bright = bright_aux;
            led_b_bright = bright_aux;
            break;
        case 4:
            // BLUE
            led_b_bright = bright_aux;
            break;
        case 5:
            // MAGENTA
            led_r_bright = bright_aux;
            led_b_bright = bright_aux;
            break;
        case 6:
            // WHITE
            led_r_bright = bright_aux;
            led_g_bright = bright_aux;
            led_b_bright = bright_aux;
            break;
    }

    analogWrite(led_r_pin, led_r_bright);
    analogWrite(led_g_pin, led_g_bright);
    analogWrite(led_b_pin, led_b_bright);

    return;
}

//----------------------------------------------------------------------------//
// FUNCTIONS (CHECK)                                                          //
//----------------------------------------------------------------------------//

void check_prox() {
    if (!prox) {
        if(digitalRead(prox_pin) == LOW) {
            #ifdef DEBUG_PROX
                Serial.println("Proximity detected");
                Serial.println();
            #endif

            prox = true;
            if (!vibr) {
                wait = true;
                wait_time = millis() + wait_interval;
            }
            set_shot(1);
        }
    }
}

void check_vibr() {
    if (!prox && !vibr) {
        if(digitalRead(vibr_pin) == HIGH) {
            #ifdef DEBUG_PROX
                Serial.println("Vibration detected");
                Serial.println();
            #endif

            vibr = true;
            wait = true;
            wait_time = millis() + wait_interval;
            set_led(1, 100);
        }
    }
}

void check_wait() {
    if (wait && millis() > wait_time) {
        if (!prox) {
            set_shot(0);
        }

        reset();
    }
}

//----------------------------------------------------------------------------//
// FUNCTIONS (MIS)                                                            //
//----------------------------------------------------------------------------//

void set_shot(int mode) {
    // MODE:
    // 0 = WRONG SHOT (MISS)
    // 1 = RIGHT SHOT (SCORE)

    if (mode == 0) {
        set_led(2, 100);
    } else {
        set_led(0, 100);
    }

    Serial1.print(mode);
    delay(1000);
}

void reset() {
    vibr = false;
    prox = false;
    wait = false;
    set_led(4, 100);
}

//----------------------------------------------------------------------------//
// MAIN                                                                       //
//----------------------------------------------------------------------------//

void loop() {
    check_prox();
    check_vibr();
    check_wait();
}
Scoreboard.aiaJava
Android MIT App Inventor code
No preview (download only).

Schematics

Scoreboard.jpg
Arduino schematics
Uploads2ftmp2fd3b0e630 6597 44ce a603 da92b3b54f6c2fscoreboard schematics l2ij0btnug

Comments

Similar projects you might like

A DIY Smart Insole to Check Your Pressure Distribution

Project tutorial by Juliette van der Pas

  • 14,089 views
  • 11 comments
  • 43 respects

Arduino Live WiFi Web Scoreboard

Project tutorial by Oli Norwell

  • 10,406 views
  • 0 comments
  • 18 respects

Smart Battery Charger Multiplexer with Smart Display

Project tutorial by leonzak

  • 2,628 views
  • 5 comments
  • 14 respects

Smart Home - Smart Rules using ARTIK Cloud & Photon

Project tutorial by Raghavendra Ponuganti

  • 4,533 views
  • 2 comments
  • 15 respects

Tinkerer Meter, a Bluetooth Multimeter Made with Arduino

Project tutorial by Federico Vivaldi

  • 1,460 views
  • 0 comments
  • 10 respects

Smart Parking System

Project in progress by Md. Khairul Alam

  • 53,826 views
  • 36 comments
  • 122 respects
Add projectSign up / Login