/****************************************************************************
Module
EventCheckers.c
Revision
1.0.1
Description
This is the sample for writing event checkers along with the event
checkers used in the basic framework test harness.
Notes
Note the use of static variables in sample event checker to detect
ONLY transitions.
History
When Who What/Why
-------------- --- --------
08/06/13 13:36 jec initial version
****************************************************************************/
// this will pull in the symbolic definitions for events, which we will want
// to post in response to detecting events
#include "ES_Configure.h"
// This gets us the prototype for ES_PostAll
#include "ES_Framework.h"
// this will get us the structure definition for events, which we will need
// in order to post events in response to detecting events
#include "ES_Events.h"
// if you want to use distribution lists then you need those function
// definitions too.
#include "ES_PostList.h"
// This include will pull in all of the headers from the service modules
// providing the prototypes for all of the post functions
#include "ES_ServiceHeaders.h"
// this test harness for the framework references the serial routines that
// are defined in ES_Port.c
#include "ES_Port.h"
// include our own prototypes to insure consistency between header &
// actual functionsdefinition
#include "EventCheckers.h"
#include "dbprintf.h"
#include "PIC32_AD_Lib.h"
#define BUTTON_DELAY 1000 // 1 second debounce
#define SENSOR_DELAY 50 // sample distance sensor every 5 ms
#define COLLISION_DELAY_FAST 800 // pause checking obstacles
#define COLLISION_DELAY_SLOW 1500
#define OBSTACLE_FAST_TICK 4600
#define OBSTACLE_SLOW_TICK 4200
#define POT_DELAY 200 // check pot every 0.2 sec
#define POT_CHANGE_THRESHOLD 50
int LastButtonState;
uint16_t LastButtonTime;
uint16_t LastSensorTime;
uint16_t LastCollisionTime;
bool buttonActive = true;
bool sensorActive = true;
static uint32_t adcResults[3];
uint16_t LastPotVal;
uint16_t LastPotTime;
// This is the event checking function sample. It is not intended to be
// included in the module. It is only here as a sample to guide you in writing
// your own event checkers
#if 0
/****************************************************************************
Function
Check4Lock
Parameters
None
Returns
bool: true if a new event was detected
Description
Sample event checker grabbed from the simple lock state machine example
Notes
will not compile, sample only
Author
J. Edward Carryer, 08/06/13, 13:48
****************************************************************************/
bool Check4Lock(void)
{
static uint8_t LastPinState = 0;
uint8_t CurrentPinState;
bool ReturnVal = false;
CurrentPinState = LOCK_PIN;
// check for pin high AND different from last time
// do the check for difference first so that you don't bother with a test
// of a port/variable that is not going to matter, since it hasn't changed
if ((CurrentPinState != LastPinState) &&
(CurrentPinState == LOCK_PIN_HI)) // event detected, so post detected event
{
ES_Event ThisEvent;
ThisEvent.EventType = ES_LOCK;
ThisEvent.EventParam = 1;
// this could be any of the service post functions, ES_PostListx or
// ES_PostAll functions
ES_PostAll(ThisEvent);
ReturnVal = true;
}
LastPinState = CurrentPinState; // update the state for next time
return ReturnVal;
}
#endif
/****************************************************************************
Function
Check4Keystroke
Parameters
None
Returns
bool: true if a new key was detected & posted
Description
checks to see if a new key from the keyboard is detected and, if so,
retrieves the key and posts an ES_NewKey event to TestHarnessService0
Notes
The functions that actually check the serial hardware for characters
and retrieve them are assumed to be in ES_Port.c
Since we always retrieve the keystroke when we detect it, thus clearing the
hardware flag that indicates that a new key is ready this event checker
will only generate events on the arrival of new characters, even though we
do not internally keep track of the last keystroke that we retrieved.
Author
J. Edward Carryer, 08/06/13, 13:48
****************************************************************************/
bool Check4Keystroke(void)
{
if (IsNewKeyReady()) // new key waiting?
{
ES_Event_t ThisEvent;
ThisEvent.EventType = ES_NEW_KEY;
ThisEvent.EventParam = GetNewKey();
ES_PostAll(ThisEvent);
return true;
}
return false;
}
void InitButtonState(void) {
LastButtonState = PORTBbits.RB13;
}
bool Check4Button(void)
{
bool ReturnVal = false;
if (buttonActive)
{
int CurrentButtonState = PORTBbits.RB13;
// DB_printf("%d\n", CurrentButtonState);
if (CurrentButtonState != LastButtonState)
{
if (CurrentButtonState == 1)
{
ES_Event_t ThisEvent;
ThisEvent.EventType = ES_START_BUTTON_PRESS;
PostGameLogicFSM(ThisEvent);
PostAvatarService(ThisEvent);
ReturnVal = true;
LastButtonTime = ES_Timer_GetTime();
buttonActive = false;
}
LastButtonState = CurrentButtonState;
}
}
else
{
uint16_t timeInt = ES_Timer_GetTime() - LastButtonTime;
// button debounce
if (timeInt > BUTTON_DELAY)
{
// DB_printf("reactivated");
buttonActive = true;
LastButtonState = PORTBbits.RB13;
}
}
return ReturnVal;
}
void InitPotValue(void) {
ADC_MultiRead(adcResults);
LastPotVal = adcResults[1];
LastPotTime = ES_Timer_GetTime();
}
bool Check4Pot(void)
{
bool ReturnVal = false;
uint16_t CurrentTime = ES_Timer_GetTime();
uint16_t timeDiff;
if (CurrentTime >= LastPotTime) {
timeDiff = CurrentTime - LastPotTime;
} else {
timeDiff = (UINT16_MAX - LastPotTime) + CurrentTime + 1;
}
if (timeDiff > POT_DELAY)
{
LastPotTime = CurrentTime;
ADC_MultiRead(adcResults);
uint16_t sample = adcResults[1];
int diff = (sample > LastPotVal) ? (sample - LastPotVal) : (LastPotVal - sample);
if (diff > POT_CHANGE_THRESHOLD)
{
DB_printf("New POT value: %d\n", sample);
if (gameStarted)
{
ES_Event_t ThisEvent;
ThisEvent.EventType = ES_POT_CHANGE;
ThisEvent.EventParam = sample;
ReturnVal = true;
PostObstacleService(ThisEvent);
// DB_printf("posted ES_POT_CHANGE !!!\n");
}
}
LastPotVal = sample;
}
return ReturnVal;
}
void InitSensorValue(void) {
LastSensorTime = ES_Timer_GetTime();
}
bool Check4Collision(void)
{
bool ReturnVal = false;
if (gameStarted)
{
if (sensorActive)
{
uint16_t CurrentTime = ES_Timer_GetTime();
uint16_t timeDiff;
if (CurrentTime >= LastSensorTime) {
timeDiff = CurrentTime - LastSensorTime;
} else {
timeDiff = (UINT16_MAX - LastSensorTime) + CurrentTime + 1;
}
if (timeDiff > SENSOR_DELAY)
{
ADC_MultiRead(adcResults);
uint16_t sample = adcResults[2];
LastSensorTime = CurrentTime;
DB_printf("%d\n", sample);
// for (int i = 0; i < 100000; i++) {}
if (sample > 200)
{
// DB_printf("collision value: %d\n", sample);
ES_Event_t ThisEvent;
ThisEvent.EventType = ES_COLLISION_DETECTED;
PostDisplayService(ThisEvent);
DB_printf("posted ES_COLLISION_DETECTED !!!\n");
ReturnVal = true;
LastCollisionTime = ES_Timer_GetTime();
sensorActive = false;
}
}
}
else
{
uint16_t timeInt = ES_Timer_GetTime() - LastCollisionTime;
uint16_t collisionDelay;
if (currentObstacleTick == OBSTACLE_FAST_TICK)
{
collisionDelay = COLLISION_DELAY_FAST;
}
else
{
collisionDelay = COLLISION_DELAY_SLOW;
}
// check obstacle every interval
if (timeInt > collisionDelay)
{
// DB_printf("reactivated");
sensorActive = true;
}
}
}
return ReturnVal;
}