How to Program an Arduino Uno for a DIY Smart Car

Are you fascinated by robotics and looking for a fun, hands-on project? Programming an Arduino Uno to control a car is an excellent starting point! This guide will walk you through the basics of setting up your Arduino Uno to drive a simple car, complete with obstacle avoidance capabilities using an infrared (IR) sensor. We’ll delve into the code, explaining each part so you can understand how it works and customize it for your own robotic car project.

What You’ll Need to Get Started

Before we dive into the code, let’s gather the necessary components for your Arduino car project. You’ll need:

  • Arduino Uno: The brain of your car, responsible for processing code and controlling the motors.
  • Motor Driver (e.g., L298N): An essential component that allows the Arduino to control the motors, as the Arduino itself cannot provide enough power.
  • DC Motors (x2): These will power the wheels of your car. Choose motors appropriate for your car chassis.
  • Wheels (x2 or x4 depending on your car design): Attach these to your DC motors to make your car mobile.
  • Infrared (IR) Sensor: This sensor will act as the “eyes” of your car, detecting obstacles in its path. We’ll use it for obstacle avoidance.
  • Jumper Wires: For connecting all the electronic components together.
  • Power Source (e.g., 9V Battery): To power your Arduino and motors.
  • Breadboard (Optional but Recommended): Makes prototyping and wiring easier.
  • Chassis for your car (DIY or pre-made): The body of your car to mount all the components.

Setting Up the Circuit: Wiring Your Arduino Car

Let’s wire up the components. Here’s a basic wiring guide. Always double-check your motor driver and IR sensor documentation for specific pinouts as they might vary.

  1. Connect the Motor Driver to the Arduino:

    • Motor Driver ENA pin to Arduino Digital Pin 4 (LEFT_A1 in the code).
    • Motor Driver IN1 pin to Arduino Digital Pin 5 (LEFT_B1 in the code).
    • Motor Driver ENB pin to Arduino Digital Pin 6 (RIGHT_A2 in the code).
    • Motor Driver IN2 pin to Arduino Digital Pin 7 (RIGHT_B2 in the code).
    • Motor Driver VCC and GND to your power source (and Arduino GND for common ground).
    • Motor Driver Motor A outputs to one DC motor.
    • Motor Driver Motor B outputs to the other DC motor.
  2. Connect the IR Sensor to the Arduino:

    • IR Sensor VCC to Arduino 5V.
    • IR Sensor GND to Arduino GND.
    • IR Sensor TRIG (Trigger) pin to Arduino Digital Pin 9 (IR_TRIG in the code).
    • IR Sensor ECHO (Echo) pin to Arduino Digital Pin 8 (IR_ECHO in the code).

Important Notes on Wiring:

  • Ensure you have a common ground between the Arduino, motor driver, and power source.
  • Refer to the datasheets of your specific components for accurate pinouts and voltage requirements.
  • Double-check all connections before powering up the circuit to avoid damage.

Understanding the Arduino Code for Car Control

Now, let’s break down the Arduino code that will bring your car to life. This code is designed to make your car move forward and stop when it detects an obstacle within a certain range using the IR sensor. It also includes a basic obstacle avoidance routine.

#include <SoftwareSerial.h>

// Define motor control pins
#define LEFT_A1 4
#define LEFT_B1 5
#define RIGHT_A2 6
#define RIGHT_B2 7

// Define IR sensor pins
#define IR_TRIG 9
#define IR_ECHO 8

void setup() {
  // Initialize serial communication for debugging
  Serial.begin(9600);

  // Set motor control pins as OUTPUT
  pinMode(LEFT_A1, OUTPUT);
  pinMode(RIGHT_A2, OUTPUT);
  pinMode(LEFT_B1, OUTPUT);
  pinMode(RIGHT_B2, OUTPUT);

  // Set IR sensor pins as OUTPUT (TRIG) and INPUT (ECHO)
  pinMode(IR_TRIG, OUTPUT);
  pinMode(IR_ECHO, INPUT);
}

