Motors Not Responding Properly with AFMotor Library (Arduino Uno + Motor Shield)

Hello, this is one of my first projects with Arduino.

The issue:

  • Initially, only M3 and M4 were spinning.
  • After a few tweaks (such as running a blink test), M1 started spinning, but M4 stopped working.
  • Now, none of the motors are spinning, even when using test code or direct commands through the AFMotor library.

What I’ve Tried

  1. Hardware Tests:
  • Verified motors work independently by powering them directly from a battery.
  • Checked all motor connections to the shield and ensured the wires are secure.
  • Ensured the motor shield is seated properly on the Arduino and powered adequately.
  1. Power Supply:
  • Using a separate external power supply for the motors (6x AA battery pack).
  • Confirmed the voltage is within the expected range.
  1. Library and Code:
  • Tested with a simple sketch using the AFMotor library (e.g., one motor running forward).
  • Tried basic examples from the library with no success.
  1. Reset and Re-Test:
  • Reset both the Arduino and motor shield.
  • Ran a “blink test” (toggling pin states on the motor shield), which worked at one point but now seems to have no effect.
  1. Motor Shield:
  • Inspected for loose solder joints or damage—everything looks fine visually.

Here is my code:

#include <AFMotor.h>
#include <IRremote.h>
#include <Servo.h>

// Pin Assignments
const int IR_RECEIVER_PIN = A5;  // IR receiver connected to A5

// Motor Setup using AFMotor
AF_DCMotor motor1(1); // Left Front Motor
AF_DCMotor motor2(2); // Left Rear Motor
AF_DCMotor motor3(3); // Right Front Motor
AF_DCMotor motor4(4); // Right Rear Motor

// Ultrasonic Sensor Pins
const int TRIG_PIN = A0;  // Ultrasonic sensor TRIG pin
const int ECHO_PIN = A1;  // Ultrasonic sensor ECHO pin

// Servo Pin
const int SERVO_PIN = 12;  // Servo motor for ultrasonic rotation

// Signal Strength Thresholds
const int STRONG_SIGNAL_THRESHOLD = 200;  // Strong signal (near the IR beacon)
const int WEAK_SIGNAL_THRESHOLD = 50;     // Weak signal (far from IR beacon)

// Obstacle Detection Threshold (in cm)
const int OBSTACLE_DISTANCE = 15;  // Stop if an obstacle is within 15 cm

// IR Receiver Setup
IRrecv irrecv(IR_RECEIVER_PIN);  // Define IR receiver object
decode_results results;          // Variable to store IR data

// Servo setup
Servo ultrasonicServo;


// Motor Pins
const int motor1Pin1 = 3;  // Motor 1 forward
const int motor1Pin2 = 4;  // Motor 1 backward
const int motor2Pin1 = 5;  // Motor 2 forward
const int motor2Pin2 = 6;  // Motor 2 backward


void testMotors() {
  pinMode(motor1Pin1, OUTPUT);
  pinMode(motor1Pin2, OUTPUT);
  pinMode(motor2Pin1, OUTPUT);
  pinMode(motor2Pin2, OUTPUT);
  
  // Test Motor 1 and Motor 2
  Serial.begin(9600);
  Serial.println("Testing Motors...");
  
  // Forward direction for Motor 1
  digitalWrite(motor1Pin1, HIGH);
  digitalWrite(motor1Pin2, LOW);
  delay(1000); // Run Motor 1 for 1 second
  
  // Forward direction for Motor 2
  digitalWrite(motor2Pin1, HIGH);
  digitalWrite(motor2Pin2, LOW);
  delay(1000); // Run Motor 2 for 1 second
  
  // Stop motors
  digitalWrite(motor1Pin1, LOW);
  digitalWrite(motor1Pin2, LOW);
  digitalWrite(motor2Pin1, LOW);
  digitalWrite(motor2Pin2, LOW);
  
  Serial.println("Motors stopped");
}

