Hi everyone,
I built an Arduino-based 2WD robot car and programmed it to autonomously navigate and avoid obstacles using an ultrasonic sensor and a servo motor. However, I’m facing several issues:
- Movement Pattern Issue: My robot currently moves in small circles. When it detects an obstacle, it either stops, moves backward, and resumes circling or just stops in front of the obstacle without continuing. I would like the robot to move in larger circles and actively avoid obstacles rather than getting stuck.
- Servo Motor Issue: The servo motor doesn't move at all, while the ultrasonic sensor works fine. This prevents the sensor from scanning different directions for obstacles.
I've attached my wiring diagram as a picture and included my current code below. Any suggestions for improvements or debugging would be greatly appreciated!
Thank you in advance for your help!
#include <Servo.h>
#include <avr/wdt.h> // Watchdog timer for auto reset
// Define ultrasonic sensor pins
#define TRIG 4
#define ECHO 5
// Define motor driver pins (L298N)
#define MOTOR_R_F 6 // Right motor forward
#define MOTOR_R_B 7 // Right motor backward
#define MOTOR_L_F 8 // Left motor forward
#define MOTOR_L_B 9 // Left motor backward
// Define servo pin
#define SERVO_PIN 10
// Create Servo object
Servo myServo;
// Function to measure distance using ultrasonic sensor
long getDistance() {
digitalWrite(TRIG, LOW);
delayMicroseconds(2);
digitalWrite(TRIG, HIGH);
delayMicroseconds(10);
digitalWrite(TRIG, LOW);
long duration = pulseIn(ECHO, HIGH);
long distance = duration * 0.034 / 2; // Convert to cm
if (distance > 200) return 200; // Limit to 200 cm max
return distance;
}
// Function to move the robot forward
void moveForward() {
digitalWrite(MOTOR_R_F, HIGH);
digitalWrite(MOTOR_R_B, LOW);
digitalWrite(MOTOR_L_F, HIGH);
digitalWrite(MOTOR_L_B, LOW);
}
// Function to move the robot backward
void moveBackward() {
digitalWrite(MOTOR_R_F, LOW);
digitalWrite(MOTOR_R_B, HIGH);
digitalWrite(MOTOR_L_F, LOW);
digitalWrite(MOTOR_L_B, HIGH);
}
// Function to turn left
void turnLeft() {
digitalWrite(MOTOR_R_F, HIGH);
digitalWrite(MOTOR_R_B, LOW);
digitalWrite(MOTOR_L_F, LOW);
digitalWrite(MOTOR_L_B, HIGH);
}
// Function to turn right
void turnRight() {
digitalWrite(MOTOR_R_F, LOW);
digitalWrite(MOTOR_R_B, HIGH);
digitalWrite(MOTOR_L_F, HIGH);
digitalWrite(MOTOR_L_B, LOW);
}
// Function to stop the robot
void stopRobot() {
digitalWrite(MOTOR_R_F, LOW);
digitalWrite(MOTOR_R_B, LOW);
digitalWrite(MOTOR_L_F, LOW);
digitalWrite(MOTOR_L_B, LOW);
}
void setup() {
Serial.begin(9600);
wdt_enable(WDTO_8S); // Enable auto-reset if frozen for 8 seconds
// Initialize motor pins
pinMode(MOTOR_R_F, OUTPUT);
pinMode(MOTOR_R_B, OUTPUT);
pinMode(MOTOR_L_F, OUTPUT);
pinMode(MOTOR_L_B, OUTPUT);
// Initialize ultrasonic sensor pins
pinMode(TRIG, OUTPUT);
pinMode(ECHO, INPUT);
// Attach servo to pin
myServo.attach(SERVO_PIN);
myServo.write(90); // Center position
delay(1000);
}
void loop() {
wdt_reset(); // Prevent watchdog timer reset if running correctly
long frontDistance = getDistance();
Serial.print("Front Distance: ");
Serial.print(frontDistance);
Serial.println(" cm");
if (frontDistance > 20) {
moveForward(); // Move forward if path is clear
} else {
stopRobot();
Serial.println("Obstacle detected! Scanning...");
delay(500);
// Scan left
myServo.write(150);
delay(500);
long leftDistance = getDistance();
Serial.print("Left Distance: ");
Serial.print(leftDistance);
Serial.println(" cm");
// Scan right
myServo.write(30);
delay(500);
long rightDistance = getDistance();
Serial.print("Right Distance: ");
Serial.print(rightDistance);
Serial.println(" cm");
// Reset servo to center
myServo.write(90);
delay(500);
// Decide turning direction
if (leftDistance > rightDistance) {
Serial.println("Turning LEFT...");
turnLeft();
delay(800);
} else {
Serial.println("Turning RIGHT...");
turnRight();
delay(800);
}
stopRobot(); // Stop after turning
delay(500);
moveForward(); // Ensure robot moves forward after turning
}
delay(200); // Prevent excessive serial flooding
}