void loop() {
  // Variables for distance measurement
  float duration, distance;

  // Trigger the IR sensor to send a pulse
  digitalWrite(IR_TRIG, HIGH);
  delay(10); // Keep HIGH for 10 microseconds
  digitalWrite(IR_TRIG, LOW);

  // Measure the duration of the echo pulse
  duration = pulseIn(IR_ECHO, HIGH);

  // Calculate distance in centimeters (approximately)
  distance = ((float)(340 * duration) / 10000) / 2;

  // Print distance to serial monitor for debugging
  Serial.print("nDistance : ");
  Serial.println(distance);

  int sum = 0; // Counter for obstacle avoidance routine

  // Obstacle detection and avoidance logic
  while (distance < 20) { // If obstacle is closer than 20cm
    Serial.println("stop");
    stop(); // Stop the car
    sum++; // Increment the counter
    Serial.println(sum);

    // Re-measure distance
    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) { // If obstacle is now clear
      Serial.println("forward");
      forward(); // Move forward
    }
    if (distance >= 20) {
      break; // Exit the while loop
    }

    if (sum > 9) { // Basic obstacle avoidance maneuver
      Serial.println("backward");
      backward(); // Move backward briefly
      Serial.println("left");
      left();      // Turn left briefly
      Serial.println("forwardi");
      forwardi();  // Move forward for a short duration
      Serial.println("right");
      right();     // Turn right briefly
      Serial.println("forwardi");
      forwardi();  // Move forward again briefly
      Serial.println("forwardi");
      forwardi();  // Move forward again briefly
      Serial.println("right");
      right();     // Turn right again briefly
      Serial.println("forwardi");
      forwardi();  // Move forward again briefly
      Serial.println("left");
      left();      // Turn left again briefly
      Serial.println("forward");
      forward();   // Resume forward motion
      sum = 0;     // Reset the counter
    }
  }

  if (distance >= 20) { // If no obstacle detected
    Serial.println("forward");
    forward(); // Move forward
  }
}

// Function to move the car forward
void forward() {
  digitalWrite(LEFT_A1, HIGH);
  digitalWrite(LEFT_B1, LOW);
  digitalWrite(RIGHT_A2, HIGH);
  digitalWrite(RIGHT_B2, LOW);
}

// Function to move the car forward for a short interval
void forwardi() {
  digitalWrite(LEFT_A1, HIGH);
  digitalWrite(LEFT_B1, LOW);
  digitalWrite(RIGHT_A2, HIGH);
  digitalWrite(RIGHT_B2, LOW);
  delay(2000); // Move forward for 2 seconds
}

// Function to move the car backward
void backward() {
  digitalWrite(LEFT_A1, LOW);
  digitalWrite(LEFT_B1, HIGH);
  digitalWrite(RIGHT_A2, LOW);
  digitalWrite(RIGHT_B2, HIGH);
  delay(1000); // Move backward for 1 second
}

// Function to turn the car left
void left() {
  digitalWrite(LEFT_A1, LOW);
  digitalWrite(LEFT_B1, HIGH);
  digitalWrite(RIGHT_A2, HIGH);
  digitalWrite(RIGHT_B2, LOW);
  delay(500); // Turn left for 0.5 seconds
}

// Function to turn the car right
void right() {
  digitalWrite(LEFT_A1, HIGH);
  digitalWrite(LEFT_B1, LOW);
  digitalWrite(RIGHT_A2, LOW);
  digitalWrite(RIGHT_B2, HIGH);
  delay(500); // Turn right for 0.5 seconds
}

// Function to stop the car
void stop() {
  digitalWrite(LEFT_A1, LOW);
  digitalWrite(LEFT_B1, LOW);
  digitalWrite(RIGHT_A2, LOW);
  digitalWrite(RIGHT_B2, LOW);
  delay(3000); // Stop for 3 seconds
}

