#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 }