Embarking on the journey of DIY robotics with an Arduino car kit is an incredibly rewarding experience. It’s a fantastic way to learn about electronics, programming, and mechanics in a hands-on, engaging way. One of the most popular and intriguing projects for beginners is programming your Arduino car to navigate autonomously, and a key aspect of this is obstacle avoidance.
This article will delve into a fundamental Arduino program designed to enable your car kit to detect and avoid obstacles. We’ll break down the code, explain its logic, and explore how you can adapt and expand upon it for your own robotic adventures. Whether you’re a student, hobbyist, or simply curious about the world of Arduino and robotics, this guide will provide you with a solid foundation to get started with your “Arduino Car Kit Program”.
#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, HIGH);
delay(1000);
}
void left(){
digitalWrite(LEFT_A1, LOW);
digitalWrite(LEFT_B1, HIGH);
digitalWrite(RIGHT_A2, HIGH);
digitalWrite(RIGHT_B2, LOW);
}
void right(){
digitalWrite(LEFT_A1, LOW);
digitalWrite(LEFT_B1, LOW);
digitalWrite(RIGHT_A2, LOW);
digitalWrite(RIGHT_B2, LOW);
}
void stop(){
digitalWrite(LEFT_A1, LOW);
digitalWrite(LEFT_B1, LOW);
digitalWrite(RIGHT_A2, LOW);
digitalWrite(RIGHT_B2, LOW);
delay(3000);
}
Code Breakdown: Understanding Your Arduino Car Program
Let’s dissect this Arduino code snippet to understand how it commands your car kit to navigate and avoid obstacles. This program is designed for a basic two-wheeled robot car chassis, utilizing an ultrasonic sensor for distance detection and a motor driver to control the wheels.
1. Setup and Definitions
#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
#include <SoftwareSerial.h>
: This line includes the SoftwareSerial library. While not strictly used in this specific code, it’s often included in Arduino projects for serial communication, and might be intended for future expansion or debugging via serial monitor. It’s good practice to keep it if you plan to add Bluetooth or other serial communication later.#define ...
: These lines define constants for the Arduino pins connected to your motor driver and ultrasonic sensor.LEFT_A1
,LEFT_B1
,RIGHT_A2
,RIGHT_B2
: These are likely connected to the control inputs of your motor driver for the left and right wheels. By setting these pins HIGH or LOW, you control the direction of each motor.IR_TRIG
: This pin is the “trigger” pin for the ultrasonic sensor. It sends out the ultrasonic pulse. (Note: While the code uses “IR_TRIG” and “IR_ECHO”, it’s highly likely they meant “ULTRASONIC_TRIG” and “ULTRASONIC_ECHO” as the code usespulseIn
which is for ultrasonic sensors, not infrared. The defines are just names, the functionality points to ultrasonic.)IR_ECHO
: This is the “echo” pin of the ultrasonic sensor. It receives the reflected ultrasonic pulse and measures the time it takes to return. (Same note as above regarding “IR” vs “Ultrasonic”).
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 setup() { ... }
: This function runs once at the beginning of your program.Serial.begin(9600);
: Initializes serial communication at 9600 bits per second. This allows you to send data from your Arduino to your computer for debugging and monitoring using the Serial Monitor in the Arduino IDE.pinMode(...)
: These lines configure the defined pins as eitherOUTPUT
(for controlling motors and triggering the sensor) orINPUT
(for reading the sensor’s echo).
2. Main Loop and Obstacle Detection
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);
// ... rest of the loop code ...
}
void loop() { ... }
: This function runs continuously after thesetup()
function completes. This is where the main logic of your robot resides.- Ultrasonic Sensor Reading:
digitalWrite(IR_TRIG, HIGH); delay(10); digitalWrite(IR_TRIG, LOW);
: This sequence triggers the ultrasonic sensor to send out a pulse. A short HIGH pulse (10 microseconds is typical,delay(10)
here is in milliseconds and likely longer than needed, but will still work) on the trigger pin initiates the ultrasonic burst.duration = pulseIn(IR_ECHO, HIGH);
: This crucial function measures the duration of the HIGH pulse on the echo pin. ThepulseIn()
function waits for the echo pin to go HIGH, starts timing, waits for it to go LOW, and returns the duration of the pulse in microseconds. This duration is directly proportional to the distance to the object.distance = ((float)(340 * duration) / 10000) / 2;
: This line calculates the distance in centimeters.340
m/s is the approximate speed of sound in air.duration
is in microseconds, so we multiply by 340 and divide by 1,000,000 (or 1000000) to get meters, and then by 100 to get centimeters. The code uses10000
which might be a simplification or slight error, but in practice, it will likely give a scaled distance reading that is usable for obstacle detection.- Dividing by
2
is because the sound wave travels to the object and back, so the measured time is for a round trip. We only need the distance to the object (one way).
Serial.print("nDistance : "); Serial.println(distance);
: This prints the calculated distance to the Serial Monitor for debugging and monitoring.
- Ultrasonic Sensor Reading:
3. Obstacle Avoidance Logic
int sum = 0;
while(distance < 20) {
Serial.println("stop");
stop();
sum++ ;
Serial.println(sum);
// ... (Repeated distance reading and movement logic) ...
}
if(distance >= 20){
Serial.println("forward");
forward();}
-
int sum = 0;
: Initializes a counter variablesum
. This counter is used to implement a more complex obstacle avoidance behavior after the robot encounters an obstacle multiple times. -
while(distance < 20) { ... }
: Thiswhile
loop is the core of the obstacle avoidance logic. As long as the measureddistance
is less than 20 cm (or whatever unit thedistance
calculation yields), the code inside this loop will execute.Serial.println("stop"); stop();
: The robot is instructed to stop when an obstacle is detected within 20cm. Thestop()
function (defined later) is called to halt the motors.sum++ ; Serial.println(sum);
: Thesum
counter is incremented, and its value is printed to the Serial Monitor.- (Repeated Distance Reading): Inside the
while
loop, the code again reads the distance using the ultrasonic sensor. This is somewhat redundant and inefficient. It’s likely intended to continuously check the distance while in the obstacle avoidance routine. However, the repeated sensor reading andif(distance >= 20){ forward();}
within the loop are logically flawed and could lead to unpredictable behavior. if(sum > 9) { ... }
: After the robot has stopped and encountered an obstaclesum
times (in theory, based on the flawed logic – in practice, this part might not be reached reliably), thisif
block executes a sequence of movements to try and get around the obstacle.- Maneuvering Sequence:
backward()
,left()
,forwardi()
,right()
,forwardi()
,forwardi()
,right()
,forwardi()
,left()
,forward()
: This sequence attempts to move the robot backward, turn left, move forward a bit, turn right, move forward again, and so on. The intention is to perform a small “dance” to try and navigate around the obstacle. The specific delays inforwardi()
,backward()
,left()
,right()
,stop()
functions determine the duration of these movements and thus the turning angles and distances. sum = 0;
: Resets thesum
counter after the maneuvering sequence, presumably to start the obstacle avoidance count again if needed.
- Maneuvering Sequence:
if(distance >= 20){ forward();}
: Thisif
statement inside thewhile(distance < 20)
loop is also logically incorrect. If the distance is already less than 20cm to enter thewhile
loop, this conditiondistance >= 20
will never be true within the loop’s first iteration after stopping. This line seems misplaced and won’t execute as intended within the obstacle avoidancewhile
loop.
-
if(distance >= 20){ forward();}
(Outside thewhile
loop): After thewhile(distance < 20)
loop finishes (meaning the distance is now 20cm or greater), thisif
statement makes the robot move forward again using theforward()
function. This is the intended behavior: if no obstacle is detected (distance >= 20cm), move forward.
4. Motor Control Functions
void forward(){ ... }
void forwardi (){ ... }
void backward(){ ... }
void left(){ ... }
void right(){ ... }
void stop(){ ... }
- These functions define the basic movements of the robot by controlling the motor driver pins.
forward()
: Sets the motor pins to move both wheels forward.forwardi()
: Moves forward for a longer duration (2 seconds delay –delay(2000);
). The ‘i’ likely stands for “interval” or “extended”.backward()
: Moves backward for 1 second (delay(1000);
).left()
: Turns left by stopping the left wheel and moving the right wheel forward for 0.5 seconds (delay(500);
).right()
: Turns right by stopping the right wheel and moving the left wheel forward for 0.5 seconds (delay(500);
).stop()
: Stops both motors and waits for 3 seconds (delay(3000);
).
Improving the Arduino Car Kit Program
This code provides a basic starting point, but there are several areas for improvement and expansion:
- Correcting Logic Errors: The repeated distance reading and misplaced
if(distance >= 20){ forward();}
inside thewhile
loop should be removed or corrected. The obstacle avoidance logic within thewhile
loop needs to be streamlined. - More Robust Obstacle Avoidance: The current maneuvering sequence is very basic and might not work well in all situations. More sophisticated algorithms could be implemented, such as:
- Turning Away: Instead of a fixed sequence, the robot could turn left or right randomly or based on previous turning direction.
- Wall Following: If the robot gets stuck, it could try to follow a wall to navigate around the obstacle.
- Path Planning: For more advanced projects, consider implementing simple path planning algorithms.
- Smoother Movement: The current
left()
andright()
functions are very abrupt. Consider implementing smoother turns by varying motor speeds instead of just stopping one wheel. - PID Control: For more precise motor control, especially if you want your robot to move in straight lines and accurate turns, implementing PID (Proportional-Integral-Derivative) control for the motors would be highly beneficial.
- Sensor Fusion: Adding more sensors (e.g., infrared line followers, bumpers, additional ultrasonic sensors) can significantly improve the robot’s awareness of its environment and its ability to navigate complex spaces.
- Code Clarity and Comments: Add more comments to the code to explain each section and function more clearly. This makes the code easier to understand and modify, especially for beginners.
- Efficiency: The repeated distance readings within the
while
loop are inefficient. Optimize the code to avoid unnecessary sensor readings.
Conclusion
This Arduino program provides a foundational example of how to program an Arduino car kit for obstacle avoidance. By understanding the code’s structure, logic, and limitations, you can begin to modify and expand upon it to create more sophisticated and capable autonomous robots. Experiment with different movement strategies, add more sensors, and explore advanced control techniques to take your “arduino car kit program” to the next level. The world of DIY robotics is vast and exciting, and your Arduino car kit is just the beginning!