Code Explanation: Step-by-Step

  1. Include Header & Pin 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>: While not strictly needed in this code, it’s often included in Arduino projects and doesn’t harm. It’s for software serial communication, which isn’t used here but might be in more complex projects.
    • #define ...: These lines define constants that represent the Arduino pins connected to the motor driver and IR sensor. This makes the code more readable and easier to modify if you change pin assignments.
  2. setup() Function:

    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);
    }
    • Serial.begin(9600);: Initializes serial communication at 9600 baud rate. This is used to send data from the Arduino to your computer’s serial monitor, which is very helpful for debugging and seeing sensor readings.
    • pinMode(...): Sets the specified pins as either OUTPUT (for controlling motors and triggering the IR sensor) or INPUT (for reading the echo from the IR sensor).
  3. loop() Function – Main Control Logic:

    void loop() {
      // ... (distance measurement code) ...
    
      int sum = 0;
      while(distance < 20) {
        // ... (obstacle detected logic) ...
        if(sum > 9) {
          // ... (obstacle avoidance maneuver) ...
        }
      }
    
      if(distance >= 20){
        forward();
      }
    }
    • The loop() function runs continuously, executing the code within it repeatedly.
    • Distance Measurement: The code first measures the distance using the IR sensor. It sends a trigger pulse (digitalWrite(IR_TRIG, HIGH); delay(10); digitalWrite(IR_TRIG, LOW);) and then measures the duration of the echo pulse (duration = pulseIn(IR_ECHO, HIGH);). The distance is calculated based on the speed of sound.
    • Obstacle Detection: while (distance < 20): This loop checks if an obstacle is detected within 20cm. If it is, the code inside the while loop executes.
    • stop() Function: stop();: The car is instructed to stop.
    • sum Counter: sum++: A counter is incremented. This counter is used to trigger the obstacle avoidance maneuver after the car has stopped a few times.
    • Obstacle Avoidance Maneuver (if(sum > 9)): If the sum counter exceeds 9 (meaning the car has stopped multiple times consecutively), the code initiates a basic obstacle avoidance sequence: backward, left, forward (short duration), right, forward (short duration), right, forward (short duration), left, and then forward again. This is a very simple avoidance strategy and can be improved.
    • Resuming Forward Motion: if (distance >= 20) { forward(); }: After obstacle detection and potentially avoidance, or if no obstacle is detected initially (if(distance >= 20) outside the while loop), the car is instructed to move forward.
  4. Motor Control Functions:

    • forward(), backward(), left(), right(), stop(), forwardi(): These functions control the direction and movement of the car by setting the digital pins connected to the motor driver HIGH or LOW in specific combinations.
    • The delay() function within some of these functions (backward(), left(), right(), stop(), forwardi()) introduces pauses to control the duration of the movements (e.g., turning for 0.5 seconds).

Running Your Arduino Car

  1. Upload the Code: Connect your Arduino Uno to your computer using a USB cable. Open the Arduino IDE, paste the code, select your Arduino board and port, and upload the code.
  2. Power Up: Disconnect the Arduino from your computer and connect your external power source (e.g., 9V battery) to power the Arduino and motor driver.
  3. Test and Observe: Place your car on the floor and observe its behavior. It should move forward and stop when it detects an obstacle in front of the IR sensor.

Enhancements and Further Learning

This is a basic Arduino car program. You can expand upon it in many ways:

  • Improved Obstacle Avoidance: Implement more sophisticated obstacle avoidance algorithms. For example, instead of a fixed sequence, you could have the car check distances to the left and right to choose a better direction to turn.
  • Speed Control: Use PWM (Pulse Width Modulation) to control the speed of the motors, making movements smoother and more controlled.
  • Remote Control: Add Bluetooth or Wi-Fi modules to control your car remotely using a smartphone app or another device.
  • Line Following: Add line sensors to create a line-following robot car.
  • More Sensors: Incorporate more sensors like ultrasonic sensors for more accurate distance readings or encoders for precise motor control and navigation.

Programming an Arduino Uno car is a fantastic project for learning about robotics, electronics, and programming. Experiment with the code, modify the movements, and add new features to create your own unique smart car!

Comments

No comments yet. Why don’t you start the discussion?

Leave a Reply

Your email address will not be published. Required fields are marked *