Вы находитесь на странице: 1из 7

#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 "inc/hw_gpio.h"
#include "inc/hw_sysctl.h"
#include "Servo.h"
#include "ServoService.h"
#include "PWM10Tiva.h"
// Time required for servos to fully reset to 0
#define RESET_TIME_SERVO 500
// Timer used to create a swaying effect of servos
#define WIND_TIME_SERVO 500
// add time delay for last grow event
#define SERVO_CONSTRUCTION_TIME 1000
// Maximum and minimum speeds expected from wind events, used to adjust servo
positions
#define MIN_SPEED_SERVO 0
#define MAX_SPEED_SERVO 100
// Maximum allowed angle for plants to lean
#define MAX_ANGLE_SERVO 180
// position for each servo in the active position, allows for some calibration
based on installation
#define WIND_ANGLE_SERVOS 130
// This is actually the wind servos'
inactive angle
#define PLANT_1_ANGLE_SERVO 20
#define PLANT_1_REST_SERVO 100
#define PLANT_2_ANGLE_SERVO 120
#define PLANT_2_REST_SERVO 20
#define PLANT_3_ANGLE_SERVO 115
#define PLANT_3_REST_SERVO 25
#define CONSTRUCTION_ANGLE_SERVO 180
#define CONSTRUCTION_REST_SERVO 0
// Servo number definitions
#define WIND_SERVOS (BIT0HI|BIT1HI|BIT2HI)
#define PLANT_1_SERVO BIT3HI
#define PLANT_2_SERVO BIT4HI
#define PLANT_3_SERVO BIT5HI
#define CONSTRUCTION_SERVO BIT6HI
static uint8_t MyPriority;
SSState_t CurrentState;
static uint8_t speed=MIN_SPEED_SERVO;
static uint8_t LastDirection=0;
static uint8_t ResetCounter=1;
static
static
static
static

void
void
void
void

drive_wind(uint8_t wind_speed, uint8_t direction);


drive_grow(uint8_t plant);
drive_construction(void);
drive_reset(uint8_t step);

// Initialize Servo Service


