0% found this document useful (0 votes)
149 views6 pages

Scenesm C

This document contains C code for implementing a state machine (SceneSM) to control different services (e.g. audio, lights, motor) based on events (e.g. proximity, wind speed). It defines states for the state machine (e.g. idle, open, wind) and handles different events in each state by transitioning states and posting events to trigger other services as needed. It includes initialization functions, an event handling function to process events and transition states, and constants/variables used in the state machine implementation.

Uploaded by

api-340729449
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as RTF, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
149 views6 pages

Scenesm C

This document contains C code for implementing a state machine (SceneSM) to control different services (e.g. audio, lights, motor) based on events (e.g. proximity, wind speed). It defines states for the state machine (e.g. idle, open, wind) and handles different events in each state by transitioning states and posting events to trigger other services as needed. It includes initialization functions, an event handling function to process events and transition states, and constants/variables used in the state machine implementation.

Uploaded by

api-340729449
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as RTF, PDF, TXT or read online on Scribd
You are on page 1/ 6

#include

#include
#include
#include
#include
#include
#include
#include
#include

<stdint.h>
<stdbool.h>
<stdio.h>
"inc/hw_types.h"
"inc/hw_memmap.h"
"driverlib/sysctl.h"
"driverlib/gpio.h"
"driverlib/interrupt.h"
"utils/uartstdio.h"

#include
#include
#include
#include

"ES_Configure.h"
"ES_Framework.h"
"ES_Port.h"
"termio.h"

#include
#include
#include
#include

"inc/hw_gpio.h"
"inc/hw_sysctl.h"
<string.h>
<stdlib.h>

//Include module-level header files


#include "SceneSM.h"
//#include "ReadAnalogInputs.h"
#include "ADMulti.h"
#include "Audio.h"
#include "MotorService.h"
#include "SenseWind.h"
#include "ServoService.h"
#include "Plants.h"
#include "LightsService.h"
#include "WeatherService.h"
#include "RangeFinder.h"
//Include module-level definitions
#define USER_INTERFACE_TIME 30000
#define SCENE_WIND_TIME 15000
#define SCENE_CONSTRUCTION_TIME 10000
#define SCENE_PROXIMITY_TIME 100
#define SCENE_MIN_WIND_THRESHOLD 7
static
static
static
static
static
static

uint8_t MyPriority;
SSMState_t CurrentState; //the current state of the Scene SM
uint8_t LastWindSpeed=0;
bool First_Wind=0;
bool Wind_Timeout=0;
uint8_t plant[] = {0,0,0,0};

// Initialize Scene SM
// Takes: uint8_t Priority: local priority number
// Returns: True if ES_INIT event is posted
bool SceneSMInit(uint8_t Priority) {
//
set the service priority
MyPriority = Priority;
//
set current state to reset
CurrentState=Scene_Reset;
// post a reset event
ES_Event Start;
Start.EventType=ES_RESET;
ES_PostToService(MyPriority, Start);
//
initialize the analog ports
ADC_MultiInit(2); //NEEDED, UNCOMMENT, TESTING ONLY
//
post an ES_Init event to the service

ES_Event ThisEvent;
ThisEvent.EventType = ES_INIT;
//
return true if the event is successfully posted, else return false
return ES_PostToService( MyPriority, ThisEvent);
}
// Set up Scene SM post function
// Takes: ES_Event ThisEvent: Event to be posted
// Returns: true if event is posted
bool PostSceneSM(ES_Event ThisEvent) {
// Post Event
return ES_PostToService(MyPriority, ThisEvent);
}

// Run Servo Service


