HOME            BACK

 

Master(C32) module

 

This module provides functions to control the robot to play the game.

 

The master finds the direction to move the platform from the outputs of IR sensors and tape detectors, and gives an order to the slave accordingly.

 

Here is code for this module. Please click on the menu for detail.

 

- Pseudo Code

 

- Source Code

 

 

 

 

 

HOME            BACK             TOP

 

 

Pseudo Code

 

 

/***** MAIN FUNCTION *****/

 

void main(void) {

          Initialize the master system

          Wait for the signal from an electronic flash before moving

          Start the timer to count 2 min.

Repeat - play the game for 2 minutes

    Find Ball Dispenser

    Follow Tape to Dispenser

    Request Balls

    Find Goal3

    Follow Tape to Goal3

    Release Balls

End

}

 

//**************************************************************************************************

// Function : void Initialize(void);

// Initialize timer, SPI, and motor

//**************************************************************************************************

void Initialize(void) {

          Initialize Timer

          Initialize SPI

          Enable Interrupts

          Initialize Motor

}

 

//**************************************************************************************************

// Function : void InitSPI(void);

// initialize SPI

//**************************************************************************************************

void InitSPI(void) {

          Enable SPI

          Select Master mode

          Set clock polarity and phase - mode 3

          Set Baud rate = 24 MHz / {(0+1)*2^(7+1)} = 93.75 kHz */

Set SS control

Enable SPI interrupt

}

 

//**************************************************************************************************

// Function : void InitTimer(void);

// initialize timer sub-system

//**************************************************************************************************

void InitTimer(void) {

          Turn the timer system on

          Set pre-scale to /16 = 1.5MHz 

          Enable local interrupt for Timer 0, 3, 4, and 7

          Set cap/comp 0, 3, and 4 to input capture

          Set cap/comp 7 to output compare

Set up IC0, 3 to capture falling edge only

Set up IC4 to capture rising edge only

}

 

 

//**************************************************************************************************

// Function : void InitMotor(void);

// initialize ball release motor

//**************************************************************************************************

void InitMotor(void) {

          Activate the Motor bits as output

          Set Motor bits low

}

 

//**************************************************************************************************

// Function : void StartTimer(void);

// start the timer when the game starts

//**************************************************************************************************

void StartTimer(void) {

          Clear over flow flag

          Enable overflow interrupt

          Calculate game over time in int

          Calculate overflow limit

          Set current overflow to be zero

          Set timeoverFlag to be waiting (i.e. not over)

}       

 

//**************************************************************************************************

// Function :  void FindBallDispenser( void);

// Find the ball dispenser (DC50), move straight

//**************************************************************************************************

void FindBallDispenser( void){

Make initial turn in CW to search for ball dispenser (DC50)

          Clear DCdetect flags

Repeat to find ball dispenser and go straight after finding

                   If DC 70 has been detected,

                             If duty cycle 50 has been detected,

                                      Move straight

                                      Break

                             END If

                   END If

                   Break

          END

         

          Increment function count

}

 

//**************************************************************************************************

// Function :  void FollowTapeTo(int loc);

// stop at the black tape, turn, track tape, stop at the end of the tape

//**************************************************************************************************

void FollowTapeTo(int loc) {

          If loc is ball dispenser (i.e. going to dispenser),

                   Detect Black Tape

 

                   If going to dispenser 1st time in the game

                             Move straight until the robot meets the tape

                             If Left tape sensor sees the tape first,

                                      Robot is on A side

                                      Turn CW for 350 ms.

                                      Move straight

                             ELSE

                                      Robot is on B side

                                      Turn CCW for 350 ms.

                                      Move straight

                             END If

                   END If

 

                   Move forward until robot hits the tape again

                   Move forward so that both sensors can see the part of tape

                   Make a turn to look at the dispenser

          ELSE If loc is goal3

                   Set the tape color to follow to be green

                   Move forward until the robot meets the tape

                   Move forward so that both sensors can see the part of tape

                   Make a turn to align with the tape

          END If

 

          Repeat- move forward along the tape until two sensors further apart hit the tape

                   PD control of the angular velocity of two wheels to track the tape

                   Read Left and Right tape sensor values for the AD port

                   Compute error = Left sensor value – Right sensor value

                   Compute error_dot = a * error_dot_old  + (1-a) * error_dot_new

                                                    = a * error_dot_old + (1-a) * (error – error_old) / dt

                   Calculate angular velocity wc = error*Kp + error_dot*Kd

Save error_old = error

Save error_dot_old = error_dot

Compute Left motor PWM (mLc) = forward velocity - wc

Compute Right motor PWM (mRc) = forward velocity + wc

If the PWM’s are larger than 50, set them to 50

If the PWM’s are smaller than -50, set them to -50

Separate the range of Left motor PWM and Right motor PWM by adding and subtracting 51

                   Send the control values to slave

          END

 

Stop if both of two further apart tape sensors see tape

}

 

