Embarking on the journey of robotics with Arduino is an exciting venture, especially when it involves building a smart robot car. One of the fundamental projects for beginners is creating an obstacle-avoiding robot car. This project not only introduces you to the basics of Arduino coding but also provides a hands-on experience with sensors and motor control. Let’s delve into the code that powers a simple yet effective Arduino smart robot car capable of navigating its way around obstacles.
Understanding the Code: Arduino Robot Car in Action
The provided code snippet is a foundational example for an Arduino-based smart car designed to detect and avoid obstacles using an infrared (IR) sensor. Let’s break down each section to understand how it works.
Setting Up the Stage: setup()
Function
#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);
}
This setup()
function is executed once at the beginning of your Arduino program. It initializes the necessary components:
#include <SoftwareSerial.h>
: While included, this line isn’t actually used in the provided code. It’s likely a remnant from projects that might have used software serial communication, but for this obstacle avoidance task, standard serial communication viaSerial.begin(9600)
is utilized for debugging and monitoring sensor readings.#define
statements: These lines assign symbolic names to Arduino pins. This makes the code more readable and easier to modify.LEFT_A1
,LEFT_B1
,RIGHT_A2
,RIGHT_B2
: These are likely connected to a motor driver controlling the left and right wheels of the robot car.IR_TRIG
,IR_ECHO
: These are pins connected to an ultrasonic distance sensor (although namedIR_TRIG
andIR_ECHO
, the code usespulseIn
which is typical for ultrasonic sensors, not IR distance sensors. It’s important to use the sensor type consistent with the code logic).IR_TRIG
pin will trigger the sensor to send out a sound wave, andIR_ECHO
pin will receive the reflected wave.
Serial.begin(9600)
: Initializes serial communication at a baud rate of 9600. This allows you to send data from your Arduino to your computer for monitoring and debugging, using the Serial Monitor in the Arduino IDE.pinMode(...)
: Configures the specified pins as eitherOUTPUT
orINPUT
.- Motor control pins (
LEFT_A1
,LEFT_B1
,RIGHT_A2
,RIGHT_B2
,IR_TRIG
) are set asOUTPUT
because the Arduino will send signals to control the motors and trigger the sensor. IR_ECHO
pin is set asINPUT
because the Arduino will receive the echo signal from the sensor.
- Motor control pins (
The Heart of the Operation: loop()
Function
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();
}
}
The loop()
function runs continuously after setup()
, forming the main control logic of the robot car.
-
Distance Measurement:
float duration, distance; digitalWrite(IR_TRIG, HIGH); delay(10); digitalWrite(IR_TRIG, LOW); duration = pulseIn(IR_ECHO, HIGH); distance = ((float)(340 * duration) / 10000) / 2;
This section measures the distance to an obstacle using the ultrasonic sensor.
digitalWrite(IR_TRIG, HIGH); delay(10); digitalWrite(IR_TRIG, LOW);
: This sequence sends a short trigger pulse to the ultrasonic sensor, initiating the measurement.duration = pulseIn(IR_ECHO, HIGH);
: ThepulseIn()
function measures the duration of the echo pulse received by theIR_ECHO
pin. This duration is proportional to the distance.distance = ((float)(340 * duration) / 10000) / 2;
: This formula converts the duration (in microseconds) to distance (in centimeters). The speed of sound in air (approximately 340 m/s or 0.034 cm/µs) is used for the calculation. The division by 2 is because the sound wave travels to the object and back.Serial.print("nDistance : "); Serial.println(distance);
: This prints the measured distance to the Serial Monitor for debugging.
-
Obstacle Avoidance Logic:
int sum = 0; while(distance < 20) { // ... (code inside while loop) ... } if(distance >= 20){ forward(); }
This is the core of the obstacle avoidance behavior.
int sum = 0;
: Initializes a counter variablesum
.while(distance < 20)
: Thiswhile
loop executes as long as the measured distance is less than 20 cm (you can adjust this threshold). This means if an obstacle is detected within 20cm, the robot will perform obstacle avoidance maneuvers.stop();
: Immediately stops the robot car.sum++ ; Serial.println(sum);
: Increments thesum
counter and prints its value to the serial monitor. This counter seems to be used to trigger a more complex avoidance maneuver after the robot has stopped multiple times, although the logic could be simplified.- Redundant Distance Measurement: Inside the
while
loop, the code measures the distance again. This is somewhat redundant as the loop condition already checks the distance. However, it ensures the robot continuously checks for obstacles while trying to navigate away. if(distance >= 20){ forward(); }
: If, after stopping and potentially maneuvering, the distance becomes greater than or equal to 20cm, the robot tries to move forward again.if(distance >= 20) { break; }
: Thisbreak
statement immediately exits thewhile
loop if the distance is greater than or equal to 20cm. This seems redundant as thewhile
loop condition itself should already handle this exit condition.- Complex Avoidance Maneuver (
if(sum > 9)
): After the robot has stopped multiple times (sum > 9
), it executes a sequence of movements: backward, left, forward (short duration –forwardi
), right, forward (short duration twice), right again, forward (short duration), left, and finally forward again. This is a pre-programmed routine to try and get the robot out of a potentially cornered situation. The effectiveness of this specific sequence will depend on the robot’s physical characteristics and environment. sum = 0;
: Resets thesum
counter after the complex maneuver.if(distance >= 20){ forward(); }
: After thewhile
loop (obstacle avoidance), if the distance is now clear (>= 20cm), the robot moves forward.
Movement Functions: Defining Actions
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);
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_A2, LOW); // Typo in original code, should be RIGHT_B2
digitalWrite(RIGHT_B2, LOW);
delay(3000);
}
These functions define the basic movements of the robot car by controlling the voltage applied to the motor driver pins. Assuming a standard motor driver setup:
forward()
: Makes the robot move forward by setting the motor pins to drive both wheels forward.forwardi()
: Similar toforward()
but includes a 2-second delay (delay(2000)
), making it a forward movement for a specific duration. The ‘i’ likely stands for “interval” or “immediate” forward, although the naming is not standard.backward()
: Moves the robot backward for 1 second (delay(1000)
).left()
: Turns the robot left for 0.5 seconds (delay(500)
). This is likely achieved by driving one wheel forward and the other backward, or by stopping one wheel and driving the other forward.right()
: Turns the robot right for 0.5 seconds (delay(500)
), similar toleft()
but in the opposite direction.stop()
: Stops the robot by setting all motor pins toLOW
, effectively cutting power to the motors. It also includes a 3-second delay (delay(3000)
), making it a stop for a specific duration. Note: There’s a potential typo in the originalstop()
function:digitalWrite(RIGHT_A2, LOW);
is repeated. It should likely bedigitalWrite(RIGHT_B2, LOW);
for correctly stopping both right motor pins.
Enhancements and Further Learning in Arduino Smart Robot Car Coding
This code provides a starting point. Here are ideas to expand your Arduino Smart Robot Car Coding skills:
-
Improved Obstacle Avoidance Logic: The current avoidance strategy is quite basic. Consider implementing more sophisticated algorithms:
- Multiple Sensors: Add sensors (e.g., another ultrasonic sensor on the side) to detect obstacles from different angles for better navigation in complex environments.
- Path Planning: Explore algorithms like wall following or more advanced path planning if you want the robot to navigate through mazes or more structured paths.
- PID Control: For smoother and more precise motor control, especially in turns and straight movements, investigate PID (Proportional-Integral-Derivative) control.
-
Different Sensor Types: Experiment with other sensors:
- Infrared (IR) Distance Sensors: While the code uses an ultrasonic sensor, true IR distance sensors (like Sharp GP2Y0A21YK0F) are also common for obstacle detection and work differently.
- Line Following Sensors: For creating robots that follow lines on the ground.
- Object Recognition with Cameras: For more advanced projects, consider integrating a camera and using libraries like TensorFlow Lite for Arduino to enable object recognition.
-
Wireless Control: Add Bluetooth or Wi-Fi modules to control your robot car wirelessly from a smartphone or computer.
-
More Complex Behaviors: Think about adding functionalities beyond simple obstacle avoidance:
- Remote Control Mode: Switch between autonomous obstacle avoidance and manual control.
- Object Tracking: Program the robot to follow a specific object (e.g., a colored ball).
- Maze Solving: Design algorithms to navigate and solve mazes.
By understanding this basic Arduino smart robot car code and exploring these enhancements, you can significantly deepen your knowledge of Arduino coding and robotics, paving the way for more complex and exciting projects. Remember to always experiment, test, and iterate on your code to learn and improve your robot’s capabilities.
Alt text: An Arduino smart robot car with visible ultrasonic sensor, navigating a miniature obstacle course made of cardboard boxes, showcasing autonomous navigation capabilities.