117 lines
3.0 KiB
C++
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 */
|
|
}
|
|
}
|
|
|
|
|