Anyone, any thoughts?
Why does the following code miss encoder pulses (as far as I can see, they are being missed only in one direction and fairly consistently):
/*
This program is reading an encoder with an Arduino DUE, calculates the corresponding distance
its cirumference travels and prints to serial interface. The code has a debounce which is added
to deal with possible imperfections of the input signal. Only if the signal stays there longer
than the set debounceDelay it is counted by the program.
*/
// Define the pins for the encoder
const int encoderPinA = 3;
const int encoderPinB = 4;
//Read the pines
#define readA digitalRead(encoderPinA)//faster than digitalRead()
#define readB digitalRead(encoderPinB)//faster than digitalRead()
// Variables for encoder state and distance
volatile bool lastStateA = LOW;
volatile bool lastStateB = LOW;
volatile long encoderCount = 0;
volatile long myCount = 0;
const int countsPerRevolution = 2000; // Counts per revolution of the encoder
const float encoderDiameter = 11.021;//11.07; // Diameter of the encoder in millimeters
float lastDistanceTraveled = 0; // Last distance traveled by the encoder's circumference
float totalDistanceTraveled = 0; // Total distance traveled by the encoder's circumference
const unsigned long debounceDelay = 10; // Adjust as needed (microseconds)
// Variables for printing to serial port conditions
unsigned long lastEncoderChangeTime = 0; // Time of the last encoder count change
unsigned long lastPrintTime = 200; // Time of the last print to serial monitor
// Setup function
void setup() {
// Initialize serial communication
Serial.begin(9600);
// Set encoder pins as inputs
pinMode(encoderPinA, INPUT);
pinMode(encoderPinB, INPUT);
// Set output HIGH pins for using with external pull-up resistors
pinMode(8, OUTPUT);
pinMode(9, OUTPUT);
digitalWrite(8, HIGH);
digitalWrite(9, HIGH);
// Attach interrupts to the encoder pins
attachInterrupt(digitalPinToInterrupt(encoderPinA), readEncoder1, CHANGE);
attachInterrupt(digitalPinToInterrupt(encoderPinB), readEncoder2, CHANGE);
}
// Function to read the encoder
void readEncoder1() {
// Update the encoder count based on the direction of rotation
if (readB != readA) {
encoderCount++;
} else {
encoderCount--;
}
// Update the time of the last encoder count change
lastEncoderChangeTime = millis();
}
void readEncoder2() {
// Update the encoder count based on the direction of rotation
if (readA == readB) {
encoderCount++;
} else {
encoderCount--;
}
// Update the time of the last encoder count change
lastEncoderChangeTime = millis();
}
// Main loop
void loop() {
//Reset the distance upon any input from the serial port
if (Serial.available()){
Serial.read();
encoderCount = 0;
}
// Calculate distance traveled based on encoder counts and diameter
float circumference = PI * encoderDiameter; // Calculate circumference
float distance = ((encoderCount) * circumference) / (countsPerRevolution); // Calculate distance
// Update total distance traveled
totalDistanceTraveled = distance;
// Check conditions for printing to serial port
unsigned long currentTime = millis();
if ((currentTime - lastEncoderChangeTime >= 500) && (totalDistanceTraveled != lastDistanceTraveled) && (currentTime - lastPrintTime >= 100)) {
// Print distance traveled to serial monitor
Serial.print(totalDistanceTraveled);
Serial.print(", EncoderCount: ");
Serial.println(encoderCount);
// Update last printed distance and time values
lastDistanceTraveled = totalDistanceTraveled;
lastPrintTime = currentTime;
}
}