void setup() {
  Serial.begin(9600);
  Serial.println("Initializing...");
  
  // Ultrasonic Sensor Pins Setup
  pinMode(TRIG_PIN, OUTPUT);
  pinMode(ECHO_PIN, INPUT);

  // Servo Setup
  ultrasonicServo.attach(SERVO_PIN);

  // Start IR Receiver
  irrecv.enableIRIn();  // Initialize IR receiver

  // Center servo initially
  ultrasonicServo.write(90);

  testMotors();  // Test Motors
  
  Serial.println("Setup complete.");
}

// Obstacle Avoidance Logic
void avoidObstacle() {
  // Move backward briefly
  moveBackward();
  delay(500);  // Adjust as needed
  stopMotors();

  // Look left
  ultrasonicServo.write(45);  // Rotate servo left
  delay(500);  // Allow time for servo to rotate
  int leftDistance = measureDistance();

  // Look right
  ultrasonicServo.write(135);  // Rotate servo right
  delay(500);  // Allow time for servo to rotate
  int rightDistance = measureDistance();

  // Center the servo again
  ultrasonicServo.write(90);
  delay(500);

  // Decide direction based on more space
  if (leftDistance > rightDistance) {
    turnLeft();
    Serial.println("Turning left...");
  } else {
    turnRight();
    Serial.println("Turning right...");
  }

  // Move forward again
  moveForward();
  delay(1000);  // Adjust as needed
  stopMotors();
}

// Ultrasonic Sensor Function to Detect Obstacles
bool isObstacleDetected() {
  int distance = measureDistance();

  // Debug: Print distance
  Serial.print("Distance: ");
  Serial.print(distance);
  Serial.println(" cm");

  // Return true if the obstacle is within the defined threshold
  return (distance > 0 && distance <= OBSTACLE_DISTANCE);
}

// Measure Distance Function
int measureDistance() {
  // Send ultrasonic pulse
  digitalWrite(TRIG_PIN, LOW);
  delayMicroseconds(2);
  digitalWrite(TRIG_PIN, HIGH);
  delayMicroseconds(10);
  digitalWrite(TRIG_PIN, LOW);

  // Measure pulse duration
  long duration = pulseIn(ECHO_PIN, HIGH);

  // Convert duration to distance in cm
  int distance = duration * 0.034 / 2;
  return distance;
}

void moveForward() {
  Serial.println("Attempting to move motors forward...");

  motor1.setSpeed(255); 
  motor1.run(FORWARD);
  Serial.println("Motor 1: FORWARD");

  motor2.setSpeed(255); 
  motor2.run(FORWARD);
  Serial.println("Motor 2: FORWARD");

  motor3.setSpeed(255); 
  motor3.run(FORWARD);
  Serial.println("Motor 3: FORWARD");

  motor4.setSpeed(255); 
  motor4.run(FORWARD);
  Serial.println("Motor 4: FORWARD");
}


void moveBackward() {
  Serial.println("Attempting to move motors backward...");

  motor1.setSpeed(255); 
  motor1.run(BACKWARD);
  Serial.println("Motor 1: BACKWARD");

  motor2.setSpeed(255); 
  motor2.run(BACKWARD);
  Serial.println("Motor 2: BACKWARD");

  motor3.setSpeed(255); 
  motor3.run(BACKWARD);
  Serial.println("Motor 3: BACKWARD");

  motor4.setSpeed(255); 
  motor4.run(BACKWARD);
  Serial.println("Motor 4: BACKWARD");
}


void turnLeft() {
  Serial.println("Attempting to turn left...");

  motor1.setSpeed(255); 
  motor1.run(BACKWARD); // Left motors backward
  Serial.println("Motor 1: BACKWARD");

  motor2.setSpeed(255); 
  motor2.run(BACKWARD); // Left motors backward
  Serial.println("Motor 2: BACKWARD");

  motor3.setSpeed(255); 
  motor3.run(FORWARD);  // Right motors forward
  Serial.println("Motor 3: FORWARD");

  motor4.setSpeed(255); 
  motor4.run(FORWARD);  // Right motors forward
  Serial.println("Motor 4: FORWARD");
}