// Takes: uint8_t Priority: local priority number
// Returns: True if ES_INIT event is posted
bool ServoSInit(uint8_t Priority){
//
set local priority
MyPriority=Priority;
//
initialize servo module
ServoInit();
//
current state is idle
CurrentState=Servo_Idle;
//
post es_init event
ES_Event Event2Post;
Event2Post.EventType=ES_INIT;
return ES_PostToService(Priority, Event2Post);
}
// Set up Servo post service
// Takes: ES_Event ThisEvent: Event to be posted
// Returns: true if event is posted
bool PostServoS(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 RunServoS(ES_Event ThisEvent) {
ES_Event ReturnEvent;
ReturnEvent.EventType=ES_NO_EVENT;
//
next state is current state
SSState_t NextState = CurrentState;
switch (CurrentState) {
//
if current state is idle
case (Servo_Idle): {
//
if event is open event
if (ThisEvent.EventType==ES_OPEN) {
//
next state is wind
NextState=Servo_Wind;
}
//
else if event is reset event
else if (ThisEvent.EventType==ES_RESET) {
//
call reset function
drive_reset(ResetCounter);
//
set reset timer
ES_Timer_InitTimer(SERVO_RESET_TIMER, RESET_TIME_SERVO);
//
next state is reset
NextState = Servo_Reset;
}
break;
}
//
else if state is wind
case (Servo_Wind): {
//
if event is wind event
if (ThisEvent.EventType==ES_WIND) {
//
speed equals event param
speed=ThisEvent.EventParam;
//
drive servos forward using wind function
drive_wind(speed, 1);
//
set wind timer

ES_Timer_InitTimer(SERVO_WIND_TIMER, WIND_TIME_SERVO);
//
next state is wind
NextState=Servo_Wind;

}
//
else if event is timeout event
else if
((ThisEvent.EventType==ES_TIMEOUT)&&(ThisEvent.EventParam==SERVO_WIND_TIMER)) {
//
if last direction was forward
if (LastDirection==1) {
//
drive servos backward using wind function
drive_wind(speed, 0);
}
//
else if last direction was backward
else if (LastDirection==0) {
//
drive servos forward using wind function
drive_wind(speed, 1);
}
//
reset wind timer
ES_Timer_InitTimer(SERVO_WIND_TIMER, WIND_TIME_SERVO);
//
next state is wind
NextState=Servo_Wind;
}
//
else if event is grow event
else if (ThisEvent.EventType==ES_GROW) {
//
speed is 0
speed=MIN_SPEED_SERVO;
//
send speed to wind function
drive_wind(speed, 0);
//
next state is grow
NextState=Servo_Grow;
}
//
else if event is reset event
else if (ThisEvent.EventType==ES_RESET) {
//
call reset function
drive_reset(ResetCounter);
//
set reset timer
ES_Timer_InitTimer(SERVO_RESET_TIMER, RESET_TIME_SERVO);
//
next state is reset
NextState=Servo_Reset;
}
break;
}
//
else if next state is grow
case (Servo_Grow): {
// if the event is a grow event
if (ThisEvent.EventType==ES_GROW) {
//
if the event param is 0
if (ThisEvent.EventParam==0) {
//
speed is 0
speed=MIN_SPEED_SERVO;
//
send speed to wind function
drive_wind(speed, 0);
//
next state is grow
NextState=Servo_Grow;
}
//
else if the event is grow and param is between 1
and 3
else if
((ThisEvent.EventParam>=1)&&(ThisEvent.EventParam<=3)) {
//
plant ro grow equals event param
uint8_t plant = ThisEvent.EventParam;
//
drive the servos using the grow function
drive_grow(plant);
//
next state is grow

NextState=Servo_Grow;

}
//
else if event is construction event
else if (ThisEvent.EventType==ES_CONSTRUCTION) {
// set construction timer
ES_Timer_InitTimer(SERVO_CONSTRUCTION_TIMER,
SERVO_CONSTRUCTION_TIME);
//
next state is construction
NextState=Servo_Construction;
}
//
else if event is reset event
else if (ThisEvent.EventType==ES_RESET) {
//
call reset function
drive_reset(ResetCounter);
//
set reset timer
ES_Timer_InitTimer(SERVO_RESET_TIMER, RESET_TIME_SERVO);
//
next state is reset
NextState=Servo_Reset;
}
break;
}
//
else if state is construction
case (Servo_Construction): {
// if event is construction timeout
if
((ThisEvent.EventType==ES_TIMEOUT)&&(ThisEvent.EventParam==SERVO_CONSTRUCTION_TI
MER)) {
//
call construction function
drive_construction();
//
next state is construction
NextState=Servo_Construction;
}
//
else if event is reset event
if (ThisEvent.EventType==ES_RESET) {
//
call reset function
drive_reset(ResetCounter);
//
set reset timer
ES_Timer_InitTimer(SERVO_RESET_TIMER, RESET_TIME_SERVO);
//
next state is reset
NextState=Servo_Reset;
}
break;
}
//
else if state is reset
case (Servo_Reset): {
//
if event is timeout event
if
((ThisEvent.EventType==ES_TIMEOUT)&&(ThisEvent.EventParam==SERVO_RESET_TIMER)) {
//
if the reset is not finished
if (ResetCounter!=1) {
// call the reset function
drive_reset(ResetCounter);
// set the reset timer
ES_Timer_InitTimer(SERVO_RESET_TIMER,
RESET_TIME_SERVO);
// next state is reset
NextState=Servo_Reset;
}
else {
//
next state is idle
NextState=Servo_Idle;
}
}

break;

}
//
current state is next state
CurrentState=NextState;
return ReturnEvent;
}
// Drive servos to simulate wind
// Takes:
uint8_t speed: wind speed
//
uint8_t direction: 1 is forward, 0 is reverse
// Returns: nothing
static void drive_wind(uint8_t wind_speed, uint8_t direction) {
//
if speed equals 0
if (wind_speed==MIN_SPEED_SERVO) {
//
set servos to 0
ServoWrite((uint8_t) WIND_SERVOS, (uint8_t) WIND_ANGLE_SERVOS);
//
last direction was backwards
LastDirection=0;
}
//
else
else {
// limit speed
if (wind_speed>MAX_SPEED_SERVO) {
wind_speed=MAX_SPEED_SERVO;
}
//
limit maximum angle
float pos=(((float)wind_speed)/MAX_SPEED_SERVO)*(MAX_ANGLE_SERVOWIND_ANGLE_SERVOS);
//
if direction is forward
if (direction==1) {
//
write position based on speed to wind servos
ServoWrite((uint8_t) WIND_SERVOS, (pos+WIND_ANGLE_SERVOS));
//
last direction was forward
LastDirection=1;
}
//
else if direction is backwards
else if (direction==0) {
//
write position based on a fraction of speed to wind
servos (simulate rocking)
ServoWrite((uint8_t) WIND_SERVOS, (uint8_t)
(pos*0.6+WIND_ANGLE_SERVOS));
//
last direction was backwards
LastDirection=0;
}
}
}
// Grow the various plants on set
// Takes: uint9_t plant: plant to be grown
// Returns: nothing
static void drive_grow(uint8_t plant) {
//
if plant is from 1-3
switch (plant) {
//
grow requested plant
case ((uint8_t) 1): {
ServoWrite((uint8_t) PLANT_1_SERVO, (uint8_t)
PLANT_1_ANGLE_SERVO);
break;
}
case ((uint8_t) 2): {
ServoWrite((uint8_t) PLANT_2_SERVO, (uint8_t)
PLANT_2_ANGLE_SERVO);

break;
}
case ((uint8_t) 3): {
ServoWrite((uint8_t) PLANT_3_SERVO, (uint8_t)
PLANT_3_ANGLE_SERVO);
break;
}
}
}
// Construct the village
// Takes: uint9_t plant: plant to be grown
// Returns: nothing
static void drive_construction(void) {
//
drive construction servos
ServoWrite((uint8_t) CONSTRUCTION_SERVO, (uint8_t)
CONSTRUCTION_ANGLE_SERVO);
}
// Reset the servos
// Takes: uint8_t step: 1 - 3 depending on which reset step is required
// Returns: nothing
static void drive_reset(uint8_t step) {
// if step is 1
if (step==1) {
//
reset speed to 0
speed=MIN_SPEED_SERVO;
// reset last direction
LastDirection=0;
//
send Plant 1 servo to rest
ServoWrite((uint8_t) PLANT_1_SERVO, (uint8_t) PLANT_1_REST_SERVO);
//
update Reset Counter
ResetCounter=2;
}
//
else if step is 2
else if (step==2) {
//
send Plant 2 servo to rest
ServoWrite((uint8_t) PLANT_2_SERVO, (uint8_t) PLANT_2_REST_SERVO);
//
update the Reset Counter
ResetCounter=3;
}
//
else if step is 3
else if (step==3) {
//
send Plant 3 servo to rest
ServoWrite((uint8_t) PLANT_3_SERVO, (uint8_t) PLANT_3_REST_SERVO);
//
update the Reset Counter
ResetCounter=4;
}
// else if step is 4
else if (step==4) {
//
send Construction servo to rest
ServoWrite((uint8_t) CONSTRUCTION_SERVO, (uint8_t)
CONSTRUCTION_REST_SERVO);
//
update the Reset Counter
ResetCounter=5;
}
//
else if step is 5
else if (step==5) {
//
drive wind servos back to rest
ServoWrite((uint8_t) WIND_SERVOS, (uint8_t) WIND_ANGLE_SERVOS);
//
update the Reset Counter
ResetCounter=6;
}
//
else if step is 6

else if (step==6) {
//
deselect all servos
ServoWrite(0, 0);
//
Reset the Reset Counter
ResetCounter=1;
}
}

Вам также может понравиться