I’m working on creating a two wheeled robot, utilizing wheel encoders for rotation and distance measurement. When using attachInterrupt(), however, the ISR (function that activates when the pin is interrupted) is never called. Despite this, using digitalRead()on the same pin in the loop()clearly shows that the state is changing, and it has been my alternative for now. My full code is below. Any help is appreciated!
// Pin assignments for motor control
const byte RForward = 12;
const byte RBackward = 11;
const byte LForward = 10;
const byte LBackward = 9;
// Pins for speed control
const byte RSpeed = 3;
const byte LSpeed = 6;
// Pins for wheel encoders
const byte RIntterupt = 7;
const byte LInterrupt = 2;
// Variables to store encoder counts
volatile int leftInterruptCount = 0;
volatile int rightInterruptCount = 0;
// Constants for encoder and robot measurements
const int interruptsPerRotation = 23; // Number of encoder ticks per wheel revolution
const float wheelDiameter = 65.0;
const float wheelBase = 150.0; // Distance between the two wheels
const float wheelCircumference = PI * wheelDiameter;
// How many encoder counts before stopping the robot
const int motorStopValue = 100;
byte originalValue = 0;
void setup() {
// Set motor control pins as outputs
pinMode(RForward, OUTPUT);
pinMode(RBackward, OUTPUT);
pinMode(LForward, OUTPUT);
pinMode(LBackward, OUTPUT);
// Attach interrupts for the encoders
// Each time a falling/rising edge is detected, the count function will run
pinMode(LInterrupt, INPUT);
attachInterrupt(digitalPinToInterrupt(LInterrupt), countLeft, CHANGE);
// Start serial communication for debugging
Serial.begin(9600);
Serial.println("Started");
originalValue = digitalRead(LInterrupt);
}
// Interrupt service routine for left wheel encoder
void countLeft() {
Serial.flush();
Serial.println("Counted left");
leftInterruptCount++;
}
// Interrupt service routine for right wheel encoder
void countRight() {
rightInterruptCount++;
}
// Function to calculate and print motion data
// This determines how many wheel revolutions have occurred,
// how far each wheel has traveled, and how much the robot has turned.
void calculateMotion() {
// Calculate number of revolutions for each wheel
float leftRevs = (float)leftInterruptCount / interruptsPerRotation;
float rightRevs = (float)rightInterruptCount / interruptsPerRotation;
// Calculate distance traveled by each wheel
float leftDistance = leftRevs * wheelCircumference;
float rightDistance = rightRevs * wheelCircumference;
// Calculate the difference in distance traveled between the two wheels
float distanceDiff = rightDistance - leftDistance;
// Calculate how much the robot has turned, in degrees
float turnDegrees = (distanceDiff / wheelBase) * (180.0 / PI);
// Print all the calculated information to the serial monitor
Serial.println("----- Motion Data -----");
Serial.print("Left revolutions: ");
Serial.println(leftRevs, 3);
Serial.print("Right revolutions: ");
Serial.println(rightRevs, 3);
Serial.print("Left distance (mm): ");
Serial.println(leftDistance, 2);
Serial.print("Right distance (mm): ");
Serial.println(rightDistance, 2);
Serial.print("Estimated turn (degrees): ");
Serial.println(turnDegrees, 2);
Serial.println("-----------------------");
}
void loop() {
// byte value = digitalRead(LInterrupt);
// if (value != originalValue) {
// originalValue = value;
// leftInterruptCount++;
// Serial.flush();
// Serial.println("Changed");
// }
// Run the motors forward until the left wheel reaches a set number of encoder counts
if (leftInterruptCount >= motorStopValue) {
// Stop both motors
digitalWrite(RForward, LOW);
digitalWrite(RBackward, LOW);
digitalWrite(LForward, LOW);
digitalWrite(LBackward, LOW);
Serial.println("Stopped");
// Once stopped, calculate and display motion data
calculateMotion();
// Stop the program from looping further
while (true);
} else {
// Move both motors forward
digitalWrite(RForward, HIGH);
digitalWrite(RBackward, LOW);
digitalWrite(LForward, HIGH);
digitalWrite(LBackward, LOW);
// analogWrite(RSpeed, 100);
analogWrite(LSpeed, 255);
}
}