Wi-Fi Controlled Robotic Car with ESP32-CAM and L298N Motor Driver
View and Edit Project In Cirkit Designer
Circuit Documentation
Summary
This circuit is designed to control a Wi-Fi-enabled car with a camera using an ESP32-CAM module. The car is powered by a 3.7V battery and uses an L298N motor driver to control four DC motors. Additionally, an MQ-5 gas sensor is included in the circuit for gas detection. The ESP32-CAM module handles the camera functionality and provides a web interface for controlling the car.
Component List
L298N DC Motor Driver
- Description: Motor driver module used to control 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
ESP32-CAM
- Description: Microcontroller with built-in camera and Wi-Fi capabilities.
- Pins: 5V, GND, IO12, IO13, IO15, IO14, IO2, IO4, VOT, VOR, VCC, IO0, IO16, 3V3
3.7V Battery
- Description: Power source for the circuit.
- Pins: +, -
DC Motor
- Description: Motor used for driving the car.
- Pins: pin 1, pin 2
MQ-5 Gas Sensor
- Description: Sensor used for detecting gas.
- Pins: VCC, GND, Digi Out, Analog out
Wiring Details
L298N DC Motor Driver
OUT1 is connected to:
- DC Motor pin 2
- DC Motor pin 2
OUT2 is connected to:
- DC Motor pin 1
- DC Motor pin 1
12V is connected to:
- 3.7V Battery +
GND is connected to:
- MQ-5 Gas Sensor GND
- ESP32-CAM GND
- 3.7V Battery -
5V is connected to:
- MQ-5 Gas Sensor VCC
- ESP32-CAM 5V
OUT3 is connected to:
- DC Motor pin 2
- DC Motor pin 2
OUT4 is connected to:
- DC Motor pin 1
- DC Motor pin 1
IN1 is connected to:
- ESP32-CAM IO14
IN2 is connected to:
- ESP32-CAM IO15
IN3 is connected to:
- ESP32-CAM IO13
IN4 is connected to:
- ESP32-CAM IO12
ESP32-CAM
GND is connected to:
- L298N DC Motor Driver GND
- MQ-5 Gas Sensor GND
- 3.7V Battery -
5V is connected to:
- L298N DC Motor Driver 5V
- MQ-5 Gas Sensor VCC
IO14 is connected to:
- L298N DC Motor Driver IN1
IO15 is connected to:
- L298N DC Motor Driver IN2
IO13 is connected to:
- L298N DC Motor Driver IN3
IO12 is connected to:
- L298N DC Motor Driver IN4
IO16 is connected to:
- MQ-5 Gas Sensor Analog out
3.7V Battery
+ is connected to:
- L298N DC Motor Driver 12V
- is connected to:
- L298N DC Motor Driver GND
- MQ-5 Gas Sensor GND
- ESP32-CAM GND
DC Motor
pin 1 is connected to:
- L298N DC Motor Driver OUT2
- L298N DC Motor Driver OUT4
pin 2 is connected to:
- L298N DC Motor Driver OUT1
- L298N DC Motor Driver OUT3
MQ-5 Gas Sensor
VCC is connected to:
- L298N DC Motor Driver 5V
- ESP32-CAM 5V
GND is connected to:
- L298N DC Motor Driver GND
- ESP32-CAM GND
- 3.7V Battery -
Analog out is connected to:
- ESP32-CAM IO16
Code Documentation
Main Code
#include "esp_camera.h"
#include <Arduino.h>
#include <WiFi.h>
#include <AsyncTCP.h>
#include <ESPAsyncWebServer.h>
#include <iostream>
#include <sstream>
struct MOTOR_PINS
{
int pinEn;
int pinIN1;
int pinIN2;
};
std::vector<MOTOR_PINS> motorPins =
{
{12, 13, 15}, //RIGHT_MOTOR Pins (EnA, IN1, IN2)
{12, 14, 2}, //LEFT_MOTOR Pins (EnB, IN3, IN4)
};
#define LIGHT_PIN 4
#define UP 1
#define DOWN 2
#define LEFT 3
#define RIGHT 4
#define STOP 0
#define RIGHT_MOTOR 0
#define LEFT_MOTOR 1
#define FORWARD 1
#define BACKWARD -1
const int PWMFreq = 1000; /* 1 KHz */
const int PWMResolution = 8;
const int PWMSpeedChannel = 2;
const int PWMLightChannel = 3;
//Camera related constants
#define PWDN_GPIO_NUM 32
#define RESET_GPIO_NUM -1
#define XCLK_GPIO_NUM 0
#define SIOD_GPIO_NUM 26
#define SIOC_GPIO_NUM 27
#define Y9_GPIO_NUM 35
#define Y8_GPIO_NUM 34
#define Y7_GPIO_NUM 39
#define Y6_GPIO_NUM 36
#define Y5_GPIO_NUM 21
#define Y4_GPIO_NUM 19
#define Y3_GPIO_NUM 18
#define Y2_GPIO_NUM 5
#define VSYNC_GPIO_NUM 25
#define HREF_GPIO_NUM 23
#define PCLK_GPIO_NUM 22
const char* ssid = "MyWiFiCar";
const char* password = "12345678";
AsyncWebServer server(80);
AsyncWebSocket wsCamera("/Camera");
AsyncWebSocket wsCarInput("/CarInput");
uint32_t cameraClientId = 0;
const char* htmlHomePage PROGMEM = R"HTMLHOMEPAGE(
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
<style>
.arrows {
font-size:40px;
color:red;
}
td.button {
background-color:black;
border-radius:25%;
box-shadow: 5px 5px #888888;
}
td.button:active {
transform: translate(5px,5px);
box-shadow: none;
}
.noselect {
-webkit-touch-callout: none; /* iOS Safari */
-webkit-user-select: none; /* Safari */
-khtml-user-select: none; /* Konqueror HTML */
-moz-user-select: none; /* Firefox */
-ms-user-select: none; /* Internet Explorer/Edge */
user-select: none; /* Non-prefixed version, currently
supported by Chrome and Opera */
}
.slidecontainer {
width: 100%;
}
.slider {
-webkit-appearance: none;
width: 100%;
height: 15px;
border-radius: 5px;
background: #d3d3d3;
outline: none;
opacity: 0.7;
-webkit-transition: .2s;
transition: opacity .2s;
}
.slider:hover {
opacity: 1;
}
.slider::-webkit-slider-thumb {
-webkit-appearance: none;
appearance: none;
width: 25px;
height: 25px;
border-radius: 50%;
background: red;
cursor: pointer;
}
.slider::-moz-range-thumb {
width: 25px;
height: 25px;
border-radius: 50%;
background: red;
cursor: pointer;
}
</style>
</