//**************************************************************************************************

// Function : void RequestBalls (void) ;

// push dispenser

//**************************************************************************************************

void RequestBalls (void) {

          Request 5 balls

                   Move straight to push

                   Wait for 1 sec

                   Move backward

          END

         

          Request 5 more balls only at the first request

                   Wait for 10 sec

Request 5 balls

                   Move straight to push

                   Wait for 1 sec

                   Move backward

          END

END

}

 

//**************************************************************************************************

// Function : void FindGoal3(void);

// turn to search goal3 (DC90), move straight, stop at the tape

//**************************************************************************************************

void FindGoal3(void) {

Make initial turn to search for goal 3(DC90)

          Clear flags

Repeat scanning until robot finds goal3

Go straight after finding

}

 

//**************************************************************************************************

// Function : void ReleaseBalls(void);

// turn to look at goal3, release balls

//**************************************************************************************************

void ReleaseBalls(void) {

          Turn to align with goal 3

          Clear flags

          Move forward when goal 3 is detected

          Release balls

          Back up for next movement

}

 

//**************************************************************************************************

// Function : void Release(void);

// Release the balls

//**************************************************************************************************

void Release(void) {

          Open the door twice to release balls 

Lower motor bits to prevent the circuit from burning

}

 

//**************************************************************************************************

// Function : void Wait(unsigned long timeMS);

// wait for timeMS(ms)

//**************************************************************************************************

void Wait(unsigned long timeMS) {

          Compute wait start time

          Compute wait end time

          Compute overflow

          Wait for timeMS(ms) until current time equals wait end time

                   Update current time

          END

}

 

//**************************************************************************************************

// Function : unsigned char ReadColor(unsigned char sensor) ;

// returns which color the tape sensor #(sensor) is seeing

//**************************************************************************************************

unsigned char ReadColor(unsigned char sensor) {

          If the tape sensor sees black, RETURN black

          ELSE If the tape sensor sees green, RETURN green

          ELSE If the tape sensor sees red, RETURN red

ELSE return blank

}

 

//**************************************************************************************************

// Interrupt for Timer 0: void interrupt 8 FlashDetection( void);

// detect flash at the beginning of game

//**************************************************************************************************

void interrupt 8 FlashDetection( void){

Set the flag to start

Clear IC0 flag 

}

 

//**************************************************************************************************

// Interrupt for Timer 3: void interrupt 11 BeaconDutyCheck_FallingEdgeDetection( void);

// detect falling edge from the beacon detector, and save the falling time

//**************************************************************************************************

void interrupt 11 BeaconDutyCheck_FallingEdgeDetection( void){

          Record falling edge time of a beacon

          Set the flag for the falling edge

          Clear IC3 flag

}

 

//**************************************************************************************************

// Interrupt for Timer 4: void interrupt 12 BeaconDutyCheck_RisingEdgeDetection( void);

// detect rising edge from the beacon detector, and calculate the duty cycle if falling edge

// has been detected. Set the duty cycle detect flag if one of them has been detected

//**************************************************************************************************

void interrupt 12 BeaconDutyCheck_RisingEdgeDetection( void){

          Clear IC4 flag

If falling edge of a beacon signal has been detected,

                   Record rising edge time of a beacon

                   Compute the duty cycle of the beacon

Set BeaconFallingEdgeDetectionFlag = 0

If duty cycle is between the lower limit and the upper limit of one of DC 30, 50, 70, or 90,

                             Set the Duty cycle detect flag to be 1 according to the computed duty cycle

                   END If

          END If

}

 

