Friday, June 28, 2013

How it works

Shot clock (2)

How it works, the process, tech stuff!

So here is a picture!

This is how it is supposed to be set up.


The wires look like a mess, but it really isn't so. The manual controls can be connected via radio control, or a cat5 ethernet cable. 
The seven segment display, buzzer, and LEDS are placeholders for maybe transistors and relays that can activate larger displays, like whole light bulbs, horns, and displays.
Again, this is still a prototype.

Being a prototype, there are problems... I am still solving them.
  • timing is not totally precise, but after 24 seconds the delay is not noticeable, and certainly negligible.
  • doesn't stop at "0" (this is a big problem)
  • laser overheats (get a new laser, simple)
  • drains battery (might need to change batteries after a single game, because you need to power a lot of components)
  • I need a flex resistor (order soon)


List of materials:
  • 2x 74hc595
  • 2x Kingbright 7 segment display
  • 1x attiny44
  • 2x led
  • 4x 9.1k resistor
  • 2x 47k resistor
  • 2x 0.1 uf capacitor (104)
  • 1x 470 resistor
  • 2x transistor
  • 1x 5k trimpot
  • 2x 1k resistor
  • 1x laser
  • 1x phototransistor
  • 2x flex resistor (and maybe weights at the end of them)
  • 3x N.O. buttons
  • 1x piezo buzzer

Here is a video of it!



Schematic:
Here is the link to the PDF
Image:


How it works:

Net shot sensor

  1. A laser shoots it's beam at a phototransistor.
  2. The phototransistor outputs a digital HIGH
  3. That signal goes through an inverter gate (I used a transistor and a few resistors)
  4. That signal goes to the microcontroller
    • If the signal is HIGH, the ball has passed through the net.
    • If the signal is LOW, no ball has passed through the net.
  5. Depending on if the ball passed the net or not, the buzzer will buzz and the timer will restart.

Rim sensor

First of all, I am generating voltage from the two flex sensors.
In flex sensors, the more you flex it, the more resistance it creates.
I have decided to use the flex sensors in a voltage divider. If you look at the schematic, you will notice that R1 (resistor to Vcc) is 47k, while R2 (resistor to ground) is the flex sensor.
    • The more the flex sensor flexes, the more resistance there is on R2, and more power can flow through R1. The more the flex sensor flexes, more voltage is let pass.
Let's look at an example:
  1. The ball hits the backboard
  2. The backboard vibrates more than the rim
  3. More voltage is passed from the backboard than the rim
  4. The microcontroller compares the voltages.
    • If backboard >= rim, do nothing
  1. The ball hits the rim
  2. The rim vibrates more than the backboard
  3. More voltage is passed from the rim than the backboard
  4. The microcontroller compares the voltages.
    • If rim > backboard, buzz and restart the shot clock

Manual controls

The manual controls are connected to the same I/O pins as the sensors. In the end, the I/O pin is only sensing whether that pin is HIGH or LOW.



That's all I have for now.
What needs to be done:
  • Flex sensor
  • test on an actual (indoor) basketball hoop
  • make a PCB to get rid of all the clumsy wires

Here is the code

I used an attiny44 @ 8mhz internal, USBtinyISP as the programmer.

//Made  by TS Wang
//6/1/2013
//Documentation on this project can be found on http://tswangshotclock.blogspot.com/
/*
This project is meant to further improve Spalding's (r) shot clock.

The problems with that shot clock:
-picks up backboard vibration
-does not pick up net shots

Improvements by this shot clock:
-ignores backboard vibration
-picks up on net shots
-allows manual control from the bench
  -manual stop-where-its-at
  -manual stop-and-restart
  -manual stop (reset)
  -manual stop-and-jump-to-zero (if that is useful at all)

This project can be replicated. Replicate all you want.*/

//Attiny44 @ internal rc 8mhz

int latchone = 10;  //ST_CP or 12      Last
int clockone = 9; //SH_CP or 11      Second
int dataone = 2; //DS or 14           FIRST

