Joana Santos
Published

Basketball Tabletop Game

This is a tabletop basketball game where the players will have 15 seconds to score as many baskets as they can.

IntermediateFull instructions provided829
Basketball Tabletop Game

Things used in this project

Hardware components

SparkFun RedBoard
SparkFun RedBoard
×1
Laser Cutter
×1
Photogate
×1
3D Printer
×1

Story

Read more

Schematics

Sketch #1

Sketch #2

Sketch #3

Sketch #4

Sketch #5

Sketch #6

Sketch #7

Sketch #8

Sketch #9

Sketch #10

Sketch #11

Code

Photogate

Arduino
I used the photogate to count the baskets.
/*
 VernierPhotogateTimmer (v 2013.12.09)
 Monitors a Vernier Photogate connected to BTD connector. 

 Very smiple code to read the Vernier Photogate when connected to digital port 1 of the
 Sparkfun / Vernier shield.

 Each time the photogate is blocked then a "basket" is scored, the number of baskets
 counter is increment and the LED (#13) is light up for 1/4 of a second

 D. Chayes, Mercersburg Makerlab Spring 2016

Added support for SparkFun 7 Segment shield with dispaly

To get this code to work, attached an Serial7Segment to an Arduino Uno using:
 A5 to SCL
 A4 to SDA
 VIN to PWR
 GND to GND

 */
 
#include <SoftwareSerial.h>
#include <Wire.h>

#define DISPLAY_ADDRESS1 0x71     //This is the default address of the OpenSegment

#define FALSE 0
#define TRUE 1

#define GATE_MODE 1              // photogate mode definitions 
#define PULSE_MODE 2
#define PENDULUM_MODE 3

const int ledPin = 13;       // re-purposed pin 13 to tie to the Serial 7 Segment
const int photogatePin = 2; // default pin if plugged into Digital 1 on SparkFun Vernier Shield 

int mode = PULSE_MODE; 
int blocked = FALSE;   // set true when the sensor is blocked
int basket = FALSE;    // set true if a basket event happened
int basket_count = 0;  // number of baskets scored

void setup() {
 
  attachInterrupt(0, photogateEvent, CHANGE);    // photogate_event
  pinMode(ledPin, OUTPUT);
  digitalWrite(ledPin, LOW);

  Wire.begin();                                 //Join the bus as master
  Wire.beginTransmission(DISPLAY_ADDRESS1);     //Send reset command to the display, return cursor to begining
  Wire.write('v');
  Wire.endTransmission();

  i2cSendValue( basket_count);    // set the display to '0'

  Serial.begin(9600);             // set up Serial library at 9600 bps
  Serial.println("");
  Serial.println(" we begin ");

}

void loop () { 
    
   if (basket == TRUE) {
     Serial.print(" Score !!!! ");
     Serial.println( ++basket_count);
     i2cSendValue( basket_count);     //Send the count to the display
  
     basket = FALSE;
     digitalWrite(ledPin, HIGH);
     delay(100);
     digitalWrite(ledPin,LOW);
  }
  
}
/*************************************************
 * photogateEvent()
 * 
 * Interrupt service routine. Handles capturing 
 * the time and saving this to memory when the 
 * photogate issues an interrupt on pin 2.
 * 
 * As it is currently written, the photogate 
 * will only work on Digital Port 1.
 *************************************************/
void photogateEvent() { 
  if ( digitalRead(photogatePin) == 1)
      blocked = TRUE;
  else { 
      blocked = FALSE;
      basket = TRUE;
  }
  
}


/*
 * Given a number, i2cSendValue chops up an integer into four values and sends them out over I2C
*/
void i2cSendValue(int tempCycles) {  
  Wire.beginTransmission(DISPLAY_ADDRESS1); 
  Wire.write(tempCycles / 1000); //Send the left most digit
  tempCycles %= 1000; //Now remove the left most digit from the number we want to display
  Wire.write(tempCycles / 100);
  tempCycles %= 100;
  Wire.write(tempCycles / 10);
  tempCycles %= 10;
  Wire.write(tempCycles); //Send the right most digit
  Wire.endTransmission(); //Stop I2C transmission
 
}

Timer Display + Buzzer

Arduino
This display was programmed to show the players how much time they had left in the game. The game started with 15 seconds on the clock. Once the clock reached 0, the buzzer would go off and the game was over.
// display code //
#include <Wire.h>
#include <TimerOne.h>

#define FALSE 0
#define TRUE 1

#define DISPLAY_ADDRESS1 0x71

int cycles = 0;
int current_seconds = 0;
int isr_event = FALSE;
int count_down = 15;

// buzzer code //
const int buzzerPin = 9;
const int songLength = 18;
char notes[] = "CCCCCCCCCCCCCCCCCC";
int beats[] = {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1};
int tempo = 100;

// button code //
const int button1Pin = 2;  // pushbutton 1 pin
const int ledPin =  13;    // LED pin
int starttime;
int endtime;


void setup () {   // display code //
  
  Wire.begin();

  Serial.begin(9600);
  Serial.println("Open Segment Example Code");

  Wire.beginTransmission(DISPLAY_ADDRESS1);
  Wire.write('v');
  Wire.endTransmission();

  Timer1.initialize(1000000);
  Timer1.attachInterrupt(display_seconds);
  Serial.println("Configuration Complete\n");
  i2cSendValue(count_down);

  pinMode(buzzerPin, OUTPUT);   // buzzer code //

  pinMode(button1Pin, INPUT);   // button code //
  Serial.begin(9600);
  Serial.println (" We begin ");
  pinMode(ledPin, OUTPUT);

}

void loop() {

  int i, duration;
  int button1State;       // display code //
   
  if (isr_event == TRUE ) {
    isr_event = FALSE;

    if ( count_down != -1) {
      i2cSendValue( count_down);
      count_down--;
    }

    if ( count_down == -1) {    // buzzer code //
      
      for (i = 0; i < songLength; i++){ 
        duration = beats[i] * tempo;
        if (notes[i] == ' ')        
         delay(duration);           
        else {                      
          tone(buzzerPin, frequency(notes[i]), duration);
          delay(duration);          
        }
      }

      delay (5000);
      count_down = 15;
     }

/*  button1State = digitalRead(button1Pin);   // button code //

  if (((button1State == LOW))) {
    starttime=micros();
    while (digitalRead(button1Pin) == LOW)
      endtime=micros();
    Serial.println( starttime);
    Serial.println( endtime);    
  if ( (endtime - starttime) > 2000 )
    count_down = 10;
    Serial.println ( "Reset");
    } */
  }
}

void display_seconds() {    // display code //

  isr_event = TRUE ;
 }

void i2cSendValue(int tempCycles) {

  Wire.beginTransmission(DISPLAY_ADDRESS1);
  Wire.write (" ");
  Wire.write (" ");
  Wire.write(tempCycles / 10);
  tempCycles %=10;
  Wire.write(tempCycles);
  Wire.endTransmission();  

}

int frequency(char note)  // buzzer code //
{

  int i;
  const int numNotes = 8;  
  char names[] = { 'c', 'd', 'e', 'f', 'g', 'a', 'b', 'C' };
  int frequencies[] = {262, 294, 330, 349, 392, 440, 494, 523};
  
  for (i = 0; i < numNotes; i++) {
    if (names[i] == note) {
      return(frequencies[i]);
    }
  }
  return(0);
}

Credits

Joana Santos

Joana Santos

4 projects • 5 followers
Thanks to Dave Holzwarth and Dan Chayes.

Comments