//**************************************************************************************************

// Interrupt for Timer 7: void interrupt 15 TimeOverCheck(void) ;

// check whether the game is over by counting the overflow

// stop the game if 2 min. is over

//**************************************************************************************************

void interrupt 15 TimeOverCheck(void) {

          Clear OC7 flag

If the game has started and overflow has reached the limit (i.e. 2 min.)

Set timeoverFlag to be timeOver

Stop the robot

END

}

 

//**************************************************************************************************

// Interrupt for Timer overflow: void interrupt 16 TimerOverflow(void);

// clear TOF flag, and increment overFlow count

//**************************************************************************************************

void interrupt 16 TimerOverflow(void){

          Clear over flow flag

          Increment overflow

}

 

//**************************************************************************************************

// Interrupt for SPI : void interrupt _Vec_SPI ControlMotors(void) ;

// dummy interrupt ; read data from the slave

//**************************************************************************************************

void interrupt _Vec_SPI ControlMotors(void) {

Read data from the slave

}

 

 

 

 

HOME            BACK             TOP

 

 

Source Code

 

 

#include <me218_c32.h>

#include <stdio.h>

#include "S12Vec.h"

#include <ADS12.h>

 

 

/***** MODULE DEFINITIONS *****/

 

#define BeaconFrequency    1250  //Hz

#define TimerFrequency     1500  //kHz

#define BeaconSignalCycle  1200 // tic

 

#define moveStr   102

#define turnCW    103

#define turnCCW   104

#define moveCW    105

#define moveCCW   106

#define stop      107

#define moveBack  108

                                                                                                             

#define TapeSensor2 2

#define TapeSensor3 3

#define TapeSensor4 4

#define TapeSensor5 5

 

#define wait      0

#define start     1

#define timeOver  2

 

#define black 0

#define green 1

#define red               2

#define blank 3

 

#define DLMotor1 BIT1HI

#define DLMotor2 BIT0HI

 

#define A 0

#define B 1

 

#define Dispenser 0

#define Goal1 1

#define Goal2 2

#define Goal3 3

 

/***** MODULE VARIABLES *****/

 

static unsigned int green_LowerLimit= 350;

static unsigned int green_UpperLimit= 510;

static unsigned int red_LowerLimit=    200;

static unsigned int red_UpperLimit=    250;

static unsigned int black_LowerLimit= 510;

static unsigned int black_UpperLimit= 1000;

 

static unsigned int BeaconRisingEdgeTime;

static unsigned int BeaconFallingEdgeTime;

static unsigned int BeaconLowTimeDuration;

static unsigned int BeaconDuty = 0;

 

static          int BeaconFallingEdgeDetectionFlag = 0;

 

static          int Duty90DetectFlag = 0;

static          int Duty70DetectFlag = 0;

static          int Duty50DetectFlag = 0;

static          int Duty30DetectFlag = 0;

 

static unsigned char Duty90_UpperLimit=  95 ;

static unsigned char Duty90_LowerLimit=     80       ;

 

static unsigned char Duty70_UpperLimit=  80 ;

static unsigned char Duty70_LowerLimit=     55       ;

 

static unsigned char Duty50_UpperLimit=     50 ;

static unsigned char Duty50_LowerLimit=     42 ;

 

static unsigned char Duty30_UpperLimit=     32 ;

static unsigned char Duty30_LowerLimit=     30 ;

 

static unsigned long startTime;

static unsigned long overFlow = 0;

static unsigned long gameDuration = 120000 * TimerFrequency;

static unsigned long gameOverTime;

static unsigned long overFlowLimit;

 

static unsigned char startFlag = wait;

static unsigned char timeoverFlag = wait;

 

static unsigned char numBallsToLoad = 10;

 

static unsigned char side = B;

static unsigned char numBallDispensed = 0;

 

static unsigned char color;

 

 

 

/***** MODULE FUNCTIONS *****/

 

void FindBallDispenser(void);

void FollowTapeTo(int loc);

void RequestBalls(void);

