µTasker Forum
µTasker Forum => µTasker general => Topic started by: Raffaele on September 13, 2020, 05:53:13 PM
-
Hi,
I'm trying to implement a state machine but I am having issues with the task.
I simply have two states: SLEEP and RX and I want to do
1) stay in SLEEP for T1 sec
2) after T1 sec go to RX
3) stay in RX for T2 sec (if something is received, aka interrupt on a pin, process data)
All these things work independently in my code. But I don't know how to properly activate the task
int const SLEEP = 1;
int const RX = 2;
extern void stateMachineTask(TTASKTABLE *ptrTaskTable){
switch (iState) {
case 0 :
steupIinterruptHandler();
iState = 1;
uTaskerMonoTimer('C', (DELAY_LIMIT) (0.5 * SEC), UTASKER_ACTIVATE);
break;
case SLEEP :
deactivate_data_processing();
// do sleep operations here
iState = RX;
uTaskerMonoTimer('C', (DELAY_LIMIT) (T1 * SEC), UTASKER_ACTIVATE);
break;
case RX :
activate_data_processing();
//if received interrupt, process data
iState = SLEEP;
uTaskerMonoTimer('C', (DELAY_LIMIT) (T2 * SEC), UTASKER_ACTIVATE);
break;
}
}
My major problem is that the interrupt is not triggered (it normally works). If I can suspend/resume the whole task that's fine too, but I don't know how to do it
-
Hi
I would use states and events to better control a state machine.
Could you try something like this?
// States
#define START_DELAY 1
#define SLEEP 1
#define RX 2
// Events
#define GO_TO_SLEEP 1
#define GO_TO_RX 2
#define MY_TASK 'C'
extern void stateMachineTask(TTASKTABLE *ptrTaskTable) {
static int iState = 0;
QUEUE_HANDLE PortIDInternal = ptrTaskTable->TaskID; // queue ID for task input
unsigned char ucInputMessage[HEADER_LENGTH]; // reserve space for receiving messages
int iEvent = 0;
if (fnRead(PortIDInternal, ucInputMessage, HEADER_LENGTH) == 0) { // check task input queue
iEvent = ucInputMessage[MSG_TIMER_EVENT];
}
switch (iState) {
case 0:
uTaskerMonoTimer(MY_TASK, (DELAY_LIMIT)(0.5 * SEC), GO_TO_RX);
iState = START_DELAY;
break;
case START_DELAY:
steupIinterruptHandler();
// Fall-though intentionally
//
case SLEEP:
if (iEvent == GO_TO_RX) {
activate_data_processing();
iState = RX;
uTaskerMonoTimer(MY_TASK, (DELAY_LIMIT)(T2 * SEC), GO_TO_SLEEP);
uTaskerStateChange(MY_TASK, UTASKER_ACTIVATE);
break;
}
// do sleep operations here
break;
case RX:
if (iEvent == GO_TO_SLEEP) {
deactivate_data_processing();
iState = SLEEP;
uTaskerMonoTimer(MY_TASK, (DELAY_LIMIT)(T1 * SEC), GO_TO_RX);
uTaskerStateChange(MY_TASK, UTASKER_ACTIVATE);
break;
}
// if received interrupt, process data
break;
}
}
Regards
Mark