From a911d97781b2969fee4948349310950bf2318027 Mon Sep 17 00:00:00 2001 From: Alvie Rahman Date: Thu, 12 Oct 2023 18:43:11 +0100 Subject: [PATCH] add TestEncoderAAR.c --- Lab_1/TestEncoderAAR.c | 121 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 121 insertions(+) create mode 100644 Lab_1/TestEncoderAAR.c diff --git a/Lab_1/TestEncoderAAR.c b/Lab_1/TestEncoderAAR.c new file mode 100644 index 0000000..21f380a --- /dev/null +++ b/Lab_1/TestEncoderAAR.c @@ -0,0 +1,121 @@ +#include +#include +#include +#define bool int +#define byte unsigned char +#define numChars 32 + +// Here we are using global variables simply to be compatible with the Arduino program structure +// This is REALLY bad practice so please don't do it otherwise! +long int count = 0; +long int error = 0; + +enum states {state1=1, state2, state3, state4}; +bool channelAState=0; +bool channelBState=0; + +enum states state; +char receivedChars[numChars]="00"; // an array to store the received data + +void initialiseEncoderStateMachine(); +void updateEncoderStateMachine(); +enum states get_state(); + +int main() +{ + // Replicates the setup in Arduino + printf("Enter a pair of characters representing initial states of channels A and B\n"); + scanf("%s",receivedChars); + channelAState = receivedChars[0]!='0'; + channelBState = receivedChars[1]!='0'; + + initialiseEncoderStateMachine(); + printf("State %d, count %ld, error %ld\n", state, count, error); + printf("Enter a pair of characters representing channels A and B, enter 99 to end\n"); + + // Replicates the loop in Arduino + do + { + scanf("%s",receivedChars); + if (strcmp(receivedChars, "99")==0) + { + break; + } + channelAState = receivedChars[0]!='0'; + channelBState = receivedChars[1]!='0'; + updateEncoderStateMachine(); + printf("State %d, count %ld, error %ld\n", state, count, error); + + } + while(1); + return 0; +} + + +enum states get_state() +{ + /* If A is 0 and B is 0, system is in State 1 + If A is 1 and B is 0, system is in State 2 + If A is 1 and B is 1, system is in State 3 + If A is 0 and B is 1, system is in State 4 */ + + if (channelAState && channelBState) return state3; + if (channelAState && (!channelBState)) return state2; + if ((!channelAState) && channelBState) return state4; + if ((!channelAState) && (!channelBState)) return state1; + + return state1; // silences clang-diagnostic-return-type warning +} + + +void initialiseEncoderStateMachine() +{ + state = get_state(); +} + + +void updateEncoderStateMachine() +{ + enum states new_state = get_state(); // get new state, don't update state yet so states can be compared + + switch (state) + { + case state1: + // check new state is valid, coming from state1, increment error count if not + // adjust count as appropriate if new state is valid + switch (new_state) { + case state1: break; + case state2: count++; break; + case state3: error++; break; + case state4: count--; break; + } + + break; + case state2: + switch (new_state) { + case state1: count--; break; + case state2: break; + case state3: count++; break; + case state4: error++; break; + } + break; + case state3: + switch (new_state) { + case state1: error++; break; + case state2: count--; break; + case state3: break; + case state4: count++; break; + } + break; + case state4: + switch (new_state) { + case state1: count++; break; + case state2: error++; break; + case state3: count--; break; + case state4: break; + } + break; + } + + state = new_state; // set new state +}