void FindGoal3(void);

void ReleaseBalls(void);                            

void Initialize(void) ;

void InitSPI(void);

void InitTimer(void) ;

void InitMotor(void) ;

unsigned char ReadColor(unsigned char sensor);

void StartTimer(void);

void Wait(unsigned long timeMS);

void Release(void);

                                                                                                                                                                                                                                                                                                             

/***** MAIN FUNCTION *****/

 

void main(void) {

  int flag;

  Initialize();

 

  /* wait for the signal from an electronic flash to start moving */

  while (startFlag == wait);

 

  /* start the timer to count 2 min. */

  StartTimer();

 

 

  /* play the game until 2 min. time is over */

  while (timeoverFlag != timeOver) {

 

    FindBallDispenser();

    FollowTapeTo(Dispenser);

    RequestBalls();

    FindGoal3();

    FollowTapeTo(Goal3);

    ReleaseBalls();  

  }        

 

  printf("end of game \n\r");                     

  flag = SPISR;

  SPIDR = stop;

 }

 

 

/***** MODULE FUNCTION IMPLEMENTATION *****/

 

 

//**************************************************************************************************

// Function : void Initialize(void);

// Initialize timer, SPI, and motor

//**************************************************************************************************

void Initialize(void) {

            InitTimer();

            EnableInterrupts;

            InitSPI();

            ADS12_Init("OAAAAAAA");

            InitMotor();

           

}

 

//**************************************************************************************************

// Function : void InitTimer(void);

// initialize timer sub-system

//**************************************************************************************************

void InitTimer(void) {

  TSCR1 = _S12_TEN;  // turn the timer system on

  TSCR2 = _S12_PR2;  // set pre-scale to /16 = 1.5MHz 

 

  // enable local interrupt for Timer 0, 3, 4, and 7

  TIE |= (_S12_C0I | _S12_C3I| _S12_C4I| _S12_C7I) ;

  

  // set cap/comp 0, 3, and 4 to input capture

  TIOS &= ~( _S12_IOS0 | _S12_IOS3| _S12_IOS4);

  // set cap/comp 7 to output compare

  TIOS |=  _S12_IOS7;

 

  TCTL1 &= ~(_S12_OL7 | _S12_OM7);

  TFLG1 = _S12_C7F;  

 

  TCTL4 &= ~(_S12_EDG0A);

  TCTL4 |= _S12_EDG0B; // set up IC0 to capture falling edge only

  TCTL4 &= ~(_S12_EDG3A);

  TCTL4 |= _S12_EDG3B; // set up IC3 to capture falling edge only

  TCTL3 &= ~(_S12_EDG4B);

  TCTL3 |= _S12_EDG4A; // set up IC4 to capture rising edge only

}

 

//**************************************************************************************************

// Function : void InitSPI(void);

// initialize SPI

//**************************************************************************************************

void InitSPI(void) {

            SPICR1 |= _S12_SPE;       /* SPI enable */

            SPICR1 |= _S12_MSTR;   /* Master mode */

            SPICR1 |= (_S12_CPOL | _S12_CPHA);           /* clock polarity and phase - mode 3 */

           

            /* Bit rate = 24 MHz / {(0+1)*2^(7+1)} = 93.75 kHz */

            SPIBR |= (_S12_SPR0 | _S12_SPR1 | _S12_SPR2);             /* SPR = 7 */

 

            /* ss control */

            SPICR1 |= _S12_SSOE;

            SPICR2 |= _S12_MODFEN;

 

             /* enable SPI transmit interrupt */

             SPICR1 |= _S12_SPIE;

}

 

//**************************************************************************************************

// Function : void InitMotor(void);

// initialize ball release motor

//**************************************************************************************************

void InitMotor(void) {

  DDRM |= (DLMotor1|DLMotor2);

  PTM &= ~DLMotor1;       

  PTM &= ~DLMotor2;       

 

}

 

//**************************************************************************************************

// Function : void StartTimer(void);

// start the timer when the game starts

//**************************************************************************************************

