When I run the code below and open and close the Serial Monitor. The _LeftEncoderTicks variable will become unpredictable. Sometimes it returns to zero, sometimes it stays the same and other times it will jump to a random number.
I am not stopping the code. Just opening and closing the Serial Monitor window. The funny thing is that when I start the Serial Monitor, it prints 0’s and as soon as I move the encoder, it jumps to the higher different numbers.
/*
*Quadrature Decoder
*/
#include "Arduino.h"
#include <digitalWriteFast.h> // library for high performance reads and writes by jrraines
// see http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1267553811/0
// and http://code.google.com/p/digitalwritefast/
// It turns out that the regular digitalRead() calls are too slow and bring the arduino down when
// I use them in the interrupt routines while the motor runs at full speed.
// Quadrature encoders
// Left encoder
#define c_LeftEncoderInterruptA 0
#define c_LeftEncoderInterruptB 1
#define c_LeftEncoderPinA 2
#define c_LeftEncoderPinB 3
#define LeftEncoderIsReversed
volatile bool _LeftEncoderASet;
volatile bool _LeftEncoderBSet;
volatile bool _LeftEncoderAPrev;
volatile bool _LeftEncoderBPrev;
volatile long _LeftEncoderTicks = 0;
void setup()
{
Serial.begin(9600);
// Quadrature encoders
// Left encoder
pinMode(c_LeftEncoderPinA, INPUT_PULLUP); // sets pin A as input
// digitalWrite(c_LeftEncoderPinA, LOW); // turn on pullup resistors
pinMode(c_LeftEncoderPinB, INPUT_PULLUP); // sets pin B as input
// digitalWrite(c_LeftEncoderPinB, LOW); // turn on pullup resistors
attachInterrupt(c_LeftEncoderInterruptA, HandleLeftMotorInterruptA, CHANGE);
attachInterrupt(c_LeftEncoderInterruptB, HandleLeftMotorInterruptB, CHANGE);
_LeftEncoderTicks = 0;
}
void loop()
{
Serial.print("Encoder Ticks: ");
Serial.print(_LeftEncoderTicks);
Serial.print(" Revolutions: ");
Serial.print(_LeftEncoderTicks/1440.00);//4000 Counts Per Revolution
Serial.print("\n");
}
// Interrupt service routines for the left motor's quadrature encoder
void HandleLeftMotorInterruptA(){
_LeftEncoderBSet = digitalReadFast(c_LeftEncoderPinB);
_LeftEncoderASet = digitalReadFast(c_LeftEncoderPinA);
_LeftEncoderTicks+=ParseEncoder();
_LeftEncoderAPrev = _LeftEncoderASet;
_LeftEncoderBPrev = _LeftEncoderBSet;
}
// Interrupt service routines for the right motor's quadrature encoder
void HandleLeftMotorInterruptB(){
// Test transition;
_LeftEncoderBSet = digitalReadFast(c_LeftEncoderPinB);
_LeftEncoderASet = digitalReadFast(c_LeftEncoderPinA);
_LeftEncoderTicks+=ParseEncoder();
_LeftEncoderAPrev = _LeftEncoderASet;
_LeftEncoderBPrev = _LeftEncoderBSet;
}
int ParseEncoder(){
if(_LeftEncoderAPrev && _LeftEncoderBPrev){
if(!_LeftEncoderASet && _LeftEncoderBSet) return 1;
if(_LeftEncoderASet && !_LeftEncoderBSet) return -1;
}else if(!_LeftEncoderAPrev && _LeftEncoderBPrev){
if(!_LeftEncoderASet && !_LeftEncoderBSet) return 1;
if(_LeftEncoderASet && _LeftEncoderBSet) return -1;
}else if(!_LeftEncoderAPrev && !_LeftEncoderBPrev){
if(_LeftEncoderASet && !_LeftEncoderBSet) return 1;
if(!_LeftEncoderASet && _LeftEncoderBSet) return -1;
}else if(_LeftEncoderAPrev && !_LeftEncoderBPrev){
if(_LeftEncoderASet && _LeftEncoderBSet) return 1;
if(!_LeftEncoderASet && !_LeftEncoderBSet) return -1;
}
}