Building an Autonomous Robot with ESP32

Difficulty Level: Advanced

This tutorial will walk you through the essential code and logic to create a basic autonomous robot using an ESP32 microcontroller. We’ll cover motor control, obstacle detection, and decision-making algorithms.

Components Required

Step 1: Setting Up the Motors

Connect the DC motors to the motor driver and wire the motor driver to the ESP32:


ESP32 Pin      | Motor Driver
---------------|-------------
GPIO 26        | IN1 (Motor A control)
GPIO 27        | IN2 (Motor A control)
GPIO 32        | IN3 (Motor B control)
GPIO 33        | IN4 (Motor B control)
5V             | VCC
GND            | GND
        

Step 2: Connecting the Ultrasonic Sensor

Wire the HC-SR04 ultrasonic sensor to detect obstacles in front of the robot:


Ultrasonic Sensor Pin | ESP32 Pin
----------------------|-------------
VCC                   | 3.3V
GND                   | GND
TRIG                  | GPIO 14
ECHO                  | GPIO 12
        

Step 3: Code for Motor Control

Below is the code to control the motors, including functions to move forward, backward, stop, and turn. This will help the robot navigate around obstacles.


#include <Arduino.h>

// Motor pins
#define MOTOR_A_IN1 26
#define MOTOR_A_IN2 27
#define MOTOR_B_IN3 32
#define MOTOR_B_IN4 33

// Function to initialize motors
void setupMotors() {
    pinMode(MOTOR_A_IN1, OUTPUT);
    pinMode(MOTOR_A_IN2, OUTPUT);
    pinMode(MOTOR_B_IN3, OUTPUT);
    pinMode(MOTOR_B_IN4, OUTPUT);
}

// Move forward
void moveForward() {
    digitalWrite(MOTOR_A_IN1, HIGH);
    digitalWrite(MOTOR_A_IN2, LOW);
    digitalWrite(MOTOR_B_IN3, HIGH);
    digitalWrite(MOTOR_B_IN4, LOW);
}

// Move backward
void moveBackward() {
    digitalWrite(MOTOR_A_IN1, LOW);
    digitalWrite(MOTOR_A_IN2, HIGH);
    digitalWrite(MOTOR_B_IN3, LOW);
    digitalWrite(MOTOR_B_IN4, HIGH);
}

// Turn left
void turnLeft() {
    digitalWrite(MOTOR_A_IN1, LOW);
    digitalWrite(MOTOR_A_IN2, HIGH);
    digitalWrite(MOTOR_B_IN3, HIGH);
    digitalWrite(MOTOR_B_IN4, LOW);
}

// Turn right
void turnRight() {
    digitalWrite(MOTOR_A_IN1, HIGH);
    digitalWrite(MOTOR_A_IN2, LOW);
    digitalWrite(MOTOR_B_IN3, LOW);
    digitalWrite(MOTOR_B_IN4, HIGH);
}

// Stop motors
void stopMotors() {
    digitalWrite(MOTOR_A_IN1, LOW);
    digitalWrite(MOTOR_A_IN2, LOW);
    digitalWrite(MOTOR_B_IN3, LOW);
    digitalWrite(MOTOR_B_IN4, LOW);
}
        

Step 4: Code for Obstacle Detection

We’ll use the ultrasonic sensor to measure the distance to obstacles in front of the robot. If an obstacle is detected within a certain range, the robot will stop and decide to turn.


#define TRIG_PIN 14
#define ECHO_PIN 12

// Initialize ultrasonic sensor
void setupUltrasonic() {
    pinMode(TRIG_PIN, OUTPUT);
    pinMode(ECHO_PIN, INPUT);
}

// Measure distance using ultrasonic sensor
long getDistance() {
    digitalWrite(TRIG_PIN, LOW);
    delayMicroseconds(2);
    digitalWrite(TRIG_PIN, HIGH);
    delayMicroseconds(10);
    digitalWrite(TRIG_PIN, LOW);
    
    long duration = pulseIn(ECHO_PIN, HIGH);
    long distance = duration * 0.034 / 2; // Convert to centimeters
    return distance;
}
        

Step 5: Main Control Logic

In the main loop, we’ll implement logic that allows the robot to move forward until it detects an obstacle within a certain range. When an obstacle is detected, the robot will stop and choose a direction to turn before resuming movement.


void setup() {
    Serial.begin(115200);
    setupMotors();
    setupUltrasonic();
}

void loop() {
    long distance = getDistance();
    Serial.print("Distance: ");
    Serial.println(distance);
    
    if (distance > 20) { // Safe distance threshold (20 cm)
        moveForward();
    } else { // Obstacle detected
        stopMotors();
        delay(500); // Brief pause
        
        // Decide to turn left or right randomly
        if (random(2) == 0) {
            turnLeft();
        } else {
            turnRight();
        }
        delay(1000); // Turn for 1 second
        stopMotors();
        delay(500); // Pause after turn
    }
}
        

Step 6: Compile and Upload

Upload the code to your ESP32 using the Arduino IDE. Ensure you’ve selected the correct board and port. Once the code is uploaded, the robot should be able to navigate around obstacles autonomously.

Conclusion

With this setup, you’ve built a basic autonomous robot that can detect and avoid obstacles using an ESP32, motors, and an ultrasonic sensor. Experiment with additional sensors or refined movement logic to enhance the robot’s autonomy!