int latchtwo = 3;
int clocktwo = 4;
int datatwo = 5;

int beeper = 6;

int sensor = 7;
int good = 500;

int readstop = 8;

int sec;

byte digitone[11]= {0x00 ,0x30, 0x6D, 0x79, 0x33, 0x5B, 0x5F, 0x70, 0x7F, 0x7B, 0x7E};

void setup() {
  pinMode(latchone, OUTPUT); pinMode(clockone, OUTPUT); pinMode(dataone, OUTPUT);
  pinMode(latchtwo, OUTPUT); pinMode(clocktwo, OUTPUT); pinMode(datatwo, OUTPUT);
  pinMode(beeper, OUTPUT);
  pinMode(sensor, INPUT); pinMode(readstop, INPUT);
}

void loop() {reading();}



/*************analog reading***********/
void reading() {
  if(digitalRead(readstop) == HIGH) {
    spaztwo();
  }
  if(analogRead(sensor) >= good) {
    spaz();
  }
  else{} 
}
/***************countdown and analog reading****************/
void thedeal() {
  while (sec >= 0){
    countdown(sec);
    sec = sec - 1;
    
    for (int i = 0; i<600; i++){ //change this ~ seconds
      reading();
      compare();
      delay(1);
    }
  }
  sec = 24;
}
/****************blink and restart*************/
void spaz() {
  sec = 24;
  countdown(sec);
  digitalWrite(beeper, HIGH);
  delay(250);
  digitalWrite(beeper, LOW);
  delay(250);
  digitalWrite(beeper, HIGH);
  delay(250);
  digitalWrite(beeper, LOW);
  delay(250);
  sec = 23;
  thedeal();
}

/****************blink and stop***************/
void spaztwo() {
  if (analogRead(sensor) >= good) { 
    digitalWrite(beeper, HIGH);
    delay(250);
    digitalWrite(beeper, LOW);
    delay(250);
    digitalWrite(beeper, HIGH);
    delay(250);
    digitalWrite(beeper, LOW);
    delay(250);
    thedeal();
  }
  else{spaztwo();}
}



/**************comparing backboard to rim vibration**************/

void compare () {
  int backboard = analogRead(0);
  int rim = analogRead(1);
  if (rim > backboard) {
    spaz();
  }
  else {}

}








