Difference between revisions of "Baseball"

From Mech
Jump to navigationJump to search
Line 120: Line 120:
void main() {
void main() {
setup_adc_ports(AN0_TO_AN5);
setup_adc_ports(AN0_TO_AN5);
setup_adc(ADC_CLOCK_INTERNAL);
setup_adc(ADC_CLOCK_INTERNAL);
while(TRUE){
while(TRUE){


while(innings<3){
while(innings<3){


while(team1==1) {
while(team1==1) {
set_adc_channel(5);
set_adc_channel(5);
delay_us(10);
delay_us(10);
stopswitch = read_adc();
stopswitch = read_adc();
if (stopswitch>200){
if (stopswitch>200){
output_high(BATSWITCH);
output_high(BATSWITCH);
delay_ms(500); //time for player to swing
delay_ms(500); //time for player to swing
output_low(BATSWITCH);
output_low(BATSWITCH);
}
}
set_adc_channel(0);
set_adc_channel(0);
delay_us(10);
delay_us(10);
singlesensor = read_adc();
singlesensor = read_adc();
set_adc_channel(1);
set_adc_channel(1);
delay_us(10);
delay_us(10);
doublesensor = read_adc();
doublesensor = read_adc();
set_adc_channel(2);
set_adc_channel(2);
delay_us(10);
delay_us(10);
triplesensor = read_adc();
triplesensor = read_adc();
set_adc_channel(3);
set_adc_channel(3);
delay_us(10);
delay_us(10);
hrsensor = read_adc();
hrsensor = read_adc();
set_adc_channel(4);
set_adc_channel(4);
delay_us(10);
delay_us(10);
outsensor = read_adc();
outsensor = read_adc();
if (singlesensor > 100) {
if (singlesensor > 100) { //need to check appropriate threshold
singlehit();
singlehit();
delay_ms(1000);
delay_ms(1000);
}
}
if (doublesensor > 100) {
if (doublesensor > 100) {
doublehit();
doublehit();
delay_ms(1000);
delay_ms(1000);
}
}
if (triplesensor > 100) {
if (triplesensor > 100) {
triplehit();
triplehit();
delay_ms(1000);
delay_ms(1000);
}
}
if (hrsensor > 100) {
if (hrsensor > 100) {
homerun();
homerun();
delay_ms(1000);
delay_ms(1000);
}
}
if (outsensor > 100) {
if (outsensor > 100) {
out();
out();
delay_ms(1000);
delay_ms(1000);
}
}
displayscore();
displayscore();
}
while(team2==1) {
}
set_adc_channel(5);

delay_us(10);
while(team2==1) {
stopswitch = read_adc();
set_adc_channel(5);
if (stopswitch>200){
delay_us(10);
output_high(BATSWITCH);
stopswitch = read_adc();
delay_ms(500); //time for player to swing
output_low(BATSWITCH);
if (stopswitch>200){
}
output_high(BATSWITCH);
delay_ms(500); //time for player to swing
set_adc_channel(0);
delay_us(10);
output_low(BATSWITCH);
}
singlesensor = read_adc();
set_adc_channel(1);
set_adc_channel(0);
delay_us(10);
delay_us(10);
doublesensor = read_adc();
singlesensor = read_adc();
set_adc_channel(2);
set_adc_channel(1);
delay_us(10);
delay_us(10);
triplesensor = read_adc();
doublesensor = read_adc();
set_adc_channel(3);
set_adc_channel(2);
delay_us(10);
delay_us(10);
hrsensor = read_adc();
triplesensor = read_adc();
set_adc_channel(4);
set_adc_channel(3);
delay_us(10);
delay_us(10);
outsensor = read_adc();
hrsensor = read_adc();
set_adc_channel(4);
if (singlesensor > 100) {
delay_us(10);
singlehit();
outsensor = read_adc();
delay_ms(1000);
}
if (singlesensor > 100) { //need to check appropriate threshold
if (doublesensor > 100) {
singlehit();
doublehit();
delay_ms(1000);
delay_ms(1000);
}
}
if (triplesensor > 100) {
if (doublesensor > 100) {
doublehit();
triplehit();
delay_ms(1000);
delay_ms(1000);
}
}
if (hrsensor > 100) {
if (triplesensor > 100) {
triplehit();
homerun();
delay_ms(1000);
delay_ms(1000);
}
}
if (outsensor > 100) {
if (hrsensor > 100) {
homerun();
out();
delay_ms(1000);
delay_ms(1000);
}
}
if (outsensor > 100) {
` displayscore();
out();
}
delay_ms(1000);
innings=innings+1;
}
}
team1score=0;
displayscore();
team2score=0;
bases=0;
}
innings=0;
}
innings=innings+1;
}

team1score=0;
team2score=0;
bases=0;
innings=0;
}

}





Revision as of 22:01, 19 March 2008

Team Members

Ming Lee Chow: Biomedical Engineering Class of 2008

Jeremy Klem: Mechanical Engineering Class of 2008

Overview

Mechanical Design

Play Field and Housing

Part

Quantity

Plywood

~4ft^2

Wood Screws

21

Set Screws

10

Acrylic Board

~2ft^2



The general concept is to have a slanted surface similar to a pinball machine. The ball will roll down and the user will try to hit it back up into a single, double, triple or homerun. These "hits" have dampening backstops and milled down grooves to channel the ball into a hole where a sensor is placed. If none of these are hit then the ball rolls back down towards the bat and into an out hole. This was done to limit the number of holes and sensor we would need to create. There are rails along the play field so the ball will not fly off. Underneath, there is a recess, which is an oppositely slanted board to channel the ball back to the pitching apparatus. The housing has sides to mount the bat button and keep the ball from sliding out of the recess.


Baseball Play Field
A Single Target
Baseball Recess


Bat

The Bat was fashioned out of wood on the band saw and sanded to a finish. Two holes were drilled: one to act as an anchoring pivot point and the other to be attached to an actuator. A solenoid, run on the two rechargeable batteries in each kit, was used with a compression spring to actuate the bat. The user interface was a simple push button usually stocked in the lab. This button was located on the right side of the game similar to where pinball buttons are located.

In order to make the game more like baseball we set up a system to only allow the user to swing during a pitched ball. To learn more about this look below to Bat Relay.


Bat with Actuation Arrows


Pitcher

To actuate the ball up to a position to be "pitched" a motor and scooping arm were used. The motor was hooked up to a single rechargeable battery found in the kits. Once activated the arm turns upwards until hitting a static bar. Attached to the bar is a lever switch which sends a pulse to the PIC telling it that a pitch has been thrown. The momentum of the ball would shoot it out of the scoop where a curved ramp would project it onto the play field. The motor is attached to a simple push button so another player can pitch creating a more interactive game.


Pitching Apparatus with Activate Button


Electrical Design

PIC Schematic

Circuit Diagram

Photodiode/Phototransistor Sensor

An IR optical sensor was used to detect the ball falling through a hole.


One of the Sensors Used to Detect the Ball


Bat Relay & Power Supplies

In order to power our solenoid and motor we needed external power. We used the 9.6V rechargeable batteries found in the lab kits. The first battery is permanently connected to the pitching motor as well as in series with the second battery. The two batteries in series are connected to the solenoid via a relay. When the PIC sends a high pulse to activate the coil the user can then activate the solenoid with the bat button. The PIC only sends a .5 second pulse, which is a little more time then is needed to pitch the ball. The PIC is activated to send this pulse when the pitching arm hits the lever switch located on the stopping bar in the back of the game (See pitching above).

Ideally, when the pitch button is activated it will turn the arm upwards and both activate the switch and pitch the ball. The relay will come on allowing the player to complete the loop on the solenoid with the bat button. Once the half second delay ends the relay closes, which means the user can no longer activate the bat. This way only one swing is allowed per pitch.

The Relay to Control the Bat


Seven Segment Displays

PIC Code

Link to full code

General outline of code:

  1. Detect switch on pitching mechanism to enable bat
  2. Detect ball dropping through sensors
  3. Call appropriate function (single, double, triple, home run, or out)
  4. Update position of baserunners and light up base LEDs
  5. Display updated score on 7-segment displays
  6. Switch teams at three outs
  7. End game after three innings


Main function for baseball game:


void main() {
   
   setup_adc_ports(AN0_TO_AN5);
   setup_adc(ADC_CLOCK_INTERNAL);
		
   while(TRUE){ 

      while(innings<3){     

         while(team1==1) {  
    
	    set_adc_channel(5);		
	    delay_us(10);
	    stopswitch = read_adc();
      
	    if (stopswitch>200){
		output_high(BATSWITCH);
		delay_ms(500);      //time for player to swing
		output_low(BATSWITCH);
	    }
      
	    set_adc_channel(0);
	    delay_us(10);
            singlesensor = read_adc();
	    set_adc_channel(1);
	    delay_us(10);
	    doublesensor = read_adc();
	    set_adc_channel(2);
            delay_us(10);
	    triplesensor = read_adc();
            set_adc_channel(3);
	    delay_us(10);
	    hrsensor = read_adc();
            set_adc_channel(4);
            delay_us(10);
            outsensor = read_adc();
      
            if (singlesensor > 100) {   //need to check appropriate threshold
               singlehit();
               delay_ms(1000);
            }
            if (doublesensor > 100) {
               doublehit();
               delay_ms(1000);
            }
            if (triplesensor > 100) {
               triplehit();
               delay_ms(1000);
            }
            if (hrsensor > 100) {
               homerun();
               delay_ms(1000);
            }
            if (outsensor > 100) {
               out();
               delay_ms(1000);
            }
           
            displayscore();
      
         }

        while(team2==1) {  
    
	    set_adc_channel(5);		
	    delay_us(10);
	    stopswitch = read_adc();
      
	    if (stopswitch>200){
		output_high(BATSWITCH);
		delay_ms(500);      //time for player to swing
		output_low(BATSWITCH);
	    }
      
	    set_adc_channel(0);
	    delay_us(10);
            singlesensor = read_adc();
	    set_adc_channel(1);
	    delay_us(10);
	    doublesensor = read_adc();
	    set_adc_channel(2);
            delay_us(10);
	    triplesensor = read_adc();
            set_adc_channel(3);
	    delay_us(10);
	    hrsensor = read_adc();
            set_adc_channel(4);
            delay_us(10);
            outsensor = read_adc();
      
            if (singlesensor > 100) {   //need to check appropriate threshold
               singlehit();
               delay_ms(1000);
            }
            if (doublesensor > 100) {
               doublehit();
               delay_ms(1000);
            }
            if (triplesensor > 100) {
               triplehit();
               delay_ms(1000);
            }
            if (hrsensor > 100) {
               homerun();
               delay_ms(1000);
            }
            if (outsensor > 100) {
               out();
               delay_ms(1000);
            }
           
            displayscore();
      
         }
   
      innings=innings+1;
   
   }

   team1score=0;
   team2score=0;
   bases=0;
   innings=0;
   }

}


Functions for single, double, triple, home run, and out:

Single:

void singlehit(){                
  
   int runsadded, basetemp;
   
   runsadded = singleadvance[bases]>>3;
   basetemp=singleadvance[bases]<<5;
   bases=basetemp>>5;
   
   output_C(bases);
   if(team1==1){
      team1score=team1score+runsadded;
   }
   if(team2==1){
      team2score=team2score+runsadded;
   }
  
}

Double:


void doublehit() {         
   
   int runsadded, basetemp;
   
       
   runsadded = doubleadvance[bases]>>3;
   basetemp=doubleadvance[bases]<<5;
   bases=basetemp>>5;
   
   output_C(bases);
   if(team1==1){
      team1score=team1score+runsadded;
   }
   if(team2==1){
      team2score=team2score+runsadded;
   }

}

Triple:


void triplehit() {
  
   int runsadded, basetemp;
   
       
   runsadded = tripleadvance[bases]>>3;
   basetemp=tripleadvance[bases]<<5;
   bases=basetemp>>5;
   
   output_C(bases);
   if(team1==1){
      team1score=team1score+runsadded;
   }
   if(team2==1){
      team2score=team2score+runsadded;
   }
  
}

Home run:


void homerun() {
   
   int runsadded, basetemp;
     
   runsadded = hradvance[bases]>>3;
   basetemp=hradvance[bases]<<5;
   bases=basetemp>>5;
   
   output_C(bases);
   if(team1==1){
      team1score=team1score+runsadded;
   }
   if(team2==1){
      team2score=team2score+runsadded;
   }
   

}

Out:


void out() {

   outs=outs+1;   //also need to add lines to turn out LEDs on
   
   if (outs==3 && team1==1){     //switch team2 at bat
      team1=0;
      team2=1;
      outs=0;
      bases=0;
      output_low(FIRSTBASE);
      output_low(SECONDBASE);
      output_low(THIRDBASE);
     
   }
   if (outs==3 && team2==1){     //switch team1 at bat
      team2=0;
      team1=1;
      outs=0;
      bases=0;
      output_low(FIRSTBASE);
      output_low(SECONDBASE);
      output_low(THIRDBASE);
      
      
   }


}

Function for scoreboard display:

void displayscore() {

  
      remainder1 = team1score % 10;
      tensdigit1 = (team1score - remainder1)/10;
   
      output_b(remainder1 & 15);
      output_high(PIN_B4);
      delay_ms(2);
      output_b(tensdigit1 & 15);
      output_high(PIN_B5);
      delay_ms(2);
  
      remainder2 = team2score % 10;
      tensdigit2 = (team2score - remainder2)/10;
   
      output_d(remainder2 & 15);
      output_high(PIN_D4);
      delay_ms(2);
      output_d(tensdigit2 & 15);
      output_high(PIN_D5);
      delay_ms(2);
   
      if (outs==0 || outs==3){      //turn on LEDs on scoreboard
      output_low(OUT1);
      output_low(OUT2);
      }
      if (outs==1) {
         output_high(OUT1);
      }
      if (outs==2){
         output_high(OUT1);
         output_high(OUT2);
      }
   
   
         
}

Results and Reflections