Embarking on DIY car projects with Arduino opens up a fascinating realm of possibilities, from simple remote-controlled vehicles to sophisticated autonomous systems. A fundamental aspect of many Arduino Car Programs is obstacle avoidance. This article will dissect a basic yet effective Arduino program designed to enable your robotic car to navigate its environment without bumping into obstacles. We’ll explore the code, break down its functionality, and discuss how you can adapt and expand upon it for your own projects.
Understanding the Code: Obstacle Avoidance with Arduino
The provided Arduino code snippet is a starting point for creating an intelligent car program. It leverages an ultrasonic sensor to detect obstacles and control the car’s movement accordingly. Let’s delve into each section to understand how it works.
#include <SoftwareSerial.h>
#define LEFT_A1 4
#define LEFT_B1 5
#define RIGHT_A2 6
#define RIGHT_B2 7
#define IR_TRIG 9
#define IR_ECHO 8
void setup() {
Serial.begin(9600);
pinMode(LEFT_A1, OUTPUT);
pinMode(RIGHT_A2, OUTPUT);
pinMode(LEFT_B1, OUTPUT);
pinMode(RIGHT_B2, OUTPUT);
pinMode(IR_TRIG, OUTPUT);
pinMode(IR_ECHO, INPUT);
}
void loop() {
float duration, distance;
digitalWrite(IR_TRIG, HIGH);
delay(10);
digitalWrite(IR_TRIG, LOW);
duration = pulseIn(IR_ECHO, HIGH);
distance = ((float)(340 * duration) / 10000) / 2;
Serial.print("nDistance : ");
Serial.println(distance);
int sum = 0;
while(distance < 20) {
Serial.println("stop");
stop();
sum++ ;
Serial.println(sum);
float duration, distance;
digitalWrite(IR_TRIG, HIGH);
delay(10);
digitalWrite(IR_TRIG, LOW);
duration = pulseIn(IR_ECHO, HIGH);
distance = ((float)(340 * duration) / 10000) / 2;
Serial.print("nDistance : ");
Serial.println(distance);
if(distance >= 20){
Serial.println("forward");
forward();
}
if(distance >= 20) {
break;
}
if(sum > 9) {
Serial.println("backward");
backward ();
Serial.println("left");
left ();
Serial.println("forwardi");
forwardi ();
Serial.println("right");
right ();
Serial.println("forwardi");
forwardi ();
Serial.println("forwardi");
forwardi ();
Serial.println("right");
right ();
Serial.println("forwardi");
forwardi ();
Serial.println("left");
left ();
Serial.println("forward");
forward();
sum = 0;
}
}
if(distance >= 20){
Serial.println("forward");
forward();
}
}
void forward(){
digitalWrite(LEFT_A1, HIGH);
digitalWrite(LEFT_B1, LOW);
digitalWrite(RIGHT_A2, HIGH);
digitalWrite(RIGHT_B2, LOW);
}
void forwardi (){
digitalWrite(LEFT_A1, HIGH);
digitalWrite(LEFT_B1, LOW);
digitalWrite(RIGHT_A2, HIGH);
digitalWrite(RIGHT_B2, LOW);
delay (2000);
}
void backward(){
digitalWrite(LEFT_A1, LOW);
digitalWrite(LEFT_B1, HIGH);
digitalWrite(RIGHT_A2, LOW);
digitalWrite(RIGHT_B2, LOW);
delay(1000);
}
void left(){
digitalWrite(LEFT_A1, LOW);
digitalWrite(LEFT_B1, HIGH);
digitalWrite(RIGHT_A2, HIGH);
digitalWrite(RIGHT_B2, LOW);
delay(500);
}
void right(){
digitalWrite(LEFT_A1, HIGH);
digitalWrite(LEFT_B1, LOW);
digitalWrite(RIGHT_A2, LOW);
digitalWrite(RIGHT_B2, HIGH);
delay(500);
}
void stop(){
digitalWrite(LEFT_A1, LOW);
digitalWrite(LEFT_B1, LOW);
digitalWrite(RIGHT_A2, LOW);
digitalWrite(RIGHT_B2, LOW);
delay(3000);
}
Pin Definitions and Setup
The code begins by defining the pins used for motor control and the ultrasonic sensor:
LEFT_A1
,LEFT_B1
,RIGHT_A2
,RIGHT_B2
: These pins control the direction of the left and right motors. The specific pins (4, 5, 6, 7) are examples and can be adjusted based on your wiring.IR_TRIG
(9) andIR_ECHO
(8): These are the trigger and echo pins for the ultrasonic sensor (often referred to as IR in the code, though it is actually ultrasonic).
In the setup()
function:
Serial.begin(9600);
: Initializes serial communication for debugging and monitoring the sensor readings.pinMode(...)
: Configures the defined pins as eitherOUTPUT
for motor control orINPUT
for receiving the echo signal from the ultrasonic sensor.
The loop()
Function: Heart of the Arduino Car Program
The loop()
function is where the core logic of the obstacle avoidance program resides. It continuously performs the following actions:
-
Distance Measurement:
digitalWrite(IR_TRIG, HIGH); delay(10); digitalWrite(IR_TRIG, LOW);
: This sequence triggers the ultrasonic sensor to send out a sound wave. A short pulse (10ms HIGH) on the trigger pin initiates the measurement.duration = pulseIn(IR_ECHO, HIGH);
: ThepulseIn()
function measures the duration of the echo pulse received back by the sensor. This duration is proportional to the distance to the obstacle.distance = ((float)(340 * duration) / 10000) / 2;
: This formula converts the duration of the sound wave travel into distance in centimeters. (Speed of sound is approximately 340 m/s, and we divide by 2 because the sound travels to the object and back).Serial.print("nDistance : "); Serial.println(distance);
: Prints the measured distance to the serial monitor for debugging.
-
Obstacle Detection and Response:
while(distance < 20)
: This loop activates when an obstacle is detected within 20cm.stop();
: The car is instructed to stop using thestop()
function (explained later).sum++ ; Serial.println(sum);
: A countersum
is incremented, likely to track how many times an obstacle is encountered in a row.- Repeated Distance Check: Inside the
while
loop, the code measures the distance again. This is somewhat redundant and could be optimized, but it’s present in the original code. if(distance >= 20){ forward(); }
: If, after stopping, the distance is now greater than 20cm, the car moves forward.if(distance >= 20) { break; }
: Thisbreak
statement seems intended to exit thewhile
loop if the distance becomes greater than 20cm after stopping and potentially moving forward, but due to the loop structure, it might not be strictly necessary.- Complex Maneuvering (when sum > 9): If the
sum
counter exceeds 9 (meaning the car has encountered obstacles multiple times consecutively without successfully moving forward), a series of maneuvers are initiated: backward, left, forward (short), right, forward (short, twice), right, forward (short), left, forward. This sequence is designed to attempt to navigate around the obstacle by trying different directions. After this sequence,sum
is reset to 0.
-
Forward Movement (if no obstacle):
if(distance >= 20){ forward(); }
: If the initial distance measurement is greater than or equal to 20cm, the car moves forward using theforward()
function.
Motor Control Functions
The code defines several functions to control the car’s movement:
forward()
: Sets the motor pins to move the car forward.forwardi()
: Moves the car forward for a longer duration (2 seconds) usingdelay(2000)
. This might be intended for making more decisive forward movements during obstacle avoidance.backward()
: Moves the car backward for 1 second.left()
: Turns the car left for 500 milliseconds.right()
: Turns the car right for 500 milliseconds.stop()
: Stops both motors and waits for 3 seconds.
These functions control the motors by setting the digital output pins HIGH
or LOW
in specific combinations. The exact logic (HIGH/LOW for forward/backward) depends on your motor driver and wiring.
Improving and Expanding the Arduino Car Program
This basic Arduino car program provides a foundation for obstacle avoidance. Here are some ways to improve and expand upon it:
- Smoother Movement Logic: The current code uses delays for movements, which can make the car’s motion jerky. Consider using motor speed control (PWM) for smoother acceleration and deceleration.
- More Sophisticated Obstacle Avoidance: The current maneuvering logic is somewhat fixed. You could implement more intelligent algorithms, such as:
- Turning based on sensor readings: Measure distances on both sides (if using multiple sensors) to determine the best direction to turn.
- Path planning: For more complex environments, consider implementing basic path planning algorithms.
- Multiple Sensors: Using multiple ultrasonic sensors (front, sides) would provide a more comprehensive view of the surroundings and enable better obstacle avoidance in tighter spaces.
- Integration with other sensors: Add sensors like line followers, infrared sensors, or even cameras to create more complex behaviors.
- Remote Control: Combine obstacle avoidance with remote control functionality, allowing you to manually override the autonomous behavior when needed.
- State Machines: For more complex programs, consider using state machines to organize different modes of operation (e.g., autonomous mode, remote control mode).
Conclusion
This Arduino car program demonstrates a simple yet effective approach to obstacle avoidance using an ultrasonic sensor. By understanding the code structure, the distance measurement principle, and the motor control logic, you can build upon this foundation to create more advanced and intelligent robotic car projects. Experiment with different sensors, movement algorithms, and control strategies to further enhance your Arduino car’s capabilities and explore the exciting world of DIY robotics and car automation.