void StartTimer(void) {

  startTime = TCNT;

  //Clear over flow flag

  TFLG2 = _S12_TOF;

  // Enable overflow interrupt

            TSCR2 |= _S12_TOI;

  // Calculate game over time in int

  gameOverTime = (startTime + gameDuration)%65536;

  TC7 = gameOverTime;

  // Calculate overflow limit

            overFlowLimit =(startTime + gameDuration)/65536;

  // overFlowLimit = 2746;

 

  // Set current overflow to be zero

            overFlow = 0;

  // Set timeoverFlag to be waiting (i.e. not over)

  timeoverFlag = wait;

}

 

//**************************************************************************************************

// Function :  void FindBallDispenser( void);

// Find the ball dispenser (DC50), move straight, stop at the black tape

//**************************************************************************************************

void FindBallDispenser( void){

 

  int flag, count = 0;

  static int function_count = 1;

 

   // Make initial turn in CW to search for ball dispenser (DC50)

  flag = SPISR;

  if (side == A) {

    SPIDR = turnCCW;

  } else if (side == B) {

    SPIDR = turnCW;

  }

 

  if (function_count >1) {

    Wait(1000);

  }

 

  /* clear flags */

  Duty50DetectFlag = 0;

  Duty70DetectFlag = 0;

 

  // find ball dispenser and go straight after finding

  while(1){

 

      if (function_count >1) {

        Duty70DetectFlag = 1;

      }

      // Detect DC 70 first

      if (Duty70DetectFlag == 1) {

          flag = SPISR;

          if (side == A) {

              SPIDR = turnCCW;

          } else if (side == B) {

              SPIDR = turnCW;

          }

         

          Wait(300);

          Duty50DetectFlag = 0;

         

          while(1) {

 

            // If duty cycle 50 has been detected

            if( Duty50DetectFlag == 1) {

                flag = SPISR;

                SPIDR = stop;

                printf("stop");

 

                if (function_count>1) {

                 

                    flag = SPISR;

                    if (side == A) {

                      SPIDR = turnCCW;

                    } else if (side == B) {

                      SPIDR = turnCW;

                    }

                    Wait(150);

                }

                 

            // Move straight

            flag = SPISR;

            SPIDR = moveStr;

            Wait(2500);

           

            break;

            }

          }

 

          break;

      }

  }

    function_count++;

}

 

 

//**************************************************************************************************

// Function :  void FollowTapeTo(int loc);

// turn, track tape, stop at the end of the tape

//**************************************************************************************************

