Hi, I have another question. I'm having a strange issue where my Motor 3 is acting odd. It is moving forward delayed and isn't moving backwards. I don't think its a hardware issue. I used a different motor driver, and then the motor worked perfectly fine when I ran my test code. However, my main code is where it went wrong and I didn't change anything hardware-wise from running my test code to my main code. I also used a different motor to test. Does anyone know what could be the problem?
Main code (doesn't work):
#include <IRremote.hpp>
#include <Servo.h>
// Motor Driver Pins (L298N)
int IN1_1 = 6; // Motor 1 direction control
int IN2_1 = 7; // Motor 1 direction control
int IN3_1 = 8; // Motor 2 direction control
int IN4_1 = 9; // Motor 2 direction control
int IN1_2 = 12; // Motor 3 direction control
int IN2_2 = 13; // Motor 3 direction control
int IN3_2 = 4; // Motor 4 direction control
int IN4_2 = 2; // Motor 4 direction control
const int IR_RECEIVER_PIN = A2;
const int TRIG_PIN = A0;
const int ECHO_PIN = A1;
const int SERVO_PIN = A3;
// Obstacle Detection Threshold
const int OBSTACLE_DISTANCE = 15; // Stop if an obstacle is within 15 cm
// Signal Thresholds
const int STRONG_SIGNAL_THRESHOLD = 1000;
const int WEAK_SIGNAL_THRESHOLD = 200;
// Servo setup
Servo ultrasonicServo;
// Flag to track turning state
bool isTurning = false;
// Function Prototypes
void testMotors();
bool isObstacleDetected();
int measureDistance();
void avoidObstacle();
void adjustDirection();
void moveForward();
void moveBackward();
void turnLeft();
void turnRight();
void stopMotors();
void setup() {
Serial.begin(9600);
Serial.println("Initializing...");
// Motor Driver Pins Setup
pinMode(IN1_1, OUTPUT);
pinMode(IN2_1, OUTPUT);
pinMode(IN3_1, OUTPUT);
pinMode(IN4_1, OUTPUT);
pinMode(IN1_2, OUTPUT);
pinMode(IN2_2, OUTPUT);
pinMode(IN3_2, OUTPUT);
pinMode(IN4_2, OUTPUT);
// Ultrasonic Sensor Setup
pinMode(TRIG_PIN, OUTPUT);
pinMode(ECHO_PIN, INPUT);
// Servo Setup
ultrasonicServo.attach(SERVO_PIN);
ultrasonicServo.write(90); // Center servo initially
// IR Receiver Setup
IrReceiver.begin(IR_RECEIVER_PIN, ENABLE_LED_FEEDBACK); // Start IR receiver with feedback LED
// Test motors
testMotors();
testRightFrontMotor();
Serial.println("Setup complete.");
}
void loop() {
// Check for obstacles first
if (isObstacleDetected()) {
Serial.println("Obstacle detected. Avoiding...");
avoidObstacle();
} else {
// If no obstacle, adjust direction based on IR signals
adjustDirection();
}
delay(50); // Minimize delay to improve responsiveness
}
void testMotors() {
digitalWrite(IN1_1, HIGH);
digitalWrite(IN2_1, LOW);
digitalWrite(IN3_1, HIGH);
digitalWrite(IN4_1, LOW);
digitalWrite(IN1_2, HIGH);
digitalWrite(IN2_2, LOW);
digitalWrite(IN3_2, HIGH);
digitalWrite(IN4_2, LOW);
delay(500);
stopMotors();
}
void testRightFrontMotor() {
digitalWrite(IN1_1, HIGH); // Set direction to forward
digitalWrite(IN2_1, LOW);
digitalWrite(IN3_1, HIGH); // Enable motor
digitalWrite(IN4_1, LOW);
delay(1000); // Run for 1 second
digitalWrite(IN3_1, LOW); // Stop motor
digitalWrite(IN4_1, LOW);
}
bool isObstacleDetected() {
int distance = measureDistance();
if (distance == -1) return false; // Ignore invalid distances
Serial.print("Obstacle Distance: ");
Serial.println(distance);
return (distance <= OBSTACLE_DISTANCE);
}
int measureDistance() {
digitalWrite(TRIG_PIN, LOW);
delayMicroseconds(2);
digitalWrite(TRIG_PIN, HIGH);
delayMicroseconds(10);
digitalWrite(TRIG_PIN, LOW);
long duration = pulseIn(ECHO_PIN, HIGH, 30000); // Timeout in 30ms
int distance = duration * 0.034 / 2; // Convert to cm
Serial.print("Measured Distance: ");
Serial.println(distance);
if (distance <= 0 || distance > 400) {
return -1; // Invalid distance
}
return distance;
}
void avoidObstacle() {
stopMotors(); // Explicitly stop motors
moveBackward();
delay(500); // Move back a little
stopMotors(); // Ensure the robot stops before turning
ultrasonicServo.write(45);
delay(600); // Wait for servo to stabilize
int leftDistance = measureDistance();
ultrasonicServo.write(135);
delay(600);
int rightDistance = measureDistance();
ultrasonicServo.write(90); // Center the servo
delay(600);
// Turn towards the side with more space
if (leftDistance > rightDistance) {
turnLeft();
Serial.println("Turn left");
} else {
turnRight();
Serial.println("Turn right");
}
// Move forward after turning
moveForward();
delay(1000);
stopMotors();
}
void adjustDirection() {
static unsigned long lastSignalTime = 0; // Track time of last signal
static bool isMoving = false;
unsigned long irSignal = 0; // Declare irSignal outside the if block
if (IrReceiver.decode()) { // If a signal is received
irSignal = IrReceiver.decodedIRData.decodedRawData;
if (irSignal == 0) {
Serial.println("Invalid IR signal, ignoring...");
IrReceiver.resume();
return;
}
Serial.print("Received IR signal: ");
Serial.println(irSignal, HEX);
IrReceiver.resume();
if (irSignal >= STRONG_SIGNAL_THRESHOLD) {
// Strong signal: move forward
moveForward();
isMoving = true;
} else if (irSignal < STRONG_SIGNAL_THRESHOLD && irSignal > WEAK_SIGNAL_THRESHOLD) {
// Weak signal: adjust direction
int speedAdjustment = map(irSignal, WEAK_SIGNAL_THRESHOLD, STRONG_SIGNAL_THRESHOLD, 50, 255);
// Left motor (full speed)
digitalWrite(IN1_1, HIGH);
digitalWrite(IN2_1, LOW);
digitalWrite(IN3_1, HIGH);
digitalWrite(IN4_1, LOW);
// Right motor (adjusted speed for weaker motor)
digitalWrite(IN1_2, HIGH);
digitalWrite(IN2_2, LOW);
digitalWrite(IN3_2, HIGH);
digitalWrite(IN4_2, LOW);
isMoving = true;
} else {
// Signal too weak or lost
stopMotors();
isMoving = false;
}
lastSignalTime = millis(); // Update the last signal time
} else if (isMoving && millis() - lastSignalTime > 1000) {
// Stop motors if no signal is received for 1 second
stopMotors();
isMoving = false;
}
}
void moveForward() {
if (isTurning) return; // Don't move forward if the robot is turning
digitalWrite(IN1_1, HIGH);
digitalWrite(IN2_1, LOW);
digitalWrite(IN3_1, HIGH);
digitalWrite(IN4_1, LOW);
digitalWrite(IN1_2, HIGH);
digitalWrite(IN2_2, LOW);
digitalWrite(IN3_2, HIGH);
digitalWrite(IN4_2, LOW);
Serial.print("Motor 1: ");
Serial.print(digitalRead(IN1_1));
Serial.print(", ");
Serial.println(digitalRead(IN2_1));
Serial.print("Motor 2: ");
Serial.print(digitalRead(IN3_1));
Serial.print(", ");
Serial.println(digitalRead(IN4_1));
Serial.print("Motor 3: ");
Serial.print(digitalRead(IN1_2));
Serial.print(", ");
Serial.println(digitalRead(IN2_2));
Serial.print("Motor 4: ");
Serial.print(digitalRead(IN3_2));
Serial.print(", ");
Serial.println(digitalRead(IN4_2));
Serial.println("Moving Forward");
}
void moveBackward() {
digitalWrite(IN1_1, LOW);
digitalWrite(IN2_1, HIGH);
digitalWrite(IN3_1, LOW);
digitalWrite(IN4_1, HIGH);
digitalWrite(IN1_2, LOW);
digitalWrite(IN2_2, HIGH);
digitalWrite(IN3_2, LOW);
digitalWrite(IN4_2, HIGH);
Serial.print("Motor 1: ");
Serial.print(digitalRead(IN1_1));
Serial.print(", ");
Serial.println(digitalRead(IN2_1));
Serial.print("Motor 2: ");
Serial.print(digitalRead(IN3_1));
Serial.print(", ");
Serial.println(digitalRead(IN4_1));
Serial.print("Motor 3: ");
Serial.print(digitalRead(IN1_2));
Serial.print(", ");
Serial.println(digitalRead(IN2_2));
Serial.print("Motor 4: ");
Serial.print(digitalRead(IN3_2));
Serial.print(", ");
Serial.println(digitalRead(IN4_2));
Serial.println("Moving Backwards");
}
void turnLeft() {
// Turning logic
digitalWrite(IN1_1, LOW);
digitalWrite(IN2_1, HIGH);
digitalWrite(IN3_1, HIGH);
digitalWrite(IN4_1, LOW);
digitalWrite(IN1_2, LOW);
digitalWrite(IN2_2, HIGH);
digitalWrite(IN3_2, HIGH);
digitalWrite(IN4_2, LOW);
Serial.print("Motor 1: ");
Serial.print(digitalRead(IN1_1));
Serial.print(", ");
Serial.println(digitalRead(IN2_1));
Serial.print("Motor 2: ");
Serial.print(digitalRead(IN3_1));
Serial.print(", ");
Serial.println(digitalRead(IN4_1));
Serial.print("Motor 3: ");
Serial.print(digitalRead(IN1_2));
Serial.print(", ");
Serial.println(digitalRead(IN2_2));
Serial.print("Motor 4: ");
Serial.print(digitalRead(IN3_2));
Serial.print(", ");
Serial.println(digitalRead(IN4_2));
delay(500); // Adjust turn duration based on needs
stopMotors(); // Ensure turn ends cleanly
}
void turnRight() {
// Turning logic
digitalWrite(IN1_1, HIGH);
digitalWrite(IN2_1, LOW);
digitalWrite(IN3_1, LOW);
digitalWrite(IN4_1, HIGH);
digitalWrite(IN1_2, HIGH);
digitalWrite(IN2_2, LOW);
digitalWrite(IN3_2, LOW);
digitalWrite(IN4_2, HIGH);
Serial.print("Motor 1: ");
Serial.print(digitalRead(IN1_1));
Serial.print(", ");
Serial.println(digitalRead(IN2_1));
Serial.print("Motor 2: ");
Serial.print(digitalRead(IN3_1));
Serial.print(", ");
Serial.println(digitalRead(IN4_1));
Serial.print("Motor 3: ");
Serial.print(digitalRead(IN1_2));
Serial.print(", ");
Serial.println(digitalRead(IN2_2));
Serial.print("Motor 4: ");
Serial.print(digitalRead(IN3_2));
Serial.print(", ");
Serial.println(digitalRead(IN4_2));
delay(500); // Adjust turn duration based on needs
stopMotors(); // Ensure turn ends cleanly
}
void stopMotors() {
digitalWrite(IN1_1, LOW);
digitalWrite(IN2_1, LOW);
digitalWrite(IN3_1, LOW);
digitalWrite(IN4_1, LOW);
digitalWrite(IN1_2, LOW);
digitalWrite(IN2_2, LOW);
digitalWrite(IN3_2, LOW);
digitalWrite(IN4_2, LOW);
Serial.println("Stopping Motors");
}
Test code (works):
// Motor Driver 1
int IN1_1 = 6; // Motor 1 direction control
int IN2_1 = 7; // Motor 1 direction control
int IN3_1 = 8; // Motor 2 direction control
int IN4_1 = 9; // Motor 2 direction control
// Motor Driver 2
int IN1_2 = 12; // Motor 3 direction control
int IN2_2 = 13; // Motor 3 direction control
int IN3_2 = 4; // Motor 4 direction control
int IN4_2 = 2; // Motor 4 direction control
// Ultrasonic Sensor
int trigPin = A0; // D14 (A0) - Trigger pin
int echoPin = A1; // D15 (A1) - Echo pin
// IR Sensor
int irSensorPin = A2; // D16 (A2) - IR sensor output pin
// Servo Motor
int servoPin = A3; // D17 (A3) - Servo motor control pin
void setup() {
// Set motor control pins as output
pinMode(IN1_1, OUTPUT);
pinMode(IN2_1, OUTPUT);
pinMode(IN3_1, OUTPUT);
pinMode(IN4_1, OUTPUT);
pinMode(IN1_2, OUTPUT);
pinMode(IN2_2, OUTPUT);
pinMode(IN3_2, OUTPUT);
pinMode(IN4_2, OUTPUT);
// Set sensor pins as input/output
pinMode(trigPin, OUTPUT);
pinMode(echoPin, INPUT);
pinMode(irSensorPin, INPUT);
// Set servo pin
pinMode(servoPin, OUTPUT);
// Initialize serial communication for debugging
Serial.begin(9600);
}
void loop() {
// Motor Test: Rotate motors in one direction (FORWARD)
Serial.println("Motors Moving FORWARD");
digitalWrite(IN1_1, HIGH);
digitalWrite(IN2_1, LOW);
digitalWrite(IN3_1, HIGH);
digitalWrite(IN4_1, LOW);
digitalWrite(IN1_2, HIGH);
digitalWrite(IN2_2, LOW);
digitalWrite(IN3_2, HIGH);
digitalWrite(IN4_2, LOW);
delay(2000); // Run motors for 2 seconds
// Stop motors
Serial.println("Motors STOPPED");
digitalWrite(IN1_1, LOW);
digitalWrite(IN2_1, LOW);
digitalWrite(IN3_1, LOW);
digitalWrite(IN4_1, LOW);
digitalWrite(IN1_2, LOW);
digitalWrite(IN2_2, LOW);
digitalWrite(IN3_2, LOW);
digitalWrite(IN4_2, LOW);
delay(1000); // Wait for 1 second before reversing
// Motor Test: Reverse motors (REVERSE)
Serial.println("Motors Moving REVERSE");
digitalWrite(IN1_1, LOW);
digitalWrite(IN2_1, HIGH);
digitalWrite(IN3_1, LOW);
digitalWrite(IN4_1, HIGH);
digitalWrite(IN1_2, LOW);
digitalWrite(IN2_2, HIGH);
digitalWrite(IN3_2, LOW);
digitalWrite(IN4_2, HIGH);
delay(2000); // Run motors for 2 seconds
// Stop motors
Serial.println("Motors STOPPED");
digitalWrite(IN1_1, LOW);
digitalWrite(IN2_1, LOW);
digitalWrite(IN3_1, LOW);
digitalWrite(IN4_1, LOW);
digitalWrite(IN1_2, LOW);
digitalWrite(IN2_2, LOW);
digitalWrite(IN3_2, LOW);
digitalWrite(IN4_2, LOW);
delay(1000); // Wait for 1 second before next loop
}
When it writes the IN pin digital values, the right front motor's IN1 and IN2 are both 0, meaning that Motor 3 is getting overridden by something as in the moveBackwards() function, it is set to 0,1.