Академический Документы
Профессиональный Документы
Культура Документы
#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
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;
}
}