2 Wheeled Smart Robot Car

Started: April 2025

Project preview

Overview

This compact autonomous robot is built around an ESP32 microcontroller, providing a powerful and Wi-Fi-capable platform for smart behaviors. It combines an ultrasonic distance sensor with dual infrared (IR) sensors to enable obstacle avoidance, line following, and edge detection—making it ideal for hands-on learning and beginner robotics exploration.

The chassis is powered by two DC motors driven by an L298N motor controller, with power supplied by three 18650 lithium-ion batteries. A buck converter regulates voltage to ensure stable operation for both motors and logic components. Mode selection is handled through onboard switches, enabling quick toggling between object avoidance, path following, and edge detection modes.

This project introduces key robotics concepts such as sensor-based navigation, motor control, power management, and conditional logic. It’s a perfect fit for STEM education, hobbyist experimentation, or anyone curious about building and programming real-world autonomous systems.

Parts & Materials

Wiring & Circuit

Brief description of how the wiring was handled, plus a diagram if desired.

Code & Logic

Summary of how the code works. Highlight logic for sensors, motors, and control flow.


#include 

// Motor direction pins
#define IN1 14
#define IN2 27
#define IN3 26
#define IN4 25

// PWM speed pins
#define ENA 33
#define ENB 32

// Ultrasonic sensor pins
#define TRIG_PIN 18
#define ECHO_PIN 19

// IR Sensor pins
#define LEFT_SENSOR_PIN 2
#define RIGHT_SENSOR_PIN 4

// Distance threshold (in cm)
#define OBSTACLE_DISTANCE 20

// Speed level (0–255)
#define SPEED_Left 120
#define SPEED_Right 100

void setup() {
  Serial.begin(115200);
  
  // Set pin modes
  pinMode(IN1, OUTPUT);
  pinMode(IN2, OUTPUT);
  pinMode(IN3, OUTPUT);
  pinMode(IN4, OUTPUT);

  // Set up PWM channels
  ledcSetup(0, 1000, 8); // Channel 0
  ledcSetup(1, 1000, 8); // Channel 1
  ledcAttachPin(ENA, 0);
  ledcAttachPin(ENB, 1);

  pinMode(TRIG_PIN, OUTPUT);
  pinMode(ECHO_PIN, INPUT);

  pinMode(LEFT_SENSOR_PIN, INPUT);
  pinMode(RIGHT_SENSOR_PIN, INPUT);
}

long getDistanceCM() {
  digitalWrite(TRIG_PIN, LOW);
  delayMicroseconds(2);
  digitalWrite(TRIG_PIN, HIGH);
  delayMicroseconds(10);
  digitalWrite(TRIG_PIN, LOW);

  long duration = pulseIn(ECHO_PIN, HIGH, 30000); // 30ms timeout
  long distance = duration * 0.034 / 2;
  return distance;
}

// Movement functions
void forward() {
  digitalWrite(IN1, LOW);
  digitalWrite(IN2, HIGH);
  digitalWrite(IN3, HIGH);
  digitalWrite(IN4, LOW);
  ledcWrite(0, SPEED_Right);
  ledcWrite(1, SPEED_Left);
}

void backward() {
  digitalWrite(IN1, HIGH);
  digitalWrite(IN2, LOW);
  digitalWrite(IN3, LOW);
  digitalWrite(IN4, HIGH);
  ledcWrite(0, SPEED_Right);
  ledcWrite(1, SPEED_Left);
}

void turnLeft() {
  digitalWrite(IN1, HIGH);
  digitalWrite(IN2, LOW);  // Left motor backward
  digitalWrite(IN3, HIGH);
  digitalWrite(IN4, LOW);   // Right motor forward
  ledcWrite(0, SPEED_Right);
  ledcWrite(1, SPEED_Left);
}

void turnRight() {
  digitalWrite(IN1, LOW);
  digitalWrite(IN2, HIGH);   // Left motor forward
  digitalWrite(IN3, LOW);
  digitalWrite(IN4, HIGH);  // Right motor backward
  ledcWrite(0, SPEED_Right);
  ledcWrite(1, SPEED_Left);
}

void stopMotors() {
  ledcWrite(0, 0);
  ledcWrite(1, 0);
}

void loop() {
  long distance = getDistanceCM();
  bool leftBlocked = digitalRead(LEFT_SENSOR_PIN) == LOW;
  bool rightBlocked = digitalRead(RIGHT_SENSOR_PIN) == LOW;
  Serial.print("Distance: ");
  Serial.print(distance);
  Serial.println(" cm");

  if (distance > 0 && distance < OBSTACLE_DISTANCE) {
    Serial.println("Obstacle detected. Backing up and turning...");
    stopMotors();
    delay(200);
    backward();
    delay(700);
    stopMotors();
    delay(100);
    turnRight();
    delay(500);
    stopMotors();
    delay(100);
  } else if (leftBlocked){
    Serial.println("Object Detected on Left");
    stopMotors();
    delay(200);
    turnRight();
    delay(500);
    stopMotors();
    delay(100);
  }else if (rightBlocked){
    Serial.println("Object Detected on Right");
    stopMotors();
    delay(200);
    turnLeft();
    delay(500);
    stopMotors();
    delay(100);
  }else {
    forward();
    Serial.println("Driving forward...");
  }

  delay(100);
}
          

Challenges & Learnings

Notes on any tricky parts of the build, problems you solved, or lessons learned.

Future Improvements

Ideas for how you might expand or refine the project in future iterations.