/*countdown code*/
void countdown(int NTD) {
  switch (NTD) {
    case 24:
      digitalWrite(latchone, LOW);
      digitalWrite(latchtwo, LOW);
      shiftOut (dataone, clockone, LSBFIRST, digitone[2]);
      shiftOut (datatwo, clocktwo, LSBFIRST, digitone[4]);
      digitalWrite(latchone, HIGH);
      digitalWrite(latchtwo, HIGH);
      break;
      
    case 23:
      digitalWrite(latchone, LOW);
      digitalWrite(latchtwo, LOW);
      shiftOut (dataone, clockone, LSBFIRST, digitone[2]);
      shiftOut (datatwo, clocktwo, LSBFIRST, digitone[3]);
      digitalWrite(latchone, HIGH);
      digitalWrite(latchtwo, HIGH);
      break;

    case 22:
      digitalWrite(latchone, LOW);
      digitalWrite(latchtwo, LOW);
      shiftOut (dataone, clockone, LSBFIRST, digitone[2]);
      shiftOut (datatwo, clocktwo, LSBFIRST, digitone[2]);
      digitalWrite(latchone, HIGH);
      digitalWrite(latchtwo, HIGH);
      break;

    case 21:
      digitalWrite(latchone, LOW);
      digitalWrite(latchtwo, LOW);
      shiftOut (dataone, clockone, LSBFIRST, digitone[2]);
      shiftOut (datatwo, clocktwo, LSBFIRST, digitone[1]);
      digitalWrite(latchone, HIGH);
      digitalWrite(latchtwo, HIGH);
      break;
      
    case 20:
      digitalWrite(latchone, LOW);
      digitalWrite(latchtwo, LOW);
      shiftOut (dataone, clockone, LSBFIRST, digitone[2]);
      shiftOut (datatwo, clocktwo, LSBFIRST, digitone[10]);
      digitalWrite(latchone, HIGH);
      digitalWrite(latchtwo, HIGH);
      break;
      
    case 19:
      digitalWrite(latchone, LOW);
      digitalWrite(latchtwo, LOW);
      shiftOut (dataone, clockone, LSBFIRST, digitone[1]);
      shiftOut (datatwo, clocktwo, LSBFIRST, digitone[9]);
      digitalWrite(latchone, HIGH);
      digitalWrite(latchtwo, HIGH);
      break;
      
    case 18:
      digitalWrite(latchone, LOW);
      digitalWrite(latchtwo, LOW);
      shiftOut (dataone, clockone, LSBFIRST, digitone[1]);
      shiftOut (datatwo, clocktwo, LSBFIRST, digitone[8]);
      digitalWrite(latchone, HIGH);
      digitalWrite(latchtwo, HIGH);
      break;
      
    case 17:
      digitalWrite(latchone, LOW);
      digitalWrite(latchtwo, LOW);
      shiftOut (dataone, clockone, LSBFIRST, digitone[1]);
      shiftOut (datatwo, clocktwo, LSBFIRST, digitone[7]);
      digitalWrite(latchone, HIGH);
      digitalWrite(latchtwo, HIGH);
      break;
    case 16:
      digitalWrite(latchone, LOW);
      digitalWrite(latchtwo, LOW);
      shiftOut (dataone, clockone, LSBFIRST, digitone[1]);
      shiftOut (datatwo, clocktwo, LSBFIRST, digitone[6]);
      digitalWrite(latchone, HIGH);
      digitalWrite(latchtwo, HIGH);
      break;
    case 15:
      digitalWrite(latchone, LOW);
      digitalWrite(latchtwo, LOW);
      shiftOut (dataone, clockone, LSBFIRST, digitone[1]);
      shiftOut (datatwo, clocktwo, LSBFIRST, digitone[5]);
      digitalWrite(latchone, HIGH);
      digitalWrite(latchtwo, HIGH);
      break;
    case 14:
      digitalWrite(latchone, LOW);
      digitalWrite(latchtwo, LOW);
      shiftOut (dataone, clockone, LSBFIRST, digitone[1]);
      shiftOut (datatwo, clocktwo, LSBFIRST, digitone[4]);
      digitalWrite(latchone, HIGH);
      digitalWrite(latchtwo, HIGH);
      break;
    case 13:
      digitalWrite(latchone, LOW);
      digitalWrite(latchtwo, LOW);
      shiftOut (dataone, clockone, LSBFIRST, digitone[1]);
      shiftOut (datatwo, clocktwo, LSBFIRST, digitone[3]);
      digitalWrite(latchone, HIGH);
      digitalWrite(latchtwo, HIGH);
      break;
    case 12:
      digitalWrite(latchone, LOW);
      digitalWrite(latchtwo, LOW);
      shiftOut (dataone, clockone, LSBFIRST, digitone[1]);
      shiftOut (datatwo, clocktwo, LSBFIRST, digitone[2]);
      digitalWrite(latchone, HIGH);
      digitalWrite(latchtwo, HIGH);
      break;
    case 11:
      digitalWrite(latchone, LOW);
      digitalWrite(latchtwo, LOW);
      shiftOut (dataone, clockone, LSBFIRST, digitone[1]);
      shiftOut (datatwo, clocktwo, LSBFIRST, digitone[1]);
      digitalWrite(latchone, HIGH);
      digitalWrite(latchtwo, HIGH);
      break;
    case 10:
      digitalWrite(latchone, LOW);
      digitalWrite(latchtwo, LOW);
      shiftOut (dataone, clockone, LSBFIRST, digitone[1]);
      shiftOut (datatwo, clocktwo, LSBFIRST, digitone[10]);
      digitalWrite(latchone, HIGH);
      digitalWrite(latchtwo, HIGH);
      break;
    case 9:
      digitalWrite(latchone, LOW);
      digitalWrite(latchtwo, LOW);
      shiftOut (dataone, clockone, LSBFIRST, digitone[10]);
      shiftOut (datatwo, clocktwo, LSBFIRST, digitone[9]);
      digitalWrite(latchone, HIGH);
      digitalWrite(latchtwo, HIGH);
      break;
    case 8:
      digitalWrite(latchone, LOW);
      digitalWrite(latchtwo, LOW);
      shiftOut (dataone, clockone, LSBFIRST, digitone[10]);
      shiftOut (datatwo, clocktwo, LSBFIRST, digitone[8]);
      digitalWrite(latchone, HIGH);
      digitalWrite(latchtwo, HIGH);
      break;
    case 7:
      digitalWrite(latchone, LOW);
      digitalWrite(latchtwo, LOW);
      shiftOut (dataone, clockone, LSBFIRST, digitone[10]);
      shiftOut (datatwo, clocktwo, LSBFIRST, digitone[7]);
      digitalWrite(latchone, HIGH);
      digitalWrite(latchtwo, HIGH);
      break;
    case 6:
      digitalWrite(latchone, LOW);
      digitalWrite(latchtwo, LOW);
      shiftOut (dataone, clockone, LSBFIRST, digitone[10]);
      shiftOut (datatwo, clocktwo, LSBFIRST, digitone[6]);
      digitalWrite(latchone, HIGH);
      digitalWrite(latchtwo, HIGH);
      break;
    case 5:
      digitalWrite(latchone, LOW);
      digitalWrite(latchtwo, LOW);
      shiftOut (dataone, clockone, LSBFIRST, digitone[10]);
      shiftOut (datatwo, clocktwo, LSBFIRST, digitone[5]);
      digitalWrite(latchone, HIGH);
      digitalWrite(latchtwo, HIGH);
      break;
    case 4:
      digitalWrite(latchone, LOW);
      digitalWrite(latchtwo, LOW);
      shiftOut (dataone, clockone, LSBFIRST, digitone[10]);
      shiftOut (datatwo, clocktwo, LSBFIRST, digitone[4]);
      digitalWrite(latchone, HIGH);
      digitalWrite(latchtwo, HIGH);
      break;
    case 3:
      digitalWrite(latchone, LOW);
      digitalWrite(latchtwo, LOW);
      shiftOut (dataone, clockone, LSBFIRST, digitone[10]);
      shiftOut (datatwo, clocktwo, LSBFIRST, digitone[3]);
      digitalWrite(latchone, HIGH);
      digitalWrite(latchtwo, HIGH);
      break;
    case 2:
      digitalWrite(latchone, LOW);
      digitalWrite(latchtwo, LOW);
      shiftOut (dataone, clockone, LSBFIRST, digitone[10]);
      shiftOut (datatwo, clocktwo, LSBFIRST, digitone[2]);
      digitalWrite(latchone, HIGH);
      digitalWrite(latchtwo, HIGH);
      break;
    case 1:
      digitalWrite(latchone, LOW);
      digitalWrite(latchtwo, LOW);
      shiftOut (dataone, clockone, LSBFIRST, digitone[10]);
      shiftOut (datatwo, clocktwo, LSBFIRST, digitone[1]);
      digitalWrite(latchone, HIGH);
      digitalWrite(latchtwo, HIGH);
      break;
    case 0:
      digitalWrite(latchone, LOW);
      digitalWrite(latchtwo, LOW);
      shiftOut (dataone, clockone, LSBFIRST, digitone[10]);
      shiftOut (datatwo, clocktwo, LSBFIRST, digitone[10]);
      digitalWrite(latchone, HIGH);
      digitalWrite(latchtwo, HIGH);
      break;
  }
}

All documents can be found on my Google Drive:
https://drive.google.com/folderview?id=0B5gFDZ2efTDSX0hPdG5sWWJuemc&usp=sharing
Files will be added.

Please ask questions in the comments.

This is the shot clock that will change the game.

No comments:

Post a Comment