Cirkit Designer LogoCirkit DesignerYour all-in-one circuit design IDE Launch Cirkit Designer App

ESP32-Based Wi-Fi Controlled Robotic Car with Ultrasonic Obstacle Avoidance

View and Edit Project In Cirkit DesignerImage of ESP32-Based Wi-Fi Controlled Robotic Car with Ultrasonic Obstacle Avoidance

Circuit Documentation

Summary

This document provides a detailed overview of a circuit designed to control a robotic car using an ESP32 microcontroller. The car is equipped with four DC motors, an ultrasonic sensor for obstacle detection, and two L298N motor drivers to control the motors. The ESP32 microcontroller receives commands via ESP-NOW and controls the motors accordingly. The ultrasonic sensor is used to detect obstacles and stop the car if it gets too close to an object.

Component List

  1. DC Motor

    • Description: A simple DC motor used for driving the wheels of the robotic car.
    • Pins: pin 1, pin 2
  2. Battery 12V

    • Description: A 12V battery used to power the motors and motor drivers.
    • Pins: +, -
  3. ESP32 38 PINS

    • Description: A microcontroller used to control the motors and receive commands via ESP-NOW.
    • Pins: GND, 23, 22/SCL, 1, 2, 21/SDA, 19, 18, 5, 17/TX2, 16/RX2, 4, 0, 15, D1, D0, CLK, 3V3, EN, VP, VN, 34, 35, 32, 33, 25, 26, 27, 14, 12, 13, D2, D3, 11, 5V/VIN
  4. L298N DC Motor Driver

    • Description: A motor driver used to control the speed and direction of the DC motors.
    • Pins: OUT1, OUT2, 12V, GND, 5V, OUT3, OUT4, 5V-ENA-JMP-I, 5V-ENA-JMP-O, +5V-J1, +5V-J2, ENA, IN1, IN2, IN3, IN4, ENB
  5. Ultrasonic Sensor

    • Description: A sensor used to measure the distance to obstacles in front of the car.
    • Pins: +VCC, Trigger, Echo, GND

Wiring Details

DC Motor

Battery 12V

ESP32 38 PINS

L298N DC Motor Driver

Ultrasonic Sensor

Documented Code

#include <esp_now.h>
#include <WiFi.h>

#define FORWARD 1
#define BACKWARD 2
#define LEFT 3
#define RIGHT 4
#define FORWARD_LEFT 5
#define FORWARD_RIGHT 6
#define BACKWARD_LEFT 7
#define BACKWARD_RIGHT 8
#define TURN_LEFT 9
#define TURN_RIGHT 10
#define STOP 0

#define BACK_RIGHT_MOTOR 0
#define BACK_LEFT_MOTOR 1
#define FRONT_RIGHT_MOTOR 2
#define FRONT_LEFT_MOTOR 3
const int trigPin = 2;
const int echoPin = 3;
struct MOTOR_PINS
{
  int pinIN1;
  int pinIN2;
  int pinEn; 
  int pwmSpeedChannel;
};

std::vector<MOTOR_PINS> motorPins = 
{
  {16, 17, 22, 4},  //BACK_RIGHT_MOTOR
  {18, 19, 23, 5},  //BACK_LEFT_MOTOR
  {26, 27, 14, 6},  //FRONT_RIGHT_MOTOR
  {33, 25, 32, 7},  //FRONT_LEFT_MOTOR   
};

#define MAX_MOTOR_SPEED 200

const int PWMFreq = 1000; /* 1 KHz */
const int PWMResolution = 8;

#define SIGNAL_TIMEOUT 1000  // This is signal timeout in milli seconds. We will reset the data if no signal
unsigned long lastRecvTime = 0;

struct PacketData
{
  byte xAxisValue;
  byte yAxisValue;
  byte zAxisValue;
};
PacketData receiverData;

// callback function that will be executed when data is received
void OnDataRecv(const uint8_t * mac, const uint8_t *incomingData, int len) 
{
  if (len == 0)
  {
    return;
  }
  memcpy(&receiverData, incomingData, sizeof(receiverData));
  String inputData ;
  inputData = inputData + "values " + receiverData.xAxisValue + "  " + receiverData.yAxisValue + "  " + receiverData.zAxisValue;
  Serial.println(inputData);

  if ( receiverData.xAxisValue < 75 && receiverData.y