void FollowTapeTo(int loc){

              int flag;

                        int kp = 50;

                        int kd = 4;     

                        int a_num = 60;

                        int a_den = 100;

                        int b_num = 40;

                        int b_den = 100;

                        int dt=1;

                        int aL, aR, err, wc =0;

                        signed char mLc, mRc;

                        int err_dot_old , err_old, err_dot = 0;

                        int vc = 15;

                        unsigned char Lsen = 2;

                        unsigned char Rsen = 3;

 

                                                           

            if (loc == Dispenser) {

              // if going to dispenser, follow black tape

      color = black;

      numBallDispensed++;

 

 

            // if going to dispenser 1st time in the game

             if (numBallDispensed == 1) {

        // move straight until the robot meets the tape

        while ( (ReadColor(Lsen) != color) && (ReadColor(Rsen) != color));

 

        // If Left tape sensor sees the tape first

        if (  (ReadColor(Lsen) == color )) {

          // Robot is on A side

          side = A;

          Wait(750);

         

         // Turn CW for 350 ms

          flag = SPISR;

          SPIDR = turnCW;

          Wait(350);

         

          // Move straight

          flag = SPISR;

          SPIDR = moveStr;

 

        } else {

          // Robot is on B side

          side = B;

          Wait(750);

         

// Turn CCW for 350 ms

flag = SPISR;

           SPIDR = turnCCW;

           Wait(350);

         

                        // Move straight

flag = SPISR;

           SPIDR = moveStr;

        }

 

        Wait(2000);

   }

 

            // move forward until robot hits the tape again

            while ( (ReadColor(Lsen) != color) && (ReadColor(Rsen) != color));

     

            // move forward so that both sensors can see the part of tape

      if (  (ReadColor(Lsen) == color )) {

        while(ReadColor(Lsen) == color);

        while(ReadColor(Rsen) != color);

      } else {

        while(ReadColor(Rsen) == color);

        while(ReadColor(Lsen) != color);

      }

 

      // make a turn to look at the dispenser

      if (numBallDispensed == 1) {

                          flag = SPISR;

        if (side == A) {

          SPIDR = turnCCW;

        } else if (side == B) {

          SPIDR = turnCW;

        }                                      

      } else {

                          flag = SPISR;

        if (side == A) {

          SPIDR = turnCW;

        } else if (side == B) {

          SPIDR = turnCCW;

        }                                      

      }    

            Wait(500);

            while((ReadColor(Lsen) != color) && (ReadColor(Rsen) != color));                     

                                     

 

// if going from dispenser to goal3

            } else if (loc == Goal3) {

              // set the tape color to follow to be green

    color = green;

   

    // move forward until the robot meets the tape

    while ( (ReadColor(Lsen) != color) && (ReadColor(Rsen) != color));

 

    // move forward so that both sensors can see the part of tape

    if (  (ReadColor(Lsen) == color )) {

      while(ReadColor(Lsen) == color);

    } else {

      while(ReadColor(Rsen) == color);

    }

 

    // make a turn to align with the tape

    flag = SPISR;

    if (side == A) {

      SPIDR = turnCW;

    } else if (side == B) {

      SPIDR = turnCCW;

    }                                          

 

            Wait(500);

            while((ReadColor(Lsen) != color) && (ReadColor(Rsen) != color));                     

            }

 

    green_LowerLimit = 350; 

           

    /* MoveForward along the tape until two sensors further apart hit the tape */

    while ( (ReadColor(TapeSensor4) != color) || (ReadColor(TapeSensor5) != color)){

   

    /* PD control of the angular velocity of two wheels to track the tape */ 

    //Read Left and Right tape sensor values for the AD port

    aL = ADS12_ReadADPin(Lsen);

    aR = ADS12_ReadADPin(Rsen);

   

    // Compute error = Left sensor value - Right sensor value

    err = aL-aR;

    // Compute error_dot = a * error_dot_old  + (1-a) * error_dot_new

    //                                              = a * error_dot_old + (1-a) * (error - error_old) / dt

    err_dot = a_num*err_dot_old/a_den + b_num*(err-err_old)/b_den;

   

    // Calculate angular velocity wc = error*Kp + error_dot*Kd

    wc = err/kp + err_dot*kd;

    // Save error_old  and error_dot_old

    err_old = err;

    err_dot_old = err_dot;

   

    // Compute Left motor PWM (mLc) = forward velocity - wc

    mLc = vc - wc;

    // Compute Right motor PWM (mRc) = forward velocity + wc

    mRc = vc + wc;

   

    /* separate the range of mLc and mRc */

    // If the PWM's are larger than 50, set them to 50

    if (mLc > 50) mLc = 50;

    if (mRc > 50) mRc = 50;

    // If the PWM's are smaller than -50, set them to -50

    if (mLc < -50) mLc = -50;

    if (mRc < -50) mRc = -50;

   

    /* separate the range of mLc and mRc by adding and subtracting 51 */

    mLc -= 51;

    mRc += 51;

   

    /* Send the control values to slave */

    flag = SPISR;

    SPIDR = mLc;

   

    while((SPISR & _S12_SPTEF)==0);

   

    flag = SPISR;

    SPIDR = mRc;

   

    printf(" mLc = %d  mRc = %d  err = %d  err_dot = %d   wc = %d  \n\r", mLc, mRc, err, err_dot, wc);

  }

 

  green_LowerLimit = 400; 

 

  /* stop if two further apart tape sensors see tape */

  flag = SPISR;

  SPIDR = stop;

  printf(" STOP ");

}

 

//**************************************************************************************************

// Function : void RequestBalls (void) ;

// push dispenser

//**************************************************************************************************