void turnRight() {
  Serial.println("Attempting to turn right...");

  motor1.setSpeed(255); 
  motor1.run(FORWARD);  // Left motors forward
  Serial.println("Motor 1: FORWARD");

  motor2.setSpeed(255); 
  motor2.run(FORWARD);  // Left motors forward
  Serial.println("Motor 2: FORWARD");

  motor3.setSpeed(255); 
  motor3.run(BACKWARD); // Right motors backward
  Serial.println("Motor 3: BACKWARD");

  motor4.setSpeed(255); 
  motor4.run(BACKWARD); // Right motors backward
  Serial.println("Motor 4: BACKWARD");
}


void stopMotors() {
  motor1.run(RELEASE);  
  motor2.run(RELEASE);  
  motor3.run(RELEASE);  
  motor4.run(RELEASE);  
  Serial.println("All motors stopped");
}


void adjustDirection() {
  if (irrecv.decode(&results)) {
    long irSignalStrength = results.value;  // Get the actual signal strength
    
    Serial.print("Signal Strength: ");
    Serial.println(irSignalStrength);

    if (irSignalStrength > STRONG_SIGNAL_THRESHOLD) {
      // Move towards the beacon (signal is strong)
      moveForward();
    } else if (irSignalStrength < WEAK_SIGNAL_THRESHOLD) {
      // Signal is weak, adjust direction to find stronger signal
      turnLeft();
      delay(1000);  // Adjust the amount of time based on testing
      turnRight();
      delay(1000);
    } else {
      // Stop if no signal is detected
      stopMotors();
    }
    irrecv.resume();  // Resume IR receiver
  }
}

void loop() {
  // Check for obstacles
  if (isObstacleDetected()) {
    Serial.println("Obstacle detected, avoiding...");
    avoidObstacle();
  } else {
    // IR Signal Following Logic
    adjustDirection();
  }
}

Also, the serial monitor shows that it is getting the commands.


I am also very sure that there is no hardware issue because I have ran multiple tests. I believe there is a problem with the code.

Long story short:

The AFMotor library uses both timers 1 & 2.

IRremote needs to use either timer 1, or timer 2.

They cannot share.

The solution is to use a motor shield that isn't a cheap clone of something Adafruit discontinued over a decade ago. Use the current shield, that's supported, doesn't use any timers, and doesn't use any pins other than the I2C bus.

Thanks for the insight! Actually, I'm not using the Adafruit motor shield. I'm using an L293D motor driver shield. Do you think that could be part of the issue, or is there something in the configuration I should check with this setup? I’m using the AFMotor library for motor control, and the IRremote library for IR communication. Any additional guidance would be really helpful!

The motor shield you are using is a cheap clone of the v1 Adafruit Motor Shield, which was discontinued over a decade ago by Adafruit. Cheap clones continue to abound because well, they're cheap, and people keep buying them. It uses timers 1 and 2. IRremote needs one of them for itself. That is the issue. Use the v2 shield. Or don't. It's your choice.

Here is a link to the v1 shield that you're using a clone of:

Thanks for the clarification! I see now that the L293D shield is causing conflicts with the timers. I’m planning to get the V2 shield as recommended. In the meantime, is there anything I should change in my code to ensure it works well with the V2 shield once I get it, or would it just work as-is with the V2? Also, does the V2 shield control 4 DC motors or just 2? Any additional tips would be appreciated!

Adafruit does a wonderful job of supporting their products. Perhaps you should read their tutorial on the v2 motor shield.

Is there anything I should change in my code to ensure it works well with the V2 shield once I get it, or would it just work as-is with the V2?

Read the tutorial. Look at the library for the v2 board. Look at the examples.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.