Sunteți pe pagina 1din 13

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

Module
TreeSM.c
Description
This is the state machine for the overall project that controls the
distribution
of services depending on events
Notes
History
When
Who
What/Why
-------------- ---------11/14/16
16:10 mwm
Created
****************************************************************************/
/*----------------------------- Include Files -----------------------------*/
/* include header files for this state machine as well as any machines at the
next lower level in the hierarchy that are sub-machines to this machine
*/
#include "ES_Configure.h"
#include "ES_Framework.h"
#include "TreeSM.h"
#include "TimingMotor.h"
#include "AudioBoard.h"
#include "BranchService.h"
#include "StartButton.h"
/*----------------------------- Module Defines ----------------------------*/
/*---------------------------- Module Functions ---------------------------*/
/* prototypes for private functions for this machine.They should be functions
relevant to the behavior of this state machine
*/
/*---------------------------- Module Variables ---------------------------*/
// everybody needs a state variable, you may need others as well.
// type of state variable should match htat of enum in header file
static TreeState_t CurrentState;
// with the introduction of Gen2, we need a module level Priority var as well
static uint8_t MyPriority;
static uint8_t GrowingBranch = 0;
/*------------------------------ Module Code ------------------------------*/
/****************************************************************************
Function
InitTreeSM
Parameters
uint8_t : the priority of this service
Returns
bool, false if error in initialization, true otherwise
Description
Saves away the priority, sets up the initial transition and does any
other required initialization for this state machine
Notes
Author
Matthew Miller, 11/14/16

****************************************************************************/
bool InitTreeSM ( uint8_t Priority )
{
ES_Event ThisEvent;

MyPriority = Priority;
// put us into the Initial PseudoState
CurrentState = InitTSM;
// post the initial transition event
ThisEvent.EventType = ES_INIT;
if (ES_PostToService( MyPriority, ThisEvent) == true)
{
return true;
}else
{
return false;
}

/****************************************************************************
Function
PostTreeSM
Parameters
EF_Event ThisEvent , the event to post to the queue
Returns
boolean False if the Enqueue operation failed, True otherwise
Description
Posts an event to this state machine's queue
Notes
Author
Matthew Miller, 11/14/16, 16:25
****************************************************************************/
bool PostTreeSM( ES_Event ThisEvent )
{
return ES_PostToService( MyPriority, ThisEvent);
}
/****************************************************************************
Function
RunTreeSM
Parameters
ES_Event : the event to process
Returns
ES_Event, ES_NO_EVENT if no error ES_ERROR otherwise
Description
add your description here
Notes
uses nested switch/case to implement the machine.
Author
Matthew Miller, 11/14/16, 16:31
****************************************************************************/
ES_Event RunTreeSM( ES_Event ThisEvent )
{
ES_Event ReturnEvent;
ES_Event PostEvent;
ReturnEvent.EventType = ES_NO_EVENT; // assume no errors

switch ( CurrentState )
{
case InitTSM :
// If current state is initial Psedudo State
if ( ThisEvent.EventType == ES_INIT )// only respond to
ES_Init
{
printf("\rEverything Initialized - Now Waiting for
Artist\n\r");
// Set CurrentState to WaitingForArtist
CurrentState = WaitingForArtist;
//Post Waiting event to this service
PostEvent.EventType = WAITING;
PostTreeSM(PostEvent);

}
break;
case WaitingForArtist :
// If current state is
WaitingForArtist State
{
if ( ThisEvent.EventType == WAITING) // If ThisEvent is
WAITING
{
//Post Waiting Event to Motor, Audio, and Start Button
services
PostEvent.EventType = WAITING;
PostTimingMotor(PostEvent);
PostAudioBoard(PostEvent);
PostStartButton(PostEvent);
}
if(ThisEvent.EventType == DONE_REPLAYING) // If ThisEvent is
DONE_REPLAYING
{
// Post WELCOME_REPLAY to Branch Service
PostEvent.EventType = WELCOME_REPLAY;
Post_BranchService(PostEvent);
}
BTN_START

if ( ThisEvent.EventType == BTN_START )// If ThisEvent is


{

//Set SEASON_TIMER for fraction of a second


ES_Timer_InitTimer(SEASON_TIMER, 50);
// Post RESET Event to branch and motor services
PostEvent.EventType = RESET;
Post_BranchService(PostEvent);
PostTimingMotor(PostEvent);
Post_BranchService(PostEvent);

}
if ( ThisEvent.EventType == ES_TIMEOUT && ThisEvent.EventParam
== SEASON_TIMER) // If ThisEvent is ES_TIMEOUT and timer is SEASON_TIMER
{
// Set CurrentState to Spring
CurrentState = Spring;
//Set SEASON_TIMER for SEASON_TIME
ES_Timer_InitTimer(SEASON_TIMER, SEASON_TIME);
//Post START Event to all services (Motors, Branch,
Audio, Start Button)

PostEvent.EventType = START;
PostTimingMotor(PostEvent);

PostStartButton(PostEvent);
PostAudioBoard(PostEvent);
Post_BranchService(PostEvent);

break;
case Spring : // If current state is Spring State
{
switch(ThisEvent.EventType)
{
case ES_TIMEOUT:
if(ThisEvent.EventParam == SEASON_TIMER) // If
ThisEvent is ES_TIMEOUT and timer is SEASON_TIMER
{
// Set CurrentState to Summer
CurrentState = Summer;
// Call ChangeSeasonTo function with

parameter SUMMER

ChangeSeasonTo(SUMMER);

}
break;

case BTN_WEATHER: // If ThisEvent is BTN_WEATHER


// Call HandleWeather function with parameter

SPRING

HandleWeather(SPRING);
break;
case PROX_NEAR: // If ThisEvent is PROX_NEAR
// Set CurrentState to Spring Growing
CurrentState = SpringGrowing;
// Call HandleProx function with parameter of
ThisEvent

HandleProx(ThisEvent);
break;
case ANALOG_CHANGE: // If ThisEvent is ANALOG_CHANGE
// Call HandleAnalog function with parameter

ThisEvent

HandleAnalog(ThisEvent);
break;
default:
break;
}

break;
case SpringGrowing :
State

// If current state is SpringGrowing

switch(ThisEvent.EventType)
{
case ES_TIMEOUT:
if(ThisEvent.EventParam == SEASON_TIMER) // If
ThisEvent Param is SEASON_TIMER
{
// Set CurrentState to SummerGrowing
CurrentState = SummerGrowing;
parameter SUMMER

// Call ChangeSeasonTo function with


ChangeSeasonTo(SUMMER);

}
else if(ThisEvent.EventParam == GROWING_TIMER) //
Elseif ThisEvent Param is GROWING_TIMER
{
HandleGrow(); // Call HandleGrow function
}
break;
case BTN_WEATHER: // If ThisEvent is BTN_WEATHER
// Call HandleWeather function with parameter

SPRING

HandleWeather(SPRING);
break;
case PROX_FAR: // If ThisEvent is PROX_FAR
// Set CurrentState to Spring
CurrentState = Spring;
// Call HandleProx function with parameter of
ThisEvent

HandleProx(ThisEvent);
break;
case ANALOG_CHANGE: // If ThisEvent is ANALOG_CHANGE
// Call HandleAnalog function with parameter of

ThisEvent

HandleAnalog(ThisEvent);
break;
default:
break;
}

break;
case Summer :
// If current state is Summer State
{
switch(ThisEvent.EventType)
{
case ES_TIMEOUT:
if(ThisEvent.EventParam == SEASON_TIMER) // If
ThisEvent is ES_TIMEOUT and timer is SEASON_TIMER
{
// Set CurrentState to Fall
CurrentState = Fall;
// Call ChangeSeasonTo function with
parameter FALL

SUMMER

ChangeSeasonTo(FALL);
}
break;
case BTN_WEATHER: // If ThisEvent is BTN_WEATHER
// Call HandleWeather function with parameter
HandleWeather(SUMMER);
break;
case PROX_NEAR: // If ThisEvent is PROX_NEAR
// Set CurrentState to SummerGrowing
CurrentState = SummerGrowing;

ThisEvent

// Call HandleProx function with parameter of


HandleProx(ThisEvent);
break;

case ANALOG_CHANGE: // If ThisEvent is ANALOG_CHANGE


// Call HandleAnalog function with parameter
ThisEvent

HandleAnalog(ThisEvent);
break;
default:
break;

}
State

break;
case SummerGrowing :

// If current state is SummerGrowing

switch(ThisEvent.EventType)
{
case ES_TIMEOUT:
if(ThisEvent.EventParam == SEASON_TIMER) // If
ThisEvent Param is SEASON_TIMER
{
// Set CurrentState to FallGrowing
CurrentState = FallGrowing;
// Call ChangeSeasonTo function with
parameter FALL

ChangeSeasonTo(FALL);
}
else if(ThisEvent.EventParam == GROWING_TIMER) //
Elseif ThisEvent Param is GROWING_TIMER
{
// Call HandleGrow function
HandleGrow();
}
break;
case BTN_WEATHER: // If ThisEvent is BTN_WEATHER
// Call HandleWeather function with parameter
SUMMER

HandleWeather(SUMMER);
break;
case PROX_FAR: // If ThisEvent is PROX_FAR with param

for which sensor

// Set CurrentState to Summer


CurrentState = Summer;
// Call HandleProx function with parameter of

ThisEvent

HandleProx(ThisEvent);
break;
case ANALOG_CHANGE: // If ThisEvent is ANALOG_CHANGE
// Call HandleAnalog function with parameter of

ThisEvent

HandleAnalog(ThisEvent);
break;
default:
break;
}

break;
case Fall :
{

// If current state is Fall State

switch(ThisEvent.EventType)
{
case ES_TIMEOUT:
if(ThisEvent.EventParam == SEASON_TIMER) // If
ThisEvent is ES_TIMEOUT and timer is SEASON_TIMER
{
// Set CurrentState to Winter
CurrentState = Winter;
// Call ChangeSeasonTo function with
parameter WINTER
ChangeSeasonTo(WINTER);
}
break;
case BTN_WEATHER: // If ThisEvent is BTN_WEATHER
// Call HandleWeather function with parameter FALL
HandleWeather(FALL);
break;
case PROX_NEAR: // If ThisEvent is PROX_NEAR
// Set CurrentState to FallGrowing
CurrentState = FallGrowing;
// Call HandleProx function with parameter of

ThisEvent

HandleProx(ThisEvent);
break;
case ANALOG_CHANGE: // If ThisEvent is ANALOG_CHANGE
// Call HandleAnalog function with parameter
ThisEvent

HandleAnalog(ThisEvent);
break;
default:
break;

break;
case FallGrowing :
// If current state is FallGrowing State
{
switch(ThisEvent.EventType)
{
case ES_TIMEOUT:
if(ThisEvent.EventParam == SEASON_TIMER) // If
ThisEvent Param is SEASON_TIMER
{
// Set CurrentState to WinterGrowing
CurrentState = WinterGrowing;
parameter WINTER

// Call ChangeSeasonTo function with

ChangeSeasonTo(WINTER);
}
else if(ThisEvent.EventParam == GROWING_TIMER) //
Elseif ThisEvent Param is GROWING_TIMER
{
// Call HandleGrow function
HandleGrow();
}
break;
case BTN_WEATHER: // If ThisEvent is BTN_WEATHER
// Call HandleWeather function with parameter FALL

HandleWeather(FALL);
break;
case PROX_FAR: // If ThisEvent is PROX_FAR
// Set CurrentState to Fall
CurrentState = Fall;
// Call HandleProx function with parameter of
ThisEvent

HandleProx(ThisEvent);
break;
case ANALOG_CHANGE: // If ThisEvent is ANALOG_CHANGE
// Call HandleAnalog function with parameter of

ThisEvent

HandleAnalog(ThisEvent);
break;
default:
break;
}

break;
case Winter :
// If current state is Winter State
{
switch(ThisEvent.EventType)
{
case ES_TIMEOUT:
if(ThisEvent.EventParam == SEASON_TIMER) // If
ThisEvent is ES_TIMEOUT and timer is SEASON_TIMER
{
// Set CurrentState to ReplayTree
CurrentState = ReplayTree;
// Post REPLAY event to Branch Service
PostEvent.EventType = REPLAY;
Post_BranchService(PostEvent);
// Turn vibration motor off
ChangeVibrationMotor(VIB_MOT_OFF);
// Call ChangeSeasonTo function with

parameter SPRING
}

ChangeSeasonTo(SPRING);

case BTN_WEATHER: // If ThisEvent is BTN_WEATHER


// Call HandleWeather function with parameter
WINTER

HandleWeather(WINTER);
break;
case PROX_NEAR: // If ThisEvent is PROX_NEAR
// Set CurrentState to WinterGrowing
CurrentState = WinterGrowing;

ThisEvent

// Call HandleProx function with parameter of


HandleProx(ThisEvent);
break;
case ANALOG_CHANGE: // If ThisEvent is ANALOG_CHANGE
// Call HandleAnalog function with parameter

ThisEvent

HandleAnalog(ThisEvent);
break;
default:
break;

}
State

break;
case WinterGrowing :

// If current state is WinterGrowing

switch(ThisEvent.EventType)
{
case ES_TIMEOUT:
if(ThisEvent.EventParam == SEASON_TIMER) // If
ThisEvent Param is SEASON_TIMER
{
// Set CurrentState to ReplayTree
CurrentState = ReplayTree;
// Post REPLAY event to Branch Service
PostEvent.EventType = REPLAY;
Post_BranchService(PostEvent);
//Put Vibration Motor OFF
ChangeVibrationMotor(VIB_MOT_OFF);
// Call ChangeSeasonTo function with

parameter SPRING

ChangeSeasonTo(SPRING);
}
else if(ThisEvent.EventParam == GROWING_TIMER) //
Elseif ThisEvent Param is GROWING_TIMER
{
// Call HandleGrow function
HandleGrow();
}
break;
case BTN_WEATHER: // If ThisEvent is BTN_WEATHER
// Call HandleWeather function with parameter

WINTER

HandleWeather(WINTER);
break;
case PROX_FAR: // If ThisEvent is PROX_FAR
// Set CurrentState to Winter
CurrentState = Winter;
// Call HandleProx function with parameter of
ThisEvent

HandleProx(ThisEvent);
break;
case ANALOG_CHANGE: // If ThisEvent is ANALOG_CHANGE
// Call HandleAnalog function with parameter of

ThisEvent

HandleAnalog(ThisEvent);
break;
default:
break;
}

break;
case ReplayTree :
// If current state is ReplayTree State
if ( ThisEvent.EventType == REPLAY ) //If this event is REPLAY
{
// Post REPLAY event to AudioBoard Service
PostEvent.EventType = REPLAY;
PostAudioBoard(PostEvent);
}
DONE_REPLAYING

if(ThisEvent.EventType == DONE_REPLAYING) // If ThisEvent is


{

// Post WAITING event to services (Audio, Motors, Start

Button)

PostEvent.EventType = WAITING;
PostTimingMotor(PostEvent);
PostAudioBoard(PostEvent);
PostStartButton(PostEvent);
// Set CurrentState to WaitingForArtist
CurrentState = WaitingForArtist;
// Post WELCOME_REPLAY event to Branch Service
PostEvent.EventType = WELCOME_REPLAY;
Post_BranchService(PostEvent);
}
break;

default :
break;
}
return ReturnEvent;
}
/****************************************************************************
Function
QueryTreeSM
Parameters
None
Returns
TreeState_t The current state of the tree state machine
Description
returns the current state of the tree state machine
Notes
Author
Matthew Miller, 11/14/16, 18:26
****************************************************************************/
TreeState_t QueryTreeFSM ( void )
{
return CurrentState;
}
/****************************************************************************
Function
HandleWeather
Parameters
Integer Season indicating the season of the year
Returns

Nothing
Description
Performs the actions that occur when a weather event happens
Notes
Author
Matthew Miller, 11/14/16, 18:26
****************************************************************************/
void HandleWeather(uint8_t Season)
{
// Post WEATHER event to Audio and Branch Service with EventParam Season
ES_Event PostEvent;
PostEvent.EventType = WEATHER;
PostEvent.EventParam = Season;
PostAudioBoard(PostEvent);
Post_BranchService(PostEvent);
}
/****************************************************************************
Function
HandleProx
Parameters
An event, either PROX_NEAR or PROX_FAR
Returns
Nothing
Description
Performs the actions that occur when a hand trips or untrips sensor
Notes
Author
Matthew Miller, 11/14/16, 18:26
****************************************************************************/
void HandleProx(ES_Event ThisEvent)
{
if(ThisEvent.EventType == PROX_NEAR) // If ThisEvent is PROX_NEAR
{
// Store the branch which is growing in GrowingBranch from ThisEvent
EventParam
GrowingBranch = ThisEvent.EventParam;
//Put Vibration Motor ON
ChangeVibrationMotor(VIB_MOT_ON);
// Set GROWING_TIMER for GROWING_TIME
ES_Timer_InitTimer(GROWING_TIMER, GROWING_TIME);

}
else if(ThisEvent.EventType == PROX_FAR) // Elseif ThisEvent is PROX_FAR
{
//Put Vibration Motor OFF
ChangeVibrationMotor(VIB_MOT_OFF);
}

/****************************************************************************
Function
HandleAnalog
Parameters
An event with parameter of the analog value

Returns
Nothing
Description
Performs the actions that occur when the slide potentiometer moves
Notes
Author
Matthew Miller, 11/14/16, 18:26
****************************************************************************/
void HandleAnalog(ES_Event ThisEvent)
{
// Call SetNewColorLimit function with parameter EventParam from input
ThisEvent
SetNewColorLimit(ThisEvent.EventParam);
}
/****************************************************************************
Function
ChangeSeasonTo
Parameters
An integer indicating the season of the year
Returns
Nothing
Description
Performs the actions that occur when the SEASON_TIMER times out and it is
a new season of the year
Notes
Author
Matthew Miller, 11/14/16, 18:26
****************************************************************************/
void ChangeSeasonTo(uint8_t Season)
{
// Post SEASON_CHANGE event with EventParam Season to Branch Service
ES_Event PostEvent;
PostEvent.EventType = SEASON_CHANGE;
PostEvent.EventParam = Season;
Post_BranchService(PostEvent);
//Set SEASON_TIMER for SEASON_TIME
if(CurrentState != ReplayTree) ES_Timer_InitTimer(SEASON_TIMER,
SEASON_TIME);
}
/****************************************************************************
Function
HandleGrow
Parameters
Nothing
Returns
Nothing
Description
Performs the actions that occur when a hand is in front of a sensor and
a branch is growing
Notes

Author
Matthew Miller, 11/14/16, 18:26
****************************************************************************/
void HandleGrow(void)
{
// Post GROW event with EventParam GrowingBranch to BranchService
ES_Event PostEvent;
PostEvent.EventType = GROW;
PostEvent.EventParam = GrowingBranch;
Post_BranchService(PostEvent);
//Set GROWING_TIMER for GROWING_TIME
ES_Timer_InitTimer(GROWING_TIMER, GROWING_TIME);
}

S-ar putea să vă placă și