void RequestBalls (void) {

              char i;

              int flag;

              static char request_count = 1;

             

     // request 5 balls

     for (i=1; i<=5; i++) {

      // Move straight to push

      flag = SPISR;

      SPIDR = moveStr;

      Wait(700);

 

      // Wait for 1 sec

      flag = SPISR;

      SPIDR = stop;

      Wait(1100);

     

      // Move backward

      flag = SPISR;

      SPIDR = moveBack;

     

      Wait(300);

    }

 

    // Request 5 more balls only at the first request

    if (request_count ==1) {

     

      // Wait for 10 sec.

      flag = SPISR;

      SPIDR = stop;

      Wait(10000);

     

      // request additional 5 balls

      for (i=1; i<=5; i++) {

        // Move straight to push

        flag = SPISR;

        SPIDR = moveStr;

        Wait(700);

 

        // Wait for 1 sec

        flag = SPISR;

        SPIDR = stop;

        Wait(1100);

 

        // Move backward

        flag = SPISR;

        SPIDR = moveBack;

       

        Wait(300);

     

      }

    }

 

    Wait(1500);

    numBallsToLoad = 10;

    request_count++;

}

 

 

//**************************************************************************************************

// Function : void FindGoal3(void);

// turn to search goal3 (DC90), move straight, stop at the tape

//**************************************************************************************************

   

void FindGoal3(void) {

  int flag;

  flag = SPISR;

 

  // turn to scan DC

  if (side == A) {

    SPIDR = turnCCW;

  } else if (side == B) {

    SPIDR = turnCW;

  }

  /* clear flags */

  Duty90DetectFlag = 0;

  BeaconDuty = 0;

 

  // Search until DC90 is detected

  while((Duty90DetectFlag == 0) );

 

  if (side == A) {

    SPIDR = turnCW;

  } else if (side == B) {

    SPIDR = turnCCW;

  }        

  Wait(200);

 

  // Move straight

  flag = SPISR;

  SPIDR = moveStr;

 

  Wait(2000);

}

 

//**************************************************************************************************

// Function : void ReleaseBalls(void);

// turn to look at goal3, release balls

//**************************************************************************************************

 

void ReleaseBalls(void) {

  int flag;

  flag = SPISR;

 

  // turn to align with goal 3

  if (side == A) {

    SPIDR = turnCCW;

  } else if (side == B) {

    SPIDR = turnCW;

  }

 

  /* clear flags */

  Duty90DetectFlag = 0;

  BeaconDuty = 0;

 

  // move forward when goal 3 is detected

  while((Duty90DetectFlag == 0) );

  flag = SPISR;

  SPIDR = moveStr;

 

  Wait(1500);

 

  Release();

 

  flag = SPISR;

  SPIDR = moveBack;

 

  Wait(2000);

 

}

 

//**************************************************************************************************

// Function : void Release(void);

// Release the balls

//**************************************************************************************************

void Release(void) {

  int i;

 

  // open the door twice to release balls 

  for (i = 1; i<=2; i++) {

    DDRM |= (DLMotor1|DLMotor2);

    PTM |= DLMotor1;

    PTM &= ~DLMotor2;

    Wait(1000);

   

    PTM |= DLMotor2;

    PTM &= ~DLMotor1;

    Wait(500); 

  }

 

  // lower motor bits to prevent the circuit from burning

  PTM &= ~DLMotor1;       

  PTM &= ~DLMotor2;       

}

 

//**************************************************************************************************

// Function : void Wait(unsigned long timeMS);

// wait for timeMS(ms)

//**************************************************************************************************

void Wait(unsigned long timeMS) {

  unsigned long waitStartTime = TCNT;

  unsigned long waitEndTime = waitStartTime +  timeMS * TimerFrequency;

  unsigned long startOverFlow = overFlow;

  unsigned long currTime = waitStartTime;

  while (currTime <= waitEndTime) {

    currTime = (overFlow-startOverFlow)*65536 + TCNT;

  }

}

 

//**************************************************************************************************

// Function : unsigned char ReadColor(unsigned char sensor) ;

// returns which color the tape sensor #(sensor) is seeing

//**************************************************************************************************

unsigned char ReadColor(unsigned char sensor) {

  unsigned int sensor_color = ADS12_ReadADPin(sensor);

  if      ( (sensor_color > black_LowerLimit) && (sensor_color < black_UpperLimit) )

    return black;

  else if ( (sensor_color > green_LowerLimit) && (sensor_color < green_UpperLimit) )

    return green;

  else if ( (sensor_color > red_LowerLimit) && (sensor_color < red_UpperLimit) )

    return red;

  else return blank;

}

 

