ESP32-Based 4WD Robot Car
Using Dual L298N Motor Drivers
A complete WiFi-controlled robot car project with circuit diagram, JSON configuration, step-by-step wiring guide, and full source code — ready to build.
📋 Project Overview
This project builds a fully WiFi-controlled 4-wheel-drive robot car using an ESP32 microcontroller and two L298N H-bridge motor driver modules. The ESP32 acts as a WiFi access point — you connect your phone or laptop directly, then control the robot from a browser interface using WebSockets for real-time, low-latency commands.
Each L298N controls one pair of motors (left side and right side). This dual-driver setup provides enough current headroom for sustained operation and opens the door to mecanum wheel configurations with full omnidirectional movement.
192.168.4.1 in any browser.
🔧 Components Required
⚡ Circuit Diagram
The diagram below shows how the ESP32, both L298N drivers, motors, and battery connect together. All ground rails must be tied together for stable signalling.
Simplified schematic — see wiring table below for exact connections
🔌 Pin Wiring Reference
ESP32 → L298N Driver A (Right-side motors)
| ESP32 GPIO | L298N Pin | Motor | Function |
|---|---|---|---|
| GPIO 16 | IN1 | Front Right | Direction 1 |
| GPIO 17 | IN2 | Front Right | Direction 2 |
| GPIO 18 | IN3 | Back Right | Direction 1 |
| GPIO 19 | IN4 | Back Right | Direction 2 |
| GND | GND | — | Common Ground |
| — | 12V / VIN | — | Battery + |
ESP32 → L298N Driver B (Left-side motors)
| ESP32 GPIO | L298N Pin | Motor | Function |
|---|---|---|---|
| GPIO 27 | IN1 | Front Left | Direction 1 |
| GPIO 26 | IN2 | Front Left | Direction 2 |
| GPIO 25 | IN3 | Back Left | Direction 1 |
| GPIO 33 | IN4 | Back Left | Direction 2 |
| GND | GND | — | Common Ground |
| — | 12V / VIN | — | Battery + |
🛠️ Step-by-Step Build Guide
ESPAsyncWebServer + AsyncTCP libraries. Open the sketch, update the SSID/password constants if needed, then upload via USB. Open Serial Monitor at 115200 baud to confirm the AP IP address.🕹️ Movement Logic (Mecanum Wheels)
The code sends values 0–10 over WebSocket. Each value maps to a motor direction pattern. For mecanum wheels, diagonal strafing is achieved by spinning specific wheels forward and others backward simultaneously.
| Command | Value | FR | BR | FL | BL |
|---|---|---|---|---|---|
| Forward | 1 | FWD | FWD | FWD | FWD |
| Backward | 2 | BWD | BWD | BWD | BWD |
| Strafe Left | 3 | FWD | BWD | BWD | FWD |
| Strafe Right | 4 | BWD | FWD | FWD | BWD |
| Diagonal ↖ | 5 | FWD | STOP | STOP | FWD |
| Diagonal ↗ | 6 | STOP | FWD | FWD | STOP |
| Diagonal ↙ | 7 | STOP | BWD | BWD | STOP |
| Diagonal ↘ | 8 | BWD | STOP | STOP | BWD |
| Turn Left | 9 | FWD | FWD | BWD | BWD |
| Turn Right | 10 | BWD | BWD | FWD | FWD |
| Stop | 0 | STOP | STOP | STOP | STOP |
💻 Full Source Code
Copy and paste into Arduino IDE. Update the SSID and password to match your desired network name. The WebSocket server handles all 10 movement commands plus auto-stop on disconnect.
#include <Arduino.h> #ifdef ESP32 #include <WiFi.h> #include <AsyncTCP.h> #elif defined(ESP8266) #include <ESP8266WiFi.h> #include <ESPAsyncTCP.h> #endif #include <ESPAsyncWebServer.h> // Movement command definitions #define UP 1 #define DOWN 2 #define LEFT 3 #define RIGHT 4 #define UP_LEFT 5 #define UP_RIGHT 6 #define DOWN_LEFT 7 #define DOWN_RIGHT 8 #define TURN_LEFT 9 #define TURN_RIGHT 10 #define STOP 0 // Motor index definitions #define FRONT_RIGHT_MOTOR 0 #define BACK_RIGHT_MOTOR 1 #define FRONT_LEFT_MOTOR 2 #define BACK_LEFT_MOTOR 3 #define FORWARD 1 #define BACKWARD -1 struct MOTOR_PINS { int pinIN1; int pinIN2; }; std::vector<MOTOR_PINS> motorPins = { {16, 17}, // FRONT_RIGHT_MOTOR {18, 19}, // BACK_RIGHT_MOTOR {27, 26}, // FRONT_LEFT_MOTOR {25, 33}, // BACK_LEFT_MOTOR }; const char* ssid = "MakeMindz-Robot"; const char* password = "robot12345"; AsyncWebServer server(80); AsyncWebSocket ws("/ws"); // ... (full HTML page and logic as shown below) void rotateMotor(int motorNumber, int motorDirection) { if (motorDirection == FORWARD) { digitalWrite(motorPins[motorNumber].pinIN1, HIGH); digitalWrite(motorPins[motorNumber].pinIN2, LOW); } else if (motorDirection == BACKWARD) { digitalWrite(motorPins[motorNumber].pinIN1, LOW); digitalWrite(motorPins[motorNumber].pinIN2, HIGH); } else { digitalWrite(motorPins[motorNumber].pinIN1, LOW); digitalWrite(motorPins[motorNumber].pinIN2, LOW); } } void processCarMovement(String inputValue) { switch(inputValue.toInt()) { case UP: rotateMotor(FRONT_RIGHT_MOTOR, FORWARD); rotateMotor(BACK_RIGHT_MOTOR, FORWARD); rotateMotor(FRONT_LEFT_MOTOR, FORWARD); rotateMotor(BACK_LEFT_MOTOR, FORWARD); break; case DOWN: rotateMotor(FRONT_RIGHT_MOTOR, BACKWARD); rotateMotor(BACK_RIGHT_MOTOR, BACKWARD); rotateMotor(FRONT_LEFT_MOTOR, BACKWARD); rotateMotor(BACK_LEFT_MOTOR, BACKWARD); break; case LEFT: rotateMotor(FRONT_RIGHT_MOTOR, FORWARD); rotateMotor(BACK_RIGHT_MOTOR, BACKWARD); rotateMotor(FRONT_LEFT_MOTOR, BACKWARD); rotateMotor(BACK_LEFT_MOTOR, FORWARD); break; case RIGHT: rotateMotor(FRONT_RIGHT_MOTOR, BACKWARD); rotateMotor(BACK_RIGHT_MOTOR, FORWARD); rotateMotor(FRONT_LEFT_MOTOR, FORWARD); rotateMotor(BACK_LEFT_MOTOR, BACKWARD); break; // ... (UP_LEFT, UP_RIGHT, DOWN_LEFT, DOWN_RIGHT, TURN_LEFT, TURN_RIGHT) default: rotateMotor(FRONT_RIGHT_MOTOR, STOP); rotateMotor(BACK_RIGHT_MOTOR, STOP); rotateMotor(FRONT_LEFT_MOTOR, STOP); rotateMotor(BACK_LEFT_MOTOR, STOP); break; } } void setup() { for (int i = 0; i < motorPins.size(); i++) { pinMode(motorPins[i].pinIN1, OUTPUT); pinMode(motorPins[i].pinIN2, OUTPUT); rotateMotor(i, STOP); } Serial.begin(115200); WiFi.softAP(ssid, password); Serial.print("AP IP: "); Serial.println(WiFi.softAPIP()); ws.onEvent(onWebSocketEvent); server.addHandler(&ws); server.on("/", HTTP_GET, handleRoot); server.begin(); } void loop() { ws.cleanupClients(); }
🖥️ Run the Simulation
Open the project in one of these supported simulation platforms to test the circuit before building hardware:
🚀 Extensions & Next Steps
- Add an HC-SR04 ultrasonic sensor for automatic obstacle detection and avoidance
- Integrate IR line sensors under the chassis for line-following mode
- Add a camera module (OV2640) for live FPV video streaming via the ESP32-CAM
- Enable Bluetooth control using the ESP32's built-in BLE and a custom Android app
- Replace breadboard wiring with a custom PCB for competition-ready builds
- Add PWM speed control by enabling the ENA/ENB pins on the L298N with
ledcWrite()
Comments
Post a Comment