Files
MMME3085_Lab_1/Lab_1/skeleton_programs/TestEncoder.ino
2023-10-12 17:26:07 +01:00

117 lines
3.0 KiB
C++

/* Test program for incremental encoder state machine code */
/* Serial input aspects are based closely upon:
http://forum.arduino.cc/index.php?topic=396450
Example 4 - Receive a number as text and convert it to an int
Modified to read a float */
long int count = 0;
long int error = 0;
enum states{state1=1, state2, state3, state4};
bool channelAState;
bool channelBState;
int state;
const byte numChars = 32;
char receivedChars[numChars]; // an array to store the received data
boolean newData = false;
void setup() {
Serial.begin(9600);
Serial.println("Enter initial state as a 2-digit number e.g. 01 then hit return");
do {
recvWithEndMarker();
} while (!newData);
channelAState = receivedChars[0]!='0';
channelBState = receivedChars[1]!='0';
initialiseEncoderStateMachine();
Serial.print(state);
Serial.print('\n');
Serial.println("Now keep entering state as a 2-digit number e.g. 01 then hit return.");
newData = false;
}
void loop() {
recvWithEndMarker();
if (newData)
{
channelAState = receivedChars[0]!='0';
channelBState = receivedChars[1]!='0';
updateEncoderStateMachine();
Serial.print("State: ");
Serial.print((int)state);
Serial.print(" Count: ");
Serial.print(count);
Serial.print(" Error: ");
Serial.print(error);
Serial.write('\n');
newData = false;
}
}
void recvWithEndMarker() {
static byte ndx = 0;
char endMarker = '\n';
char rc;
while (Serial.available() > 0 && newData == false) {
rc = Serial.read();
if (rc != endMarker) {
receivedChars[ndx] = rc;
ndx++;
if (ndx >= numChars) {
ndx = numChars - 1;
}
}
else {
receivedChars[ndx] = '\0'; // terminate the string
ndx = 0;
newData = true;
}
}
}
void initialiseEncoderStateMachine()
{
/* If initially A is 0 and B is 0, system starts in State 1
If initially A is 1 and B is 0, system starts in State 2
If initially A is 1 and B is 1, system starts in State 3
If initially A is 0 and B is 1, system starts in State 4 */
if (channelAState)
{
if(channelBState)
{
state = state3;
}
/* else .... lots of code goes here */
}
}
void updateEncoderStateMachine()
{
switch (state)
{
case state1:
/* If A is 0 and B is 0, do nothing and stay in State 1
If A is 1 and B is 0, add 1 to main counter and go to State 2
If A is 0 and B is 1, subtract 1 to main counter and go to State 4
If A is 1 and B is 1, do nothing to main counter but add 1 to error counter and go to state 3 */
if (channelAState && !channelBState)
{
count++;
state = state2;
}
/* else .... lots of code goes here */
break; /* don't forget break at the end of each case! */
/* other cases follow */
}
}