//**************************************************************************************************

// Interrupt for Timer 0: void interrupt 8 FlashDetection( void);

// detect flash at the beginning of game

//**************************************************************************************************

void interrupt 8 FlashDetection( void){

  startFlag = start; // set the flag to start moving

  TFLG1 = _S12_C0F; // clear IC0 flag  

}

 

//**************************************************************************************************

// Interrupt for Timer 3: void interrupt 11 BeaconDutyCheck_FallingEdgeDetection( void);

// detect falling edge from the beacon detector, and save the falling time

//**************************************************************************************************

void interrupt 11 BeaconDutyCheck_FallingEdgeDetection( void){

  BeaconFallingEdgeTime = TC3;        // Record the falling edge time of a beacon

  BeaconFallingEdgeDetectionFlag = 1; // Set the flag for the falling edge

  TFLG1 = _S12_C3F;                   // clear IC3 flag 

}

 

//**************************************************************************************************

// Interrupt for Timer 4: void interrupt 12 BeaconDutyCheck_RisingEdgeDetection( void);

// detect rising edge from the beacon detector, and calculate the duty cycle if falling edge

// has been detected. Set the duty cycle detect flag if one of them has been detected

//**************************************************************************************************

void interrupt 12 BeaconDutyCheck_RisingEdgeDetection( void){

    TFLG1 = _S12_C4F; // clear IC4 flag

 

  // If falling edge of a beacon signal has been detected

  if( BeaconFallingEdgeDetectionFlag == 1){

   

    BeaconRisingEdgeTime = TC4;                    // Record  rising edge time of a beacon

    BeaconLowTimeDuration = (TC4 - BeaconFallingEdgeTime);

    BeaconDuty = ( BeaconLowTimeDuration ) / (BeaconSignalCycle / 100);     // Compute the duty cycle of the beacon

   

    BeaconFallingEdgeDetectionFlag = 0;

   

   

    // set the flag according to the computed duty cycle of the beacon

   if     ( (BeaconDuty > Duty90_LowerLimit) && (BeaconDuty < Duty90_UpperLimit) )

      Duty90DetectFlag = 1;

    else if     ( (BeaconDuty > Duty70_LowerLimit) && (BeaconDuty < Duty70_UpperLimit) )

      Duty70DetectFlag = 1;                                                                                                                         

    else if( (BeaconDuty > Duty50_LowerLimit) && (BeaconDuty < Duty50_UpperLimit) )

      Duty50DetectFlag = 1;

    else if( (BeaconDuty > Duty30_LowerLimit) && (BeaconDuty < Duty30_UpperLimit) )

      Duty30DetectFlag = 1;      

  }

}                    

 

//**************************************************************************************************

// Interrupt for Timer 7: void interrupt 15 TimeOverCheck(void) ;

// check whether the game is over by counting the overflow

// stop the game if 2 min. is over

//**************************************************************************************************

void interrupt 15 TimeOverCheck(void) {

  unsigned char flag;

  TFLG1 = _S12_C7F;

  if ((overFlow == overFlowLimit) && (startFlag == start)) {

    timeoverFlag = timeOver;

    flag = SPISR;

    SPIDR = stop;

    while(1);

  }

}

 

//**************************************************************************************************

// Interrupt for Timer overflow: void interrupt 16 TimerOverflow(void);

// clear TOF flag, and increment overFlow count

//**************************************************************************************************

void interrupt 16 TimerOverflow(void) {

  TFLG2 = _S12_TOF;

  overFlow++;

}

 

//**************************************************************************************************

// Interrupt for SPI : void interrupt _Vec_SPI ControlMotors(void) ;

// dummy interrupt ; read data from the slave

//**************************************************************************************************

void interrupt _Vec_SPI ControlMotors(void) {

            unsigned char order, flag;

           

            // Read data from the slave

            flag = SPISR;

            order = SPIDR;

}

 

 

HOME            BACK             TOP