I am using a 4wd robotic car to measure straight distances. I have attached two encoders on the front two wheels to measure the distance and I am using the back two wheels to adjust the car and keep it driving straight by using a compass as a reference. The Problem is that when my program is executing the section that drives the back wheels this somehow triggers the interrupt and increments the number of ticks. What is causing this issue?
volatile unsigned long enc_l = 0;
volatile unsigned long enc_r = 0;
void driveStraight(float drive_distance, int motor_power)
{
Serial.print("\n");
Serial.println("num_tick_l \t num_tick_r \t diff_l \t diff_r \t enc_1_prev \t enc_r_prev \t Power_l \t Power_r \t Power_a \t Power_b ");
unsigned long num_ticks_l;
unsigned long num_ticks_r;
// Set initial motor power
int power_l = motor_power;
int power_r = motor_power;
// Used to determine which way to turn to adjust
unsigned long diff_l;
unsigned long diff_r;
// Reset encoder counts
enc_l = 0;
enc_r = 0;
// Remember previous encoder counts
unsigned long enc_l_prev = enc_l;
unsigned long enc_r_prev = enc_r;
// Calculate targer number of ticks
float num_rev = (drive_distance * 10) / wheel_c; // Convert to mm
unsigned long target_count = 29; //num_rev * counts_per_rev;
/*
// Debug
Serial.print("Driving for ");
Serial.print(drive_distance);
Serial.print(" cm(");
Serial.print(target_count);
Serial.print(" ticks) at ");
Serial.print(motor_power);
Serial.println(" Motor Power");
*/
//Drive until on of the encoders reaches desired count
while ((enc_l < target_count) && (enc_r < target_count))
{
bluetooth(); // if new bluetooth value received break from loop
if (blueToothVal == 5) {
break; // If a 'Stop' Bluetooth command is received then break from the Loop
}
// Sample number of encoder ticks
num_ticks_l = enc_l;
num_ticks_r = enc_r;
// Sample out current number of ticks
Serial.print(num_ticks_l);
Serial.print(" \t\t");
Serial.print(num_ticks_r);
// Drive
drive(power_l, power_r);
// Number of ticks counted since last time
const int StraightDriveOffset = 1; // Increase this or even make it a negatie number to tweak the
diff_l = num_ticks_l - enc_l_prev; // + StraightDriveOffset;
diff_r = num_ticks_r - enc_r_prev;
Serial.print(" \t\t");
Serial.print(diff_l);
Serial.print(" \t \t");
Serial.print(diff_r);
// Store current ticks counter for next time
enc_l_prev = num_ticks_l;
enc_r_prev = num_ticks_r;
Serial.print(" \t \t");
Serial.print(enc_l_prev);
Serial.print(" \t \t");
Serial.print(enc_r_prev);
// If left is faster, slow it down and speed up right
if ( diff_l > diff_r) {
power_l -= motor_offset;
power_r += motor_offset;
}
// If right is faster, slow it down and speed up right
if ( diff_l < diff_r) {
power_l += motor_offset;
power_r -= motor_offset;
}
// Debugging
Serial.print(" \t\t");
Serial.print(power_l);
Serial.print(" \t\t");
Serial.println(power_r);
// Brif pause to let motors respond
delay(20);
}
StopCar();
//Buzzer();
}
void drive(int power_a, int power_b)
{
getCompass(); // Update Compass Heading
bluetooth(); // Check to see if any Bluetooth commands have been sent
if (blueToothVal == 5) {
break; // If a Stop Bluetooth command ('5') is received then break from the Loop
}
// Constrain power to between -255 and 255
power_a = constrain(power_a, -255, 255);
power_b = constrain(power_b, -255, 255);
if ( abs(desired_heading - compass_heading) <= compass_dev ) // If the Desired Heading and the Compass Heading are within the compass deviation, X degrees of each other then Go Forward
// otherwise find the shortest turn radius and turn left or right
{
// Left motor direction
if ( power_a < 0)
{
motor2.setSpeed(abs(power_a)); // Motor is the front left wheel
motor2.run(BACKWARD);
}
else
{
motor2.setSpeed(abs(power_a)); // Motor is the front left wheel
motor2.run(FORWARD);
}
// Right Motor direction
if ( power_b < 0)
{
motor4.setSpeed(abs(power_b)); // Motor is the front left wheel
motor4.run(BACKWARD);
}
else
{
motor4.setSpeed(abs(power_b)); // Motor is the front left wheel
motor4.run(FORWARD);
}
}
else
{
int x = (desired_heading - 359); // x = the GPS desired heading - 360
int y = (compass_heading - (x)); // y = the Compass heading - x
int z = (y - 360); // z = y - 360
if ((z <= 180) && (z >= 0)) // if z is less than 180 and not a negative value then turn left
{ // otherwise turn right
motor1.setSpeed(190);
motor3.setSpeed(190);
motor1.run(BACKWARD);
motor3.run(FORWARD);
}
else
{
motor1.setSpeed(190);
motor3.setSpeed(190);
motor1.run(FORWARD);
motor3.run(BACKWARD);
}
}
}
void countLeft()
{
enc_l ++;
}
void countRight()
{
enc_r ++;
}
and this is what is on the setup function
const int enc_l_pin = 18;
const int enc_r_pin = 19;
void setup()
{
Serial.begin(115200); // Serial 0 is for communication with the computer
Serial3.begin(9600); // Serial 1 is for Bluetooth communication - DO NOT MODIFY - JY-MCU HC-06 v1.40
Wire.begin(); // Join I2C bus used for the HMC5883L compass
compass.begin(); // initialize the compass (HMC5883L)
compass.setRange(HMC5883L_RANGE_1_3GA); // Set measurement range
compass.setMeasurementMode(HMC5883L_CONTINOUS); // Set measurement mode
compass.setDataRate(HMC5883L_DATARATE_30HZ); // Set data rate
compass.setSamples(HMC5883L_SAMPLES_8); // Set number of samples averaged
compass.setOffset(118, 473); // Set calibration offset
// Buzzer
pinMode(Buzzer_pin, OUTPUT);
// Set up pins
pinMode(enc_l_pin, INPUT);
pinMode(enc_r_pin, INPUT);
// Set up interrupts
attachInterrupt(digitalPinToInterrupt(enc_l_pin), countLeft, CHANGE);
attachInterrupt(digitalPinToInterrupt(enc_r_pin), countRight, CHANGE);