// Takes: ES_Event ThisEvent: Event to be processed
// Returns: ES_Event ReturnEvent: ES_NO_EVENT if no errors
ES_Event RunSceneSM (ES_Event ThisEvent) {
// Set up return event and assume no errors
ES_Event ReturnEvent;
ReturnEvent.EventType = ES_NO_EVENT;
// build new event for later use
ES_Event NewEvent;
// set up next state as current state
SSMState_t NextState = CurrentState;
switch (CurrentState){
// if current state is idle
case (Scene_Idle):{
//
if event is proximity
if (ThisEvent.EventType == ES_WELCOME){
//
send welcome event to lights
PostLightsService(ThisEvent);
//
set user interface timer
ES_Timer_InitTimer(USER_INTERFACE_TIMER,
USER_INTERFACE_TIME);
// next state is open
NextState = Scene_Open;
}
//
else if event is proximity timer timeout
else if
((ThisEvent.EventType==ES_TIMEOUT)&&(ThisEvent.EventParam==SCENE_PROXIMITY_TIMER
)) {
//
check the proximity sensor event checker
CheckRangeEvents();
//
reset the proximity timer timeout
ES_Timer_InitTimer(SCENE_PROXIMITY_TIMER,
SCENE_PROXIMITY_TIME);
}
break;
}
//
else if current state is open
case(Scene_Open):{
if (ThisEvent.EventType == ES_BUTTON_DOWN){
// send open event to audio, lights, motor, wind reader,
and servo

NewEvent.EventType = ES_OPEN;
PostMotor(NewEvent);
PostAudioService(NewEvent);
PostLightsService(NewEvent);
PostServoS(NewEvent);

//
reset user niterface timer
ES_Timer_InitTimer(USER_INTERFACE_TIMER,
USER_INTERFACE_TIME);

//
next state is open
NextState = Scene_Open;

}
// else if event is motor timeout
else if
((ThisEvent.EventType==ES_TIMEOUT)&&(ThisEvent.EventParam==MOTOR_TIMER)) {
// post open event to wind reader
NewEvent.EventType = ES_OPEN;
PostWindReaderService(NewEvent);
// reset user interface timer
ES_Timer_InitTimer(USER_INTERFACE_TIMER,
USER_INTERFACE_TIME);
//
next state is wind
NextState = Scene_Wind;
}
//
else if event is user interface timeout
else if
((ThisEvent.EventType==ES_TIMEOUT)&&(ThisEvent.EventParam==USER_INTERFACE_TIMER)
) {
//
send reset event SceneSM
NewEvent.EventType=ES_RESET;
PostSceneSM(NewEvent);
//
next state is reset
NextState=Scene_Reset;
}
break;
}
//
else if current state is wind
case (Scene_Wind): {
//
if event is wind
if (ThisEvent.EventType==ES_WIND) {
// if this is the first gust of wind
if (First_Wind==0) {
// Start the wind timer
ES_Timer_InitTimer(SCENE_WIND_TIMER,
SCENE_WIND_TIME);
// Set First Wind
First_Wind=1;
}
//
send wind event to lights, audio, servo
PostWeatherService(ThisEvent);
PostAudioService(ThisEvent);
PostServoS(ThisEvent);
//
set user interface timer
ES_Timer_InitTimer(USER_INTERFACE_TIMER,
USER_INTERFACE_TIME);
//
update last wind speed
LastWindSpeed=ThisEvent.EventParam;
//
if wind speed is 0 and wind has timed out
if
((LastWindSpeed<SCENE_MIN_WIND_THRESHOLD)&&(Wind_Timeout==1)) {
//
send grow (0) event to audio, servo, plants,
wind reader
NewEvent.EventType=ES_GROW;
NewEvent.EventParam=0;
PostAudioService(NewEvent);
PostServoS(NewEvent);
PostPlants(NewEvent);
PostWindReaderService(NewEvent);
//
next state is grow
NextState=Scene_Grow;

}
//
else
else {
//
next state is wind
NextState=Scene_Wind;
}
}
//
else if event is wind timeout
else if
((ThisEvent.EventType==ES_TIMEOUT)&&(ThisEvent.EventParam==SCENE_WIND_TIMER)) {
//
set wind timeout true
Wind_Timeout=1;
//
if last wind speed is 0
if (LastWindSpeed<SCENE_MIN_WIND_THRESHOLD) {
//
send grow (0) event to audio, lights, servo,
plants, wind reader
NewEvent.EventType=ES_GROW;
NewEvent.EventParam=0;
PostWindReaderService(NewEvent);
PostAudioService(NewEvent);
PostServoS(NewEvent);
PostPlants(NewEvent);
//
next state is grow
NextState=Scene_Grow;
}
//
else
else {
//
next state is wind
NextState=Scene_Wind;
}
}
//
else if event is button down
else if (ThisEvent.EventType==ES_BUTTON_DOWN) {
//
send reset event SceneSM
NewEvent.EventType=ES_RESET;
PostSceneSM(NewEvent);
//
next state is reset
NextState=Scene_Reset;
}
//
else if event is user interface timeout
else if
((ThisEvent.EventType==ES_TIMEOUT)&&(ThisEvent.EventParam==USER_INTERFACE_TIMER)
) {
//
next state is reset
NextState=Scene_Reset;
//
send reset event SceneSM
NewEvent.EventType=ES_RESET;
PostSceneSM(NewEvent);
}
break;
}
//
else if current state is grow
case (Scene_Grow): {
//
if the event is grow
if (ThisEvent.EventType==ES_GROW) {
//
if the current plant has not been grown
if
((plant[ThisEvent.EventParam]==0)&&(ThisEvent.EventParam!=0)) {
//
update grown plants
plant[ThisEvent.EventParam]=1;
//
update user interface timer
ES_Timer_InitTimer(USER_INTERFACE_TIMER,
USER_INTERFACE_TIME);
//
post event to audio, servos

//BEGIN HACK ********************


ES_Event plantGrownHACK; //need to post a distinct
event to audio. A plant growing SHOULD be a different event than the one to
start the grow scene, so this is a hack!
plantGrownHACK.EventType = ES_PLANTGROWN; //create
the plant grown event, since the incoming event is an ES_GROW and we can't use
that
PostAudioService(plantGrownHACK); //send the plant
grown event to audio
//END HACK ***************************************
PostServoS(ThisEvent);
//
if all plants grown
if ((plant[1]==1)&&(plant[2]==1)&&(plant[3]==1)) {
//
post construction event to audio,
servos

NewEvent.EventType=ES_CONSTRUCTION;
PostAudioService(NewEvent);
PostServoS(NewEvent);
//
set construction timer
ES_Timer_InitTimer(SCENE_CONSTRUCTION_TIMER,

SCENE_CONSTRUCTION_TIME);

//
next state is construction
NextState=Scene_Construction;

}
//
else
else {
//
next state is grow
NextState=Scene_Grow;
}

}
//
else
else {
//
next state is grow
NextState=Scene_Grow;
}

}
//
else if event is button down
else if (ThisEvent.EventType==ES_BUTTON_DOWN) {
//
send reset event SceneSM
NewEvent.EventType=ES_RESET;
PostSceneSM(NewEvent);
//
next state is reset
NextState=Scene_Reset;
}
//
else if event is user interface timeout
else if
((ThisEvent.EventType==ES_TIMEOUT)&&(ThisEvent.EventParam==USER_INTERFACE_TIMER)
) {
//
send reset event SceneSM
NewEvent.EventType=ES_RESET;
PostSceneSM(NewEvent);
//
next state is reset
NextState=Scene_Reset;
}
break;
}
//
else if current state is construction
case (Scene_Construction) : {
//
if event is construction timeout
if
((ThisEvent.EventType==ES_TIMEOUT)&&(ThisEvent.EventParam==SCENE_CONSTRUCTION_TI
MER)) {

//
send reset event SceneSM
NewEvent.EventType=ES_RESET;
PostSceneSM(NewEvent);
//
next state is reset
NextState=Scene_Reset;

}
else if (ThisEvent.EventType==ES_BUTTON_DOWN) {
// send reset event SceneSM
NewEvent.EventType=ES_RESET;
PostSceneSM(NewEvent);
//
next state is reset
NextState=Scene_Reset;
}
//
else if event is user interface timeout
else if
((ThisEvent.EventType==ES_TIMEOUT)&&(ThisEvent.EventParam==USER_INTERFACE_TIMER)
) {
//
next state is reset
NextState=Scene_Reset;
//
send reset event SceneSM
NewEvent.EventType=ES_RESET;
PostSceneSM(NewEvent);
}
break;

}
//
else if current state is reset
case (Scene_Reset): {
// if event is reset event
if (ThisEvent.EventType==ES_RESET) {
//
set First Wind to false
First_Wind=0;
//
set wind timeout false
Wind_Timeout=0;
//
set last wind speed to 0
LastWindSpeed=0;
//
set plants grown to 0
memset(plant, 0, sizeof(plant));
//
send reset event to audio, lights, motor, servo,
plants, wind reader
PostAudioService(ThisEvent);
PostLightsService(ThisEvent);
PostServoS(ThisEvent);
PostMotor(ThisEvent);
PostPlants(ThisEvent);
PostWindReaderService(ThisEvent);
//
next state is idle
ES_Timer_InitTimer(SCENE_PROXIMITY_TIMER, 10000);
NextState=Scene_Idle;
}
break;
}
}
//
Current state is next state
CurrentState=NextState;
return ReturnEvent;
}

You might also like