MasterSM (Pseudo code)
Global variables-
MasterState_t CurrentState
Boolean activeShips[40]
Int enemyShip
Int align, color
Int ammo
Int emitterActive
Int twomin
Int shipJustShot
INITIALIZATION FUNCTIONS
InitMasterSM
Set MyPriority to Priority that was passed in
Call SPIInit, TimerInit, PWMInit, ServoInitCh1
Set DDRS bit 7 to high
Set DDRT bit 1 to high
Set DDRU bit 6 and bit 7 to high
Set DDRP bit 1 to high
Init AD pins with “OAAAAAAI”
Set enemyShip to 0 and ammo to 5
Set servo angles to initial servo angles
Set emitter off
Stop motors with Stop()
Set shooter motor to PWM 0
Turn off LED (green/red to indicate game status)
StartMasterSM with ES_ENTRY
SPIInit
Set SPIBR to highest (all bits to high that deal with baud rate)
Set SPICR1 bits MSTR, CPOL, CPHA all high, and SSOE low
Set SPICR2 bits MODFEN, SPC0 low
Set DDRS slave select high
Enable with SPE bit on SPICR1
PWMInit
Set PWMPRCLK to a prescaler of 64
Set PWMSCLA and B to 8
Set all PWMs with PWME bits high
Set MODRR pins high for all channels
Set PCLK pins high for all channels
Set PPOL pins high for all channels
PWMPER to 250 for all channels
PWMDTY to 0 for all channels
TimerInit
Set enable on TSCR1 and put the multiplier to 64 on TSCR2
Set timer 4 to IR detection mode – Set EDG4A on TCTL3 for rising edges, disable interrupts to start, and clear the flag
Set timer 5 to output compare
Clear bits OL5 and OM5 for manual control
Set TC5 to TCNT + 10ms
Clear TC5 flag
Enable Interrupts
ServoInitCh1
Set enable on TSCR1, and rate multiplier to 8 for 3MHz
Set rise on compare for all channels (OLx and OMx high)
Set toggle on overflow (TOVx)
Set TCx to 0xFFFF – 4500 to start, which gives a servo neutral position of 1.5 ms pulse width
INTERRUPT FUNCTION
Interrupt function for IR detection
Static long lastEdge and secondLastEdge
Clear the interrupt flag and get the time, TC4 into a variable
Calculate the periods of current time – last edge and current time – second last edge in uS
If either period is within 13.8 and 14.2 ms and color is 1 (red) (or period is around 20ms and color is 2 (blue))
If align is 1 (align was requested and found)
Disable interrupts by clearing C4I on TIM0_TIE
Post Aligned to MasterSM
Set align to 0
Else if align is not 0 or 1
Decrement align
If the period was not within the ranges, set align to 2
Set secondLastEdge to lastEdge
Set lastEdge to the current time variable
Other Functions
StartMasterSM
Set CurrentState to WaitingForFAC
Run MasterSM with ES_ENTRY
QueryMasterSM
Return CurrentState
RunMasterSM
State Machine- For all of these states, run its corresponding During function
State ShootingTargets
If current event is OutOfBalls
Switch states to MovingToTape
If current event is BallFired
updateFAC
if ammo is a pre-determined amount for shooting the power station
Rotate to Exact for 270 for red, 90 for blue
StartShootPowerSM with ES_ENTRY
Else if ammo is not 0
StartShootTargetSM with ES_ENTRY
State MovingToFire
If current event is MovementFinished
Switch states to ShootingTargets
State MoveOutOfCamo
If current event is botfound
Switch states to MovingToFire
State MovingToTape
If current event is MovementFinished
Switch states to PreparingToLoad
State PreparingToLoad
If current event is BumpSwitchHit
Set Timer 4 to 300ms
If Timer 4 timed out
Switch states to Loading
State Loading
If current event is LoadingFinished
Switch states to MoveOutOfCamo
State ShootingPower
If current event is OutOfBalls
Switch states to MovingToTape
If current event is BallFired
updateFAC
If ammo is not 0, StartShootTargetSM with ES_ENTRY
State WaitingForFAC (for starting off)
If current event is UpdateFinish and color is not 0
Switch states to WaitForStart
Start Timer 7 with 100 ms
Else if current event is UpdateFinish and color is 0
updateFAC
State WaitForStart
If current event is GameStart
Set twomin to 0, set duty on shooting motor to 20
Turn on LED, and switch states to ShootingTargets
State Finished
Don’t do anything, because we’re finished.
DuringMaster
If event is ES_ENTRY
updateFAC()
if event is GameEnd
Switch states to Finished
Stop all motors, turn off LED and set the emitter off
Run all the lower level SMs with GameEnd
If timer 4 or timer 1 timed out
Stop driving motors
RunMovementSM, ShootTargetSM, PowerSM with the event
If timer 7 timed out
StartCommSM with ENTRY and 0x3F as message for status update
If twomin >= 240, post GameEnd to MasterSM
If twomin < -1 (Game hasn’t started yet), set timer 7 on 100ms
If neither are true, set timer 7 to 500ms
If event is UpdateFinish
updateActive()
if color is 0, check our bot’s coordinates and if they aren’t 0, set our color to blue or red
If event is ES_NEW_KEY
Run processKeyboard with the EventParam
If event is OC1Exp
Run RespondToOC1
If the event is none of the above,
Run all the lower level SMs with the event
DuringShootingTargets
Set ReturnEvent equal to Event
if EventType is ES_ENTRY
call StartShootTargetSM(currEvent)
return(ReturnEvent)
DuringMovingToFire
Set ReturnEvent equal to Event
if EventType is ES_ENTRY
call SetDuty(15,1) // start launcger motor while moving
if color is equal to 1
call StartMovementSM(Event, 80, 127, 270, 4, 0);
else if color is equal to 2
call StartMovementSM(Event, 176, 127, 90, 4, 0);
else if (EventType is ES_EXIT)
call resetCurrentSector
else
return(ReturnEvent)
DuringMovingToTape
Set ReturnEvent equal to Event
if EventType is ES_ENTRY
call SetDuty(0,1) // turn launcher motor off while moving
if color is equal to 1
call StartMovementSM(Event, 51, 127, 270, 2, 1);
else if color is equal to 2
call StartMovementSM(Event, 205, 127, 90, 2, 1);
return(ReturnEvent)
DuringMoveOutOfCamo
Set ReturnEvent equal to Event
if EventType is ES_ENTRY
call requestFind
call DriveForward
call updateFAC
call ES_Timer_SetTimer, Timer 4, 500 ms
call ES_Timer_StartTimer, Timer 4
else if (EventType is ES_EXIT)
call Stop // stop movement
else if Event.EventType equalts ES_TIMEOUT and Event.EventParam equals 4
call updateFAC
call DriveForward
call ES_Timer_SetTimer, Timer 4, 500 ms
call ES_Timer_StartTimer, Timer 4
return(ReturnEvent)
DuringPreparingToLoad
Set ReturnEvent equal to Event
if EventType is ES_ENTRY
call requestBump
call DriveReverse
else if (EventType is ES_EXIT)
call Stop
else
return(ReturnEvent)
DuringLoading
Set ReturnEvent equal to Event
if EventType is ES_ENTRY
call StartBallSM
return(ReturnEvent)
DuringEnding
Set ReturnEvent equal to Event
return(ReturnEvent)
updateActive
int i;
if enemyShip is 0 // enemy ship has not yet been found
for i = 3 to 20
if queryActive(i) is true and i is not 15
enemyShip is i // actually enemy Bot
for i = 20 to 40
if queryActive(i) is true
set activeShips[i] to true
else
set activeShips[i] to false
requestAlign
set align equal to 2
turn interrupt on (for IR detection)
int getColor
return color
int getNextTarget
int i
int NumberOurShips
int NumberEnemyShips
if color is 2
set NumberOurShips equal to queryBlueShips
set NumberEnemyShips equal to queryRedShips
else if color is 1
set NumberOurShips equal to queryRedShips
set NumberEnemyShips equal to queryBlueShips
if NumberEnemyShips + 3 is less than NumberOurShips or NumberEnemyShips equals 0, return enemyShip
if color is 1
loop through all sectors in order 1,4,2,5,3,6
loop through all ships for i equal 30 to 40
if activeShips[i] is TRUE and doesn't equal shipJustShot
return i
if color is 2
loop through all sectors in order 1,4,2,5,3,6
loop through all ships for i equal 20 to 30
if activeShips[i] is TRUE and doesn't equal shipJustShot
return i
setLastShip
set shipJustShot equal to num
if color is 1
if queryBlueShips is less than 1
set shipJustShot equal to 0
if color is 2
if queryRedShips is less than 1
set shipJustShot equal to 0
CloakBot
call Servo_SetAngle(FiducialServo,0)
call ES_Timer_SetTimer, Timer 3, 1000 ms
call ES_Timer_StartTimer, Timer 3
UncloakBot
call Servo_SetAngle(FiducialServo, 30)
changeAmmo
add one to ammo
if ammo is 0
set currEvent.EventType to OutOfBalls
PostMasterSM(currEvent)
setEmitter(int onoff)
if onoff is 1
set emitterActive to 1
clear flag
add period to output capture time
else if onoff is 0
set emitterActive to 0
turn emitter output (T1) low
RespondToOC1
clear flag
if emitterActive is 1
if PPT is high
set PTT low
add 30 ms to period for low time
else
set PTT high
add 10 ms period for high time
LEDon
turn P1 high
LEDoff
turn P1 low
MasterState_t CurrentState
Boolean activeShips[40]
Int enemyShip
Int align, color
Int ammo
Int emitterActive
Int twomin
Int shipJustShot
INITIALIZATION FUNCTIONS
InitMasterSM
Set MyPriority to Priority that was passed in
Call SPIInit, TimerInit, PWMInit, ServoInitCh1
Set DDRS bit 7 to high
Set DDRT bit 1 to high
Set DDRU bit 6 and bit 7 to high
Set DDRP bit 1 to high
Init AD pins with “OAAAAAAI”
Set enemyShip to 0 and ammo to 5
Set servo angles to initial servo angles
Set emitter off
Stop motors with Stop()
Set shooter motor to PWM 0
Turn off LED (green/red to indicate game status)
StartMasterSM with ES_ENTRY
SPIInit
Set SPIBR to highest (all bits to high that deal with baud rate)
Set SPICR1 bits MSTR, CPOL, CPHA all high, and SSOE low
Set SPICR2 bits MODFEN, SPC0 low
Set DDRS slave select high
Enable with SPE bit on SPICR1
PWMInit
Set PWMPRCLK to a prescaler of 64
Set PWMSCLA and B to 8
Set all PWMs with PWME bits high
Set MODRR pins high for all channels
Set PCLK pins high for all channels
Set PPOL pins high for all channels
PWMPER to 250 for all channels
PWMDTY to 0 for all channels
TimerInit
Set enable on TSCR1 and put the multiplier to 64 on TSCR2
Set timer 4 to IR detection mode – Set EDG4A on TCTL3 for rising edges, disable interrupts to start, and clear the flag
Set timer 5 to output compare
Clear bits OL5 and OM5 for manual control
Set TC5 to TCNT + 10ms
Clear TC5 flag
Enable Interrupts
ServoInitCh1
Set enable on TSCR1, and rate multiplier to 8 for 3MHz
Set rise on compare for all channels (OLx and OMx high)
Set toggle on overflow (TOVx)
Set TCx to 0xFFFF – 4500 to start, which gives a servo neutral position of 1.5 ms pulse width
INTERRUPT FUNCTION
Interrupt function for IR detection
Static long lastEdge and secondLastEdge
Clear the interrupt flag and get the time, TC4 into a variable
Calculate the periods of current time – last edge and current time – second last edge in uS
If either period is within 13.8 and 14.2 ms and color is 1 (red) (or period is around 20ms and color is 2 (blue))
If align is 1 (align was requested and found)
Disable interrupts by clearing C4I on TIM0_TIE
Post Aligned to MasterSM
Set align to 0
Else if align is not 0 or 1
Decrement align
If the period was not within the ranges, set align to 2
Set secondLastEdge to lastEdge
Set lastEdge to the current time variable
Other Functions
StartMasterSM
Set CurrentState to WaitingForFAC
Run MasterSM with ES_ENTRY
QueryMasterSM
Return CurrentState
RunMasterSM
State Machine- For all of these states, run its corresponding During function
State ShootingTargets
If current event is OutOfBalls
Switch states to MovingToTape
If current event is BallFired
updateFAC
if ammo is a pre-determined amount for shooting the power station
Rotate to Exact for 270 for red, 90 for blue
StartShootPowerSM with ES_ENTRY
Else if ammo is not 0
StartShootTargetSM with ES_ENTRY
State MovingToFire
If current event is MovementFinished
Switch states to ShootingTargets
State MoveOutOfCamo
If current event is botfound
Switch states to MovingToFire
State MovingToTape
If current event is MovementFinished
Switch states to PreparingToLoad
State PreparingToLoad
If current event is BumpSwitchHit
Set Timer 4 to 300ms
If Timer 4 timed out
Switch states to Loading
State Loading
If current event is LoadingFinished
Switch states to MoveOutOfCamo
State ShootingPower
If current event is OutOfBalls
Switch states to MovingToTape
If current event is BallFired
updateFAC
If ammo is not 0, StartShootTargetSM with ES_ENTRY
State WaitingForFAC (for starting off)
If current event is UpdateFinish and color is not 0
Switch states to WaitForStart
Start Timer 7 with 100 ms
Else if current event is UpdateFinish and color is 0
updateFAC
State WaitForStart
If current event is GameStart
Set twomin to 0, set duty on shooting motor to 20
Turn on LED, and switch states to ShootingTargets
State Finished
Don’t do anything, because we’re finished.
DuringMaster
If event is ES_ENTRY
updateFAC()
if event is GameEnd
Switch states to Finished
Stop all motors, turn off LED and set the emitter off
Run all the lower level SMs with GameEnd
If timer 4 or timer 1 timed out
Stop driving motors
RunMovementSM, ShootTargetSM, PowerSM with the event
If timer 7 timed out
StartCommSM with ENTRY and 0x3F as message for status update
If twomin >= 240, post GameEnd to MasterSM
If twomin < -1 (Game hasn’t started yet), set timer 7 on 100ms
If neither are true, set timer 7 to 500ms
If event is UpdateFinish
updateActive()
if color is 0, check our bot’s coordinates and if they aren’t 0, set our color to blue or red
If event is ES_NEW_KEY
Run processKeyboard with the EventParam
If event is OC1Exp
Run RespondToOC1
If the event is none of the above,
Run all the lower level SMs with the event
DuringShootingTargets
Set ReturnEvent equal to Event
if EventType is ES_ENTRY
call StartShootTargetSM(currEvent)
return(ReturnEvent)
DuringMovingToFire
Set ReturnEvent equal to Event
if EventType is ES_ENTRY
call SetDuty(15,1) // start launcger motor while moving
if color is equal to 1
call StartMovementSM(Event, 80, 127, 270, 4, 0);
else if color is equal to 2
call StartMovementSM(Event, 176, 127, 90, 4, 0);
else if (EventType is ES_EXIT)
call resetCurrentSector
else
return(ReturnEvent)
DuringMovingToTape
Set ReturnEvent equal to Event
if EventType is ES_ENTRY
call SetDuty(0,1) // turn launcher motor off while moving
if color is equal to 1
call StartMovementSM(Event, 51, 127, 270, 2, 1);
else if color is equal to 2
call StartMovementSM(Event, 205, 127, 90, 2, 1);
return(ReturnEvent)
DuringMoveOutOfCamo
Set ReturnEvent equal to Event
if EventType is ES_ENTRY
call requestFind
call DriveForward
call updateFAC
call ES_Timer_SetTimer, Timer 4, 500 ms
call ES_Timer_StartTimer, Timer 4
else if (EventType is ES_EXIT)
call Stop // stop movement
else if Event.EventType equalts ES_TIMEOUT and Event.EventParam equals 4
call updateFAC
call DriveForward
call ES_Timer_SetTimer, Timer 4, 500 ms
call ES_Timer_StartTimer, Timer 4
return(ReturnEvent)
DuringPreparingToLoad
Set ReturnEvent equal to Event
if EventType is ES_ENTRY
call requestBump
call DriveReverse
else if (EventType is ES_EXIT)
call Stop
else
return(ReturnEvent)
DuringLoading
Set ReturnEvent equal to Event
if EventType is ES_ENTRY
call StartBallSM
return(ReturnEvent)
DuringEnding
Set ReturnEvent equal to Event
return(ReturnEvent)
updateActive
int i;
if enemyShip is 0 // enemy ship has not yet been found
for i = 3 to 20
if queryActive(i) is true and i is not 15
enemyShip is i // actually enemy Bot
for i = 20 to 40
if queryActive(i) is true
set activeShips[i] to true
else
set activeShips[i] to false
requestAlign
set align equal to 2
turn interrupt on (for IR detection)
int getColor
return color
int getNextTarget
int i
int NumberOurShips
int NumberEnemyShips
if color is 2
set NumberOurShips equal to queryBlueShips
set NumberEnemyShips equal to queryRedShips
else if color is 1
set NumberOurShips equal to queryRedShips
set NumberEnemyShips equal to queryBlueShips
if NumberEnemyShips + 3 is less than NumberOurShips or NumberEnemyShips equals 0, return enemyShip
if color is 1
loop through all sectors in order 1,4,2,5,3,6
loop through all ships for i equal 30 to 40
if activeShips[i] is TRUE and doesn't equal shipJustShot
return i
if color is 2
loop through all sectors in order 1,4,2,5,3,6
loop through all ships for i equal 20 to 30
if activeShips[i] is TRUE and doesn't equal shipJustShot
return i
setLastShip
set shipJustShot equal to num
if color is 1
if queryBlueShips is less than 1
set shipJustShot equal to 0
if color is 2
if queryRedShips is less than 1
set shipJustShot equal to 0
CloakBot
call Servo_SetAngle(FiducialServo,0)
call ES_Timer_SetTimer, Timer 3, 1000 ms
call ES_Timer_StartTimer, Timer 3
UncloakBot
call Servo_SetAngle(FiducialServo, 30)
changeAmmo
add one to ammo
if ammo is 0
set currEvent.EventType to OutOfBalls
PostMasterSM(currEvent)
setEmitter(int onoff)
if onoff is 1
set emitterActive to 1
clear flag
add period to output capture time
else if onoff is 0
set emitterActive to 0
turn emitter output (T1) low
RespondToOC1
clear flag
if emitterActive is 1
if PPT is high
set PTT low
add 30 ms to period for low time
else
set PTT high
add 10 ms period for high time
LEDon
turn P1 high
LEDoff
turn P1 low