Build a Wi-Fi remote controlled car robot with the ESP32-CAM. You’ll be able to control the robot using a web server that displays a video streaming of what the robot “sees”. You can control your robot remotely even if it’s out of your sight. The ESP32-CAM will be programmed using Arduino IDE.
Boards compatibility: this project requires 4 GPIOs to control the DC motors. So, you can use any ESP32 camera board with 4 available GPIOs like the ESP32-CAM Ai-Thinker board or the TTGO T-Journal.
Project Overview
Before starting the project, we’ll highlight the most important features and components used to build the robot.
Wi-Fi
The robot will be controlled via Wi-Fi using your ESP32-CAM. We’ll create a web-based interface to control the robot, that can be accessed in any device inside your local network.
The web page also shows a video streaming of what the robot “sees”. For good results with video streaming, we recommend using an ESP32-CAM with external antenna.
Important: without an external antenna the video stream lags and the web server is extremely slow to control the robot.
Robot Controls
The web server has 5 controls: Forward, Backward, Left, Right, and Stop.
The robot moves as long as you’re pressing the buttons. When you release any button, the robot stops. However, we’ve included the Stop button that can be useful in case the ESP32 doesn’t receive the stop command when you release a button.
Smart Robot Chassis Kit
We’re going to use the Smart Robot Chassis Kit. You can find it in most online stores. The kit costs around $10 and it’s easy to assemble – watch this video to see how to assemble the robot chassis kit.
You can use any other chassis kit as long as it comes with two DC motors.
L298N Motor Driver
There are many ways to control DC motors. We’ll use the L298N motor driver that provides an easy way to control the speed and direction of 2 DC motors.
We won’t explain how the L298N motor driver works. You can read the following article for an in-depth tutorial about the L298N motor driver:
Power
To keep the circuitry simple, we’ll power the robot (motors) and the ESP32 using the same power source. We used a power bank/portable charger (like the ones used to charge your smartphone) and it worked well.
Note: the motors draw a lot of current, so if you feel your robot is not moving properly, you may need to use an external power supply for the motors. This means you need two different power sources. One to power the DC motors, and the other to power the ESP32.
Parts Required
For this project, we’ll use the following parts:
- ESP32-CAM AI-Thinker with external antenna
- L298N Motor Driver
- Robot Car Chassis Kit
- Power bank or other 5V power supply
- Prototyping circuit board (optional)
You can use the preceding links or go directly to MakerAdvisor.com/tools to find all the parts for your projects at the best price!
Code
Copy the following code to your Arduino IDE.
/*********
Rui Santos
Complete instructions at https://RandomNerdTutorials.com/esp32-cam-projects-ebook/
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files.
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
*********/
#include "esp_camera.h"
#include <WiFi.h>
#include "esp_timer.h"
#include "img_converters.h"
#include "Arduino.h"
#include "fb_gfx.h"
#include "soc/soc.h" // disable brownout problems
#include "soc/rtc_cntl_reg.h" // disable brownout problems
#include "esp_http_server.h"
// Replace with your network credentials
const char* ssid = "REPLACE_WITH_YOUR_SSID";
const char* password = "REPLACE_WITH_YOUR_PASSWORD";
#define PART_BOUNDARY "123456789000000000000987654321"
#define CAMERA_MODEL_AI_THINKER
//#define CAMERA_MODEL_M5STACK_PSRAM
//#define CAMERA_MODEL_M5STACK_WITHOUT_PSRAM
//#define CAMERA_MODEL_M5STACK_PSRAM_B
//#define CAMERA_MODEL_WROVER_KIT
#if defined(CAMERA_MODEL_WROVER_KIT)
#define PWDN_GPIO_NUM -1
#define RESET_GPIO_NUM -1
#define XCLK_GPIO_NUM 21
#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 19
#define Y4_GPIO_NUM 18
#define Y3_GPIO_NUM 5
#define Y2_GPIO_NUM 4
#define VSYNC_GPIO_NUM 25
#define HREF_GPIO_NUM 23
#define PCLK_GPIO_NUM 22
#elif defined(CAMERA_MODEL_M5STACK_PSRAM)
#define PWDN_GPIO_NUM -1
#define RESET_GPIO_NUM 15
#define XCLK_GPIO_NUM 27
#define SIOD_GPIO_NUM 25
#define SIOC_GPIO_NUM 23
#define Y9_GPIO_NUM 19
#define Y8_GPIO_NUM 36
#define Y7_GPIO_NUM 18
#define Y6_GPIO_NUM 39
#define Y5_GPIO_NUM 5
#define Y4_GPIO_NUM 34
#define Y3_GPIO_NUM 35
#define Y2_GPIO_NUM 32
#define VSYNC_GPIO_NUM 22
#define HREF_GPIO_NUM 26
#define PCLK_GPIO_NUM 21
#elif defined(CAMERA_MODEL_M5STACK_WITHOUT_PSRAM)
#define PWDN_GPIO_NUM -1
#define RESET_GPIO_NUM 15
#define XCLK_GPIO_NUM 27
#define SIOD_GPIO_NUM 25
#define SIOC_GPIO_NUM 23
#define Y9_GPIO_NUM 19
#define Y8_GPIO_NUM 36
#define Y7_GPIO_NUM 18
#define Y6_GPIO_NUM 39
#define Y5_GPIO_NUM 5
#define Y4_GPIO_NUM 34
#define Y3_GPIO_NUM 35
#define Y2_GPIO_NUM 17
#define VSYNC_GPIO_NUM 22
#define HREF_GPIO_NUM 26
#define PCLK_GPIO_NUM 21
#elif defined(CAMERA_MODEL_AI_THINKER)
#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
#elif defined(CAMERA_MODEL_M5STACK_PSRAM_B)
#define PWDN_GPIO_NUM -1
#define RESET_GPIO_NUM 15
#define XCLK_GPIO_NUM 27
#define SIOD_GPIO_NUM 22
#define SIOC_GPIO_NUM 23
#define Y9_GPIO_NUM 19
#define Y8_GPIO_NUM 36
#define Y7_GPIO_NUM 18
#define Y6_GPIO_NUM 39
#define Y5_GPIO_NUM 5
#define Y4_GPIO_NUM 34
#define Y3_GPIO_NUM 35
#define Y2_GPIO_NUM 32
#define VSYNC_GPIO_NUM 25
#define HREF_GPIO_NUM 26
#define PCLK_GPIO_NUM 21
#else
#error "Camera model not selected"
#endif
#define MOTOR_1_PIN_1 14
#define MOTOR_1_PIN_2 15
#define MOTOR_2_PIN_1 13
#define MOTOR_2_PIN_2 12
static const char* _STREAM_CONTENT_TYPE = "multipart/x-mixed-replace;boundary=" PART_BOUNDARY;
static const char* _STREAM_BOUNDARY = "\r\n--" PART_BOUNDARY "\r\n";
static const char* _STREAM_PART = "Content-Type: image/jpeg\r\nContent-Length: %u\r\n\r\n";
httpd_handle_t camera_httpd = NULL;
httpd_handle_t stream_httpd = NULL;
static const char PROGMEM INDEX_HTML[] = R"rawliteral(
<html>
<head>
<title>ESP32-CAM Robot</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>
body { font-family: Arial; text-align: center; margin:0px auto; padding-top: 30px;}
table { margin-left: auto; margin-right: auto; }
td { padding: 8 px; }
.button {
background-color: #2f4468;
border: none;
color: white;
padding: 10px 20px;
text-align: center;
text-decoration: none;
display: inline-block;
font-size: 18px;
margin: 6px 3px;
cursor: pointer;
-webkit-touch-callout: none;
-webkit-user-select: none;
-khtml-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
-webkit-tap-highlight-color: rgba(0,0,0,0);
}
img { width: auto ;
max-width: 100% ;
height: auto ;
}
</style>
</head>
<body>
<h1>ESP32-CAM Robot</h1>
<img src="" id="photo" >
<table>
<tr><td colspan="3" align="center"><button class="button" onmousedown="toggleCheckbox('forward');" ontouchstart="toggleCheckbox('forward');" onmouseup="toggleCheckbox('stop');" ontouchend="toggleCheckbox('stop');">Forward</button></td></tr>
<tr><td align="center"><button class="button" onmousedown="toggleCheckbox('left');" ontouchstart="toggleCheckbox('left');" onmouseup="toggleCheckbox('stop');" ontouchend="toggleCheckbox('stop');">Left</button></td><td align="center"><button class="button" onmousedown="toggleCheckbox('stop');" ontouchstart="toggleCheckbox('stop');">Stop</button></td><td align="center"><button class="button" onmousedown="toggleCheckbox('right');" ontouchstart="toggleCheckbox('right');" onmouseup="toggleCheckbox('stop');" ontouchend="toggleCheckbox('stop');">Right</button></td></tr>
<tr><td colspan="3" align="center"><button class="button" onmousedown="toggleCheckbox('backward');" ontouchstart="toggleCheckbox('backward');" onmouseup="toggleCheckbox('stop');" ontouchend="toggleCheckbox('stop');">Backward</button></td></tr>
</table>
<script>
function toggleCheckbox(x) {
var xhr = new XMLHttpRequest();
xhr.open("GET", "/action?go=" + x, true);
xhr.send();
}
window.onload = document.getElementById("photo").src = window.location.href.slice(0, -1) + ":81/stream";
</script>
</body>
</html>
)rawliteral";
static esp_err_t index_handler(httpd_req_t *req){
httpd_resp_set_type(req, "text/html");
return httpd_resp_send(req, (const char *)INDEX_HTML, strlen(INDEX_HTML));
}
static esp_err_t stream_handler(httpd_req_t *req){
camera_fb_t * fb = NULL;
esp_err_t res = ESP_OK;
size_t _jpg_buf_len = 0;
uint8_t * _jpg_buf = NULL;
char * part_buf[64];
res = httpd_resp_set_type(req, _STREAM_CONTENT_TYPE);
if(res != ESP_OK){
return res;
}
while(true){
fb = esp_camera_fb_get();
if (!fb) {
Serial.println("Camera capture failed");
res = ESP_FAIL;
} else {
if(fb->width > 400){
if(fb->format != PIXFORMAT_JPEG){
bool jpeg_converted = frame2jpg(fb, 80, &_jpg_buf, &_jpg_buf_len);
esp_camera_fb_return(fb);
fb = NULL;
if(!jpeg_converted){
Serial.println("JPEG compression failed");
res = ESP_FAIL;
}
} else {
_jpg_buf_len = fb->len;
_jpg_buf = fb->buf;
}
}
}
if(res == ESP_OK){
size_t hlen = snprintf((char *)part_buf, 64, _STREAM_PART, _jpg_buf_len);
res = httpd_resp_send_chunk(req, (const char *)part_buf, hlen);
}
if(res == ESP_OK){
res = httpd_resp_send_chunk(req, (const char *)_jpg_buf, _jpg_buf_len);
}
if(res == ESP_OK){
res = httpd_resp_send_chunk(req, _STREAM_BOUNDARY, strlen(_STREAM_BOUNDARY));
}
if(fb){
esp_camera_fb_return(fb);
fb = NULL;
_jpg_buf = NULL;
} else if(_jpg_buf){
free(_jpg_buf);
_jpg_buf = NULL;
}
if(res != ESP_OK){
break;
}
//Serial.printf("MJPG: %uB\n",(uint32_t)(_jpg_buf_len));
}
return res;
}
static esp_err_t cmd_handler(httpd_req_t *req){
char* buf;
size_t buf_len;
char variable[32] = {0,};
buf_len = httpd_req_get_url_query_len(req) + 1;
if (buf_len > 1) {
buf = (char*)malloc(buf_len);
if(!buf){
httpd_resp_send_500(req);
return ESP_FAIL;
}
if (httpd_req_get_url_query_str(req, buf, buf_len) == ESP_OK) {
if (httpd_query_key_value(buf, "go", variable, sizeof(variable)) == ESP_OK) {
} else {
free(buf);
httpd_resp_send_404(req);
return ESP_FAIL;
}
} else {
free(buf);
httpd_resp_send_404(req);
return ESP_FAIL;
}
free(buf);
} else {
httpd_resp_send_404(req);
return ESP_FAIL;
}
sensor_t * s = esp_camera_sensor_get();
int res = 0;
if(!strcmp(variable, "forward")) {
Serial.println("Forward");
digitalWrite(MOTOR_1_PIN_1, 1);
digitalWrite(MOTOR_1_PIN_2, 0);
digitalWrite(MOTOR_2_PIN_1, 1);
digitalWrite(MOTOR_2_PIN_2, 0);
}
else if(!strcmp(variable, "left")) {
Serial.println("Left");
digitalWrite(MOTOR_1_PIN_1, 0);
digitalWrite(MOTOR_1_PIN_2, 1);
digitalWrite(MOTOR_2_PIN_1, 1);
digitalWrite(MOTOR_2_PIN_2, 0);
}
else if(!strcmp(variable, "right")) {
Serial.println("Right");
digitalWrite(MOTOR_1_PIN_1, 1);
digitalWrite(MOTOR_1_PIN_2, 0);
digitalWrite(MOTOR_2_PIN_1, 0);
digitalWrite(MOTOR_2_PIN_2, 1);
}
else if(!strcmp(variable, "backward")) {
Serial.println("Backward");
digitalWrite(MOTOR_1_PIN_1, 0);
digitalWrite(MOTOR_1_PIN_2, 1);
digitalWrite(MOTOR_2_PIN_1, 0);
digitalWrite(MOTOR_2_PIN_2, 1);
}
else if(!strcmp(variable, "stop")) {
Serial.println("Stop");
digitalWrite(MOTOR_1_PIN_1, 0);
digitalWrite(MOTOR_1_PIN_2, 0);
digitalWrite(MOTOR_2_PIN_1, 0);
digitalWrite(MOTOR_2_PIN_2, 0);
}
else {
res = -1;
}
if(res){
return httpd_resp_send_500(req);
}
httpd_resp_set_hdr(req, "Access-Control-Allow-Origin", "*");
return httpd_resp_send(req, NULL, 0);
}
void startCameraServer(){
httpd_config_t config = HTTPD_DEFAULT_CONFIG();
config.server_port = 80;
httpd_uri_t index_uri = {
.uri = "/",
.method = HTTP_GET,
.handler = index_handler,
.user_ctx = NULL
};
httpd_uri_t cmd_uri = {
.uri = "/action",
.method = HTTP_GET,
.handler = cmd_handler,
.user_ctx = NULL
};
httpd_uri_t stream_uri = {
.uri = "/stream",
.method = HTTP_GET,
.handler = stream_handler,
.user_ctx = NULL
};
if (httpd_start(&camera_httpd, &config) == ESP_OK) {
httpd_register_uri_handler(camera_httpd, &index_uri);
httpd_register_uri_handler(camera_httpd, &cmd_uri);
}
config.server_port += 1;
config.ctrl_port += 1;
if (httpd_start(&stream_httpd, &config) == ESP_OK) {
httpd_register_uri_handler(stream_httpd, &stream_uri);
}
}
void setup() {
WRITE_PERI_REG(RTC_CNTL_BROWN_OUT_REG, 0); //disable brownout detector
pinMode(MOTOR_1_PIN_1, OUTPUT);
pinMode(MOTOR_1_PIN_2, OUTPUT);
pinMode(MOTOR_2_PIN_1, OUTPUT);
pinMode(MOTOR_2_PIN_2, OUTPUT);
Serial.begin(115200);
Serial.setDebugOutput(false);
camera_config_t config;
config.ledc_channel = LEDC_CHANNEL_0;
config.ledc_timer = LEDC_TIMER_0;
config.pin_d0 = Y2_GPIO_NUM;
config.pin_d1 = Y3_GPIO_NUM;
config.pin_d2 = Y4_GPIO_NUM;
config.pin_d3 = Y5_GPIO_NUM;
config.pin_d4 = Y6_GPIO_NUM;
config.pin_d5 = Y7_GPIO_NUM;
config.pin_d6 = Y8_GPIO_NUM;
config.pin_d7 = Y9_GPIO_NUM;
config.pin_xclk = XCLK_GPIO_NUM;
config.pin_pclk = PCLK_GPIO_NUM;
config.pin_vsync = VSYNC_GPIO_NUM;
config.pin_href = HREF_GPIO_NUM;
config.pin_sccb_sda = SIOD_GPIO_NUM;
config.pin_sccb_scl = SIOC_GPIO_NUM;
config.pin_pwdn = PWDN_GPIO_NUM;
config.pin_reset = RESET_GPIO_NUM;
config.xclk_freq_hz = 20000000;
config.pixel_format = PIXFORMAT_JPEG;
if(psramFound()){
config.frame_size = FRAMESIZE_VGA;
config.jpeg_quality = 10;
config.fb_count = 2;
} else {
config.frame_size = FRAMESIZE_SVGA;
config.jpeg_quality = 12;
config.fb_count = 1;
}
// Camera init
esp_err_t err = esp_camera_init(&config);
if (err != ESP_OK) {
Serial.printf("Camera init failed with error 0x%x", err);
return;
}
// Wi-Fi connection
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.println("WiFi connected");
Serial.print("Camera Stream Ready! Go to: http://");
Serial.println(WiFi.localIP());
// Start streaming web server
startCameraServer();
}
void loop() {
}
Insert your network credentials and the code should work straight away.
const char* ssid = "REPLACE_WITH_YOUR_SSID";
const char* password = "REPLACE_WITH_YOUR_PASSWORD";
How the Code Works
Let’s take a look at the relevant parts to control the robot. Define the GPIOs that will control the motors. Each motor is controlled by two pins.
#define MOTOR_1_PIN_1 14
#define MOTOR_1_PIN_2 15
#define MOTOR_2_PIN_1 13
#define MOTOR_2_PIN_2 12
When you click the buttons, you make a request on a different URL.
<table>
<tr><td colspan="3" align="center"><button class="button" onmousedown="toggleCheckbox('forward');" ontouchstart="toggleCheckbox('forward');" onmouseup="toggleCheckbox('stop');" ontouchend="toggleCheckbox('stop');">Forward</button></td></tr>
<tr><td align="center"><button class="button" onmousedown="toggleCheckbox('left');" ontouchstart="toggleCheckbox('left');" onmouseup="toggleCheckbox('stop');" ontouchend="toggleCheckbox('stop');">Left</button></td><td align="center"><button class="button" onmousedown="toggleCheckbox('stop');" ontouchstart="toggleCheckbox('stop');">Stop</button></td><td align="center"><button class="button" onmousedown="toggleCheckbox('right');" ontouchstart="toggleCheckbox('right');" onmouseup="toggleCheckbox('stop');" ontouchend="toggleCheckbox('stop');">Right</button></td></tr>
<tr><td colspan="3" align="center"><button class="button" onmousedown="toggleCheckbox('backward');" ontouchstart="toggleCheckbox('backward');" onmouseup="toggleCheckbox('stop');" ontouchend="toggleCheckbox('stop');">Backward</button></td></tr>
</table>
<script>
function toggleCheckbox(x) {
var xhr = new XMLHttpRequest();
xhr.open("GET", "/action?go=" + x, true);
xhr.send();
}
window.onload = document.getElementById("photo").src = window.location.href.slice(0, -1) + ":81/stream";
</script>
Here’s the requests made depending on the button that is being pressed:
Forward:
<ESP_IP_ADDRESS>/action?go=forward
Backward:
/action?go=backward
Left:
/action?go=left
Right:
/action?go=right
Stop:
/action?go=stop
When you release the button, a request is made on the /action?go=stop URL. The robot only moves as long as you’re pressing the buttons.
Handle Requests
To handle what happens when we get requests on those URLs, we use these if… else statements:
if(!strcmp(variable, "forward")) {
Serial.println("Forward");
digitalWrite(MOTOR_1_PIN_1, 1);
digitalWrite(MOTOR_1_PIN_2, 0);
digitalWrite(MOTOR_2_PIN_1, 1);
digitalWrite(MOTOR_2_PIN_2, 0);
}
else if(!strcmp(variable, "left")) {
Serial.println("Left");
digitalWrite(MOTOR_1_PIN_1, 0);
digitalWrite(MOTOR_1_PIN_2, 1);
digitalWrite(MOTOR_2_PIN_1, 1);
digitalWrite(MOTOR_2_PIN_2, 0);
}
else if(!strcmp(variable, "right")) {
Serial.println("Right");
digitalWrite(MOTOR_1_PIN_1, 1);
digitalWrite(MOTOR_1_PIN_2, 0);
digitalWrite(MOTOR_2_PIN_1, 0);
digitalWrite(MOTOR_2_PIN_2, 1);
}
else if(!strcmp(variable, "backward")) {
Serial.println("Backward");
digitalWrite(MOTOR_1_PIN_1, 0);
digitalWrite(MOTOR_1_PIN_2, 1);
digitalWrite(MOTOR_2_PIN_1, 0);
digitalWrite(MOTOR_2_PIN_2, 1);
}
else if(!strcmp(variable, "stop")) {
Serial.println("Stop");
digitalWrite(MOTOR_1_PIN_1, 0);
digitalWrite(MOTOR_1_PIN_2, 0);
digitalWrite(MOTOR_2_PIN_1, 0);
digitalWrite(MOTOR_2_PIN_2, 0);
}
Testing the Code
After inserting your network credentials, you can upload the code to your ESP32-CAM board. If you don’t know how to upload code to the board, follow the next tutorial:
After uploading, open the Serial Monitor to get its IP address.
Open a browser and type the ESP IP address. A similar web page should load:
Press the buttons and take a look at the Serial Monitor to see if it is streaming without lag and if it is receiving the commands without crashing.
If everything is working properly, it’s time to assemble the circuit.
Circuit
After assembling the robot chassis, you can wire the circuit by following the next schematic diagram.
Start by connecting the ESP32-CAM to the motor driver as shown in the schematic diagram. You can either use a mini breadboard or a stripboard to place your ESP32-CAM and build the circuit.
The following table shows the connections between the ESP32-CAM and the L298N Motor Driver.
L298N Motor Driver | ESP32-CAM |
IN1 | GPIO 14 |
IN2 | GPIO 15 |
IN3 | GPIO 13 |
IN4 | GPIO 12 |
We assembled all the connections on a mini stripboard as shown below.
After that, wire each motor to its terminal block.
Note: we suggest soldering a 0.1 uF ceramic capacitor to the positive and negative terminals of each motor, as shown in the diagram to help smooth out any voltage spikes. Additionally, you can solder a slider switch to the red wire that comes from the power bank. This way, you can turn the power on and off.
Finally, apply power with a power bank as shown in the schematic diagram. You need to strip a USB cable. In this example, the ESP32-CAM and the motors are being powered using the same power source and it works well.
Note: the motors draw a lot of current, so if you feel your robot is not moving fast enough, you may need to use an external power supply for the motors. This means you need two different power sources. One to power the DC motors, and the other to power the ESP32. You can use a 4 AA battery pack to power the motors. When you get your robot chassis kit, you usually get a battery holder for 4 AA batteries.
Your robot should look similar to the following figure:
Don’t forget that you should use an external antenna with the ESP32-CAM, otherwise the web server might be extremely slow.
Demonstration
Open a browser on the ESP32-CAM IP address, and you should be able to control your robot. The web server works well on a laptop computer or smartphone.
You can only have the web server open in one device/tab at a time.
Wrapping Up
In this tutorial you’ve learned how to build a remote controlled robot using the ESP32-CAM and how to control it using a web server.
Controlling DC motors with the ESP32-CAM is the same as controlling them using a “regular” ESP32. Read this tutorial to learn more: ESP32 with DC Motor and L298N Motor Driver – Control Speed and Direction.
If you want to control your robot outside the range of your local network, you might consider setting the ESP32-CAM as an access point. This way, the ESP32-CAM doesn’t need to connect to your router, it creates its own wi-fi network and nearby wi-fi devices like your smartphone can connect to it.
For more projects and tutorials with the ESP32-CAM:
I am always surprised by your funny and motivating projects. This project again. A little hint regarding the human interface: There is a nice JS joystick that can be used by the control of mobile robots (see link). Regards Wijnand…
Hi.
That’s an interesting alternative way of controlling the robot.
Thanks for sharing.
Regards,
Sara
But i cant find a vid (its easier with a vid)
JS joystick – where is the link hidden?
Thank you for the one more interesting project
You’re welcome.
Regards,
Sara
Hello
Very nice project which can follow, I think, to the excellent tutorial “ESP32-CAM Pan and Tilt video streaming web server (2 axes)”
https://randomnerdtutorials.com/esp32-cam-pan-and-tilt-2-axis/#comment-630951
Thanks, that’s great
Hallo…
How could I extend I/O esp32-cam with PCF8574?
Thank and kiss…
Hi.
We don’t have any tutorials about that.
Search for a tutorial with that module and the ESP32. It will be similar for the ESP32-CAM.
Regards,
Sara
have you had any luck with the PCF8574 and the ESP32-CAM . I too need more I/O’s from it.
SIR I AM INTREST FOR FACERECOGNITATION DOOR LOCK SYSTEM.
PLEASE SEND ME CODE .
Thank you
“How could I extend I/O esp32-cam with PCF8574?”
I made a project using an I2C interface:
#define I2C_SDA 13
#define I2C_SCL 15
You may have to disable any pullups on these lines during programming
int SCLpin = I2C_SCL;
int SDApin = I2C_SDA;
/* setup /
Wire.begin(SDApin, SCLpin);
/ code specific to your chip */
Hello
It would be nice to monitor the streamed video on another esp32 (connected to a tft display or likewise). Something like a remote monitor.
Do you have any suggestions? I did not find any tutorial.
Thanks!
Hi, interesting project from different points of view.
I would be interested in your last suggested solution, and that is to set esp as the access point.
Thank you guys.
Where I can find the ESP32-CAM IP address?
Hi.
After uploading the code, remove GPIO 0 from GND, open the Serial Monitor and press the RST button.
The IP address will be printed on the Serial Monitor.
Regards,
Sara
Done but I get only this;
ets Jun 8 2016 00:22:57
rst:0x1 (POWERON_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:1
load:0x3fff0018,len:4
load:0x3fff001c,len:1216
ho 0 tail 12 room 4
load:0x40078000,len:9720
ho 0 tail 12 room 4
load:0x40080400,len:6352
entry 0x400806b8
Testing DC Motor…Moving Forward
Motor stopped
Moving Backwards
Motor stopped
Forward with duty cycle: 200
Forward with duty cycle: 205
Forward with duty cycle: 210
Sorry Sara,
I uploaded the wrong sketch, all Ok following your instructions.
Thanks
Renzo
Great!
Realy very good project.
Iam very happy.
thank you
All runned very well, but now suddenly in my smartphone Android i get only this message:
“header files are too long for server to interpret”.
What happen, what have I to do?
Thanks
Renzo
Thanks for a very nice project but may I ask where can I find esp_camera.h.
Dear Sara,
as I wrote in a my previus post the sketck runned perfectly in my smartphone.
Now I get only this message :“header files are too long for server to interpret”.
On the serial monitor I continue di see all command an the imagine.
I tried to find the solution on the Web bud i didn’t get any reply.
There is someone that can help me.
Thanks
Renzo
Hi.
I’m sorry, but I don’t know how to solve that issue.
See these suggestions:
– https://rntlab.com/question/esp32-camera-headers-and-browser/
– https://stackoverflow.com/questions/67849381/esp32-httpd-header-fields-are-too-long-for-the-server-to-interpret
I’m not sure if this works, but I hope it helps.
Regards,
Sara
Hi Sara,
many thanks, but no success. Smartphon doesn’t run but serial monitor do.
You are always great.
Renzo
Hi Rui and Sara, the ESP32-CAM set Access Point works fine but the Remote Control Car Robot doesn’t connect to Wi.Fi – on the Serial Monitor the IP Address never comes up and
it shows Flash Read err , 1000.
Any suggestions?
Thanks
Hi.
Can you tell me the exact error that you get? Do you get it in the Serial Monitor?
Regards,
Sara
Hi Sara, the serial monitor reads : rst:0x1 (POWERON_RESET), boot:0x13 (SPI_FAST_FLASH_BOOT)
flash read err, 1000
est_main.c 371
rst:0x10 (RICWDI_RTC_RESER),boot:0x13 (SPI_FAST_FLAS_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:1
load:0x3fff0018,len 4
load:0xfff001c,len1216
ho ) tail 12 room 4
load:0x40078000,10944
load:0x40080400,len:6388
entry 0x400806b4
………………………………………………………………………………………………………………………………
so the err is 1000 and it doesn’t give any IP address.
Any idea where I may be going wrong?
Thanks
Hi.
Can you first double-check that you’ve inserted the right network credentials?
Because you have a lot of dots being printed on the Serial Monitor, and that means that it can’t connect to Wi-Fi.
Then, disconnect all circuitry from your ESP32-CAM before uploading the code.
Get your ESP32-CAM IP address.
Then, wire the circuit and restart the ESP32-CAM.
I hope this helps.
Regards,
Sara
Hello, thanks for all the helpful information, I have a similar project that I am working on, only my project bot requires lots of GPIO pins. I added a second ESP32(not a camera board) to accommodate for GPIO pins. But now i have become curious if the esp32 cam could stream the camera data to the ESP32 via ESPNOW ? My esp32 cam does not have an external antenna for the Wi-Fi connection but the ESP32 can connect an antenna using GPIO pins. My bot has a lot going on, and not sure how to get going properly. Thanks again for all the hard work.
Hi.
ESP-NOW only supports sending a small number of bytes. See our ESP-NOW tutorial: https://randomnerdtutorials.com/esp-now-esp32-arduino-ide/
So, you can’t stream the camera data using that communication protocol.
Regards,
Sara
thanks for all the help from the website.
I have come back to my rover project after some time now, and i am confused on how to use Wi-Fi with my project. My ESP32-CAM is mounted to a pan/tilt servo’s on a fairly large platform. my project uses 97mm mecanum wheels, so it has four motors. I am using 2 additional ESP32’s that are connected via I2C. One is the Motor Control board and the other is the Logic board that handles all the sensor data. Currently the logic board connects to a PS4 controller to be able to drive the rover around. the ESP32-CAM is only providing a video steam. How can I connect the Logic Board with the ESP32-CAM to provide controls from the Camera Web Server instead of using the PS4 controller?
Hi Sara, I use the SSID : “ESP32-CAM” and password :”NULL”
I also changed the password to “123456789” that of course didn’t make any changes.
in the tools I changed the flash mode from “QIO” to “DIO” and also made no changes.
The fact is that if I load the sketch “Camera Web Server Access Point” every thing works as expected and I get the IP Address.
It sounds to me like there is something wrong in the Wi.Fi connection part of the sketch, maybe a miss print I can’t detect?
I hate to be so insistent but I would really like to get this sketch to work as it seems to be working for other people.
Thanks again
Hi.
Did you disconnect all peripherals before uploading the code?
Regards,
Sara
Hi
Yes of course all peripherals were disconnected before uploading the code.
When I upload the Camera Web Server Access IP Address I follow exactly the same steps as when I upload the ESP32-CAM Remote control – the web server access sketch gives me the IP Address while the remote control sketch doesn’t connect to Wi-Fi.
I see you both are very busy and my interest in the project is not important it is only for kids toy.
Valeu a tentativa, obrigado por tudo.
Roberto
Hi again.
I really would like to help.
But I’m not sure what might be causing the issue.
Select the AI-Thinker ESP32-CAM board when uploading the code in Tools>Board.
If your Access point is running appropriately, it has the default IP address: 192.168.4.1
Regards,
Sara
Hi i need to build truck with 4 motor using 2*l298n driver with esp32 no cam I am searching for internet I cant find any code can one help me…
Hi.
At the moment, we don’t have any web server tutorial with DC motors. I’m planning to create a tutorial about that.
We have this getting started guide for DC motors:
– https://randomnerdtutorials.com/esp32-dc-motor-l298n-motor-driver-control-speed-direction/
Because DC motors are controlled with PWM signals, you can try one of our tutorial that control PWM for LEDs and try to adapt to DC motors.
– https://randomnerdtutorials.com/esp32-web-server-websocket-sliders/
– https://randomnerdtutorials.com/esp32-web-server-slider-pwm/
I hope this helps.
Regards,
Sara
Dear Sara
The motors works fine in esp 32 cam survielance robot car but camera not works kindly help
Hi.
Check the antenna and if the board can catch a good wi-fi signal.
Check the power supply.
Regards,
Sara
Hello,
Nice project I try to make it but car not going anyway please help me. Camera work very well
Hi.
Double-check the wiring of the motors.
Regards,
Sara
It is an interesting project and I tried to make it happen. The camera works but the motors don’t. I have checked the wiring several times. I haven’t put the antenna on yet. Could this be the problem? Thanks and congratulations.
Thanks for sharing this great project!
I have lot of cheap servos, there is a very easy mod to run servos in continuous mode, removing a small part inside servo.
Unfortunately I don´t have software skills, do you think is lot of coding adding a servo option for motoring this project?
I mean use two servos controlled by PWM outputs instead of smart robot chassis and L298N driver. This wiil be great and reduce the price of the robot
Thanks in advance
Best regards
Ernest.
Bonjour,
Joli projet fonctionnel. Téléchargement un peu difficil, mais en suivant les instructions, j’y suis parvenu.
Un petit plus en gadget peut-être? Créer un bouton pour allumer et éteindre la Led de l’ESP32 CAM.
Merci
Hello and thanks for the great tutorial!
I am still a novice in the field of micro-controller programming and therefore still have a question of understanding:
Don’t I need to download libraries before I transfer the code using the Arduino IDE?
Kind regards, Alex
Hi.
It depends on the libraries.
There are libraries that are installed by default.
When you need to install external libraries, it is mentioned in our tutorials.
Regards,
Sara
All well, but I haven’t solved an old problem. On my Android smartphone I only see this message:
“header files are too long for server to interpret”.
What can I do?
Thanks
Renzo
Thanks again for the instructions,
it all worked out great (although I’m still a beginner).
Now that my video car is driving around the apartment so nicely, however, I notice that the video image is quite dark.
Isn’t there also a onboard LED on the ESP32Cam? … how could I include it in the code?
Kind regards
Dear All,
As I like to controll this Robotcar Project from the outside world I changed my router settings in port-forwarding to the according ESP32-cam IP- address 192.168.. : myport. and switched my router setting protocol in TCP-UDP and Internal port: 80.
These settings result in just seeing the ESP32 cam- site pushbuttons but no video streaming window….
Can you advise me what to do in the router portforwarding menu to see the complete ESP32-cam site?
Thank you in advance for your reply…!
Alex
Good afternoon,
I had the same problem, I fixed opennig the port 80 and 81, at the same time. It looks like the streaming video go with other port..
Good luck. Miguel.
Hello.
nice job , love your tutorials .
please help me with some suggestions .
in the past i have done with your help , webserver for a relay to open my building door from a web page. all my neighbors love it .
now i am at the point where i want to do a webserver for esp32 cam with button for a relay so i can see who is at the building door and open it .
basically it will need to be like the one from this project but with just 1 button and user login .
thanks in advance
Hi,
How can I add in a bumper switch sensor to indicate collision and display it in the webpage below the backward button?
Thanks in advance.
Hi,
very good tutorial, thank you.
One question:
how can i display and refresh status messages on the html web screen ?
Hello , thanks for your amazing projects,
i have problem
E (125) cam_hal: cam_dma_config(280): frame buffer malloc failed
E (126) cam_hal: cam_config(364): cam_dma_config failed
E (126) camera: Camera config failed with error 0xffffffff
Camera init failed with error 0xffffffff
shows this massage on serial monitor, pls help me
Hi,
Did you find a solution ?
I’ve got the same message with all DEFINE camera..
Hi guys, thanks for posting this, was trying to proxy this out via my router to get access from my phone remotely. When I proxy the ESP32-Cam I get the following error Header fields are too long for server to interpret. (it all works great locally, I think it might be when I add a letsencrypt certificate this error shows up.
I have tried to add
config.stack_size = 4096;
config.max_resp_headers = 8;
To no avail, is there any way to get over the header error? Any advice greatly appreciated.
First of all:
Thanks for the great tutorials , thea are awesome, even for me NOOB ,
( jou should add a ” buy me a Coffee ” sponsor link to your page, i would press it 🙂
Would it be possible to make it a ” ESP32-ToyTank” when I combine
Could you pick up my idear / or just Comment “should work” or “nonsens” 🙂
i cant confirm the function of what i just wrote – i am waiting the Hardware to arrive- but after all- i get a WIFI connection, a CAM screen, all buttons, and serial output- so it COULD? work ?
=> if i add a Servo for “Barrel/ CAM ” > up/down
I am not “THAAAAK PROGRAMMING GUY”
I can copy / paste & Hope it works 🙂
– i am working on a ESP32Cam – CAMERA_MODEL_AI_THINKER
and when i include & define:
#include “esp_http_server.h”
#define SERVO_1 16
#define SERVO_STEP 5
Servo servoN1;
Servo servo1;
int servo1Pos = 0;
——————– ad to
<
table>
Up
Down
————- and at the end-continue below >
else if(!strcmp(variable, “stop”)) {
Serial.println(“Stop”);
digitalWrite(MOTOR_1_PIN_1, 0);
digitalWrite(MOTOR_1_PIN_2, 0);
digitalWrite(MOTOR_2_PIN_1, 0);
digitalWrite(MOTOR_2_PIN_2, 0);
}
— if i add there the servo part
else if(!strcmp(variable, “up”)) {
if(servo1Pos <= 170) {
servo1Pos += 10;
servo1.write(servo1Pos);
}
Serial.println(servo1Pos);
Serial.println(“Up”);
}
else if(!strcmp(variable, “down”)) {
if(servo1Pos >= 10) {
servo1Pos -= 10;
servo1.write(servo1Pos);
}
Serial.println(servo1Pos);
Serial.println(“Down”);
}
—————–finaly at >void setup() {
servo1.setPeriodHertz(50); // standard 50 hz servo
servoN1.attach(2, 1000, 2000);
servo1.attach(SERVO_1, 1000, 2000);
Hi.
I think it should work. But in the end, you need to try all the hardware and see if everything actually works together.
Regards,
Sara
Great Tutorial, I have used couple of codes from here and other sites to have the ESP Work fine, Few troubles I have though.
1. ESP resets itself after first connecting to WiFi if i make use of Battery power, It works fine with USB plugged into Laptop though.
2. How do I send a sensor data for example an Ultrasonic sensor to the webpage (Any hint would be really helpful)
Thanks
Hi.
If the ESP is constantly resetting with battery, it probably means that the battery is not supplying enough power to the ESP32-CAM.
We have many web server examples that show how to display sensor data. We don’t have a specific web server for ultrasonic sensor, but you may want to try to combine several tutorials:
– Get started with Ultrasonic sensor ESP32: https://randomnerdtutorials.com/esp32-hc-sr04-ultrasonic-arduino/
– Web Server tutorials (choose a simple one): https://randomnerdtutorials.com/?s=web+server
I hope this helps.
Regards,
Sara
Very Happy and Thanks for the great tutorials.
Please tell me the Code for return status of Robot Car:
if(!strcmp(variable, “forward”)) {
Serial.println(“Forward”);
digitalWrite(MOTOR_1_PIN_1, 1);
digitalWrite(MOTOR_1_PIN_2, 0);
digitalWrite(MOTOR_2_PIN_1, 1);
digitalWrite(MOTOR_2_PIN_2, 0);
-> ESP send back (“Forward”);
}
Many thanks for your help.
Regards,
Tam Thai
I did it this way:
char http_response[50] = “\0”; // < add this
if(!strcmp(variable, “forward”)) {
Serial.println(“Forward”);
digitalWrite(MOTOR_1_PIN_1, 1);
digitalWrite(MOTOR_1_PIN_2, 0);
digitalWrite(MOTOR_2_PIN_1, 1);
digitalWrite(MOTOR_2_PIN_2, 0);
strcpy(http_response, “Forward”); // < add this
}
at the bottom of the function you find:
return httpd_resp_send(req, NULL, 0);
replace it by:
httpd_resp_set_type(req, “text/html”);
return httpd_resp_send(req, http_response, strlen(http_response));
in the html part you find:
<
script>
function toggleCheckbox(x) {
var xhr = new XMLHttpRequest();
xhr.open(“GET”, “/action?go=” + x, true);
xhr.send();
}
replace it by:
<script>
function toggleCheckbox(x) {
var xhr = new XMLHttpRequest();
xhr.open(“GET”, “/action?go=” + x, true);
xhr.addEventListener(‘load’, function(event) {
document.getElementById(‘txtbox’).innerHTML = xhr.responseText;
});
xhr.send();
}
Sorry the html part was broken.
replace it by:
Sorry again, the html does not display correctly.
Try this:
https://drive.google.com/file/d/1LrFolJP9ouR2Twy_XJEa84Kjh1DKN381/view?usp=sharing
Hi Walter.
I did it:
char http_response[50] = “\0”; // < add this
if(!strcmp(variable, “forward”)) {
Serial.println(“Forward”);
digitalWrite(MOTOR_1_PIN_1, 1);
digitalWrite(MOTOR_1_PIN_2, 0);
digitalWrite(MOTOR_2_PIN_1, 1);
digitalWrite(MOTOR_2_PIN_2, 0);
strcpy(http_response, “Forward”); // < add this
}
But Adruino verify show notification:
exit status 1
stray ‘\342’ in program
Thanks for your helps.
Regard,
Tam Thai
Sorry, it was a problem with the character set used in this site.
If you (or me) copy the code of the postings and insert it into Arduino, you get this error message.
I fixed the above file, you should download it again.
Now it should work 😉
Best Regards, Walter
Hi, is it working?
I found an old RC tank track car and used it as a base with a 12v battery bank on board . It works great.I think I’ll have to figure a way to slow it down a bit though ,it rockets around the place 🙂
Thanks for the tutorial.
That’s great!
I’m glad this was useful.
Regards,
Sara
I put a buck converter on the input of the L298N and dropped it down to about 8v . I shouldn’t get speeding tickets now 🙂
Thanks again for the easy to follow tutorial.
Can I change 16 buttons below vedio streaming in this project
Tengo una pregunta.
Donde descargo las librerías que pide, desde el mismo Arduino IDE no las encuentro, alguien que por favor me las pudiera compartir. Gracias.
Hi.
All the used libraries are automatically included.
You don’t need to install anything. Just make sure you have an ESP32 board selected in Tools > Board.
Regards,
Sara
Olá, vi o código do Arduíno, e fiquei com algumas questões relativamente à primeira parte do código. No inicio aparece “defined(camera_model…”, sei que são definições para a camara, no entanto gostava de saber se era possível descrever o que faz cada bloco. Obrigado!
Hello
First of all great tutorial, it was really easy to build silimar car to yours.
I wanted to add length sensor to avoid crashing into walls and I managed to do that but I also wanted to display the length between car and obsticle on website but i dont know how to that using esp_http_server (in asyncwebserver it is really easy but with this library I find it really difficult). Do you now maybe how to do that? I would be very grateful for your help
Regards
Can you share how you implemented the length sensor to prevent crashing? Are you using Ultrasonic sensing for that? Also how did you incorporate the Code ? Kindly share.. I implemented the reading distance on site once and it was working, ll share it when I get access to my old laptop.
hi i was wondering where i can download the libraries for this code to work. cant seem to find any of the libraries i need. thanks
actually got the libraries working but now i have a compiling issue. getting error message ‘Y2_GPIO_NUM’ was not declared in this scope. dont know how to solve this error.
Hi.
In what line of the code do you get the error?
Regards,
Sara
error codes are gone, thanks
Hello,
Thanks for the tutorial!
However, I have an issue with the video stream: after connection, the image flickers randomly for a few seconds, and then the image is gone. The control buttons work further. If I reload the page, it is flickery again for some time and then the stream stops.
I think it is a software issue because
with the stock webserver code the camera runs fine.Anyway, I like your much simpler user interface and the control buttons.
Do you have any idea what may be wrong?
Thank you in advance!
I built the project and got it to work without major problems, and was able to make it work in both Station Mode and AP mode.
Also added a couple of buttons to the table to control the onboard LED which worked OK.
I did however run into a problem which I was able to solve but I am not certain why the fix worked.
I had the same problem with all of the buttons as follows:
Controlling the robot with my Windows 10 computer everything worked as it should.
When I would click and release my mouse on the Forward Button I would get the following on the Serial Monitor:
Forward
Stop
(Which is how it should work)
However when I controlled the Robot with my Ipad and pressed the button on the screen I got the following on the Serial Monitor
Forward
Stop
Forward
(in order to stop the robot I would have to press the Stop button)
After some experimenting I was able to solve the problem by removing the onmousedown=”toggleCheckbox(‘forward’)
[ or other run commands from the button table.]
Doing this for all of the commands in the button table solved my problem for the Ipad but I am at loss as to why?
Hey! I have an end-of-course project based on an ESP-32CAM. I’m using as a basis the code of “Video Streaming Web Server Sensor Reading”. Any ideas on how to enter code techos to control a robot with gas detection sensors?
Hey, can you add one more button to control a led on another pin, not a esp32-cam led? would love if you can teach me
Great project and tutorials all along the website. Thank you so much ! I had a lot of fun building this robot this year. I would ask the same thing as Jack… I was wondering how to add a button to put the esp-32 led on (and off). Also, if there is a way to use keyboard input to drive the robot instead of mouse ?
Anyway thank you so much ! Take care
Hi Sara, may use any other Pins free for another sensor?
I tried with GPIO 04 or GPIO 02 naming them 2 , 4 or 22 , 24 but nothins run.
Where may I find the corresponce numer of pins, I found only that one above?
Thanks
Renzo
Hi.
You refer to those pins as 4 and 2.
Which sensors are you trying to connect?
Regards,
Sara
Hi Sara, I want use two ultrasonic sensors HR-SR04, so in fact I need four pins.
Thanks
Renzo
Thank you for the great content.
How do I add the ability to turn on and off the led on the esp32cam board?
Hi.
You control it like a regular LED connected to your board.
It is connected to GPIO 4.
So,
declare it as an OUTPUT using pinMode() and then just use digitalWrite() to turn it on and off.
Here’s an example on how to blynk the LED onboard:
Regards,
Sara
if you want to take photo save to micro SD card, the led will be out the of control, i don’t know why
Hi,
control and streaming is working fine in my local network.
now, i was trying to access the camera server from the internet with FritzBox and Port forwarding (IP4). I can access the web screen and it seemed to be working fine.
But: what i see is the web screen with the buttons but NO stream.
it only shows the broken picture symbol.
Any idea?
Are you forwarding just one port? The buttons are on port 80 and the video stream is port 81.
Look at the code very carefully and you will see there are really 2 servers. I send the video to it’s own page so I can have room on the control page for sensor data. A work in progress.
I’m forwarding both ports. 80 and 81. On port 81/stream i can get the stream. But the stream does not work in the web interface. In my local network it is working
I got it!
I had to modify the forwarding ports for the stream to be (port+1) for the stream:
function getStreamSrc(aref) {
var href = aref.split(“:”);
var port = 80; // default port
if (href.length > 2) {
if (href[2].length > 0) port = +(href[2]);
}
port += 1; // increment port
return href[0] + “:” + href[1] + “:” + port + “/stream”;
}
// instead of: window.onload = document.getElementById(“photo”).src = window.location.href.slice(0, -1) +”:81/stream”;
window.onload = document.getElementById(“photo”).src = getStreamSrc(window.location.href.slice(0, -1));
I had to move the
function toggleCheckbox(x)
to the header, otherwise strange things happend.
@Sara
How do i post code snippets here correctly?
i tried
<
pre> tag but it does not work. (see my last post above)
the ” double quote is displayed in the wrong character set, it will cause an error when pasted in arduino IDE.
Hi.
It is better to upload the code to github or pastebin and then share a link to the resource.
Regards,
Sara
good Tipp.
Thank you, you do a great Job!!!
hi, how can i control this car from everywhere,not only on local network
Hi mrt, this is a different Chapter.
I can try to explain how i did it:
(If you do not understand what i’m talking about, Google can help you 😉
1) To access your local network over IP4 protocol, first you need a “Dual Stack” connection to the Internet, ask your provider to get one.
2) Then you need a “DynDNS” Adress to access your local network from outside.
3) In your router, you have to enable “port forwarding” for your ESP32-Cam.
Example: https://www.cfos.de/en/cfos-personal-net/port-forwarding/avm-fritzbox-7490.htm
You have to forward port 80 – 81.
4) If all settings are correct, you can access your ESP32-Cam from outside with:
“your-dyndns-address.80” for the web interface and “your-dyndns-address.81/stream” if you only want to access the video stream.
5) If your router changes the forwarding port number (because port 80 is already occupied) then you have to follow my instruction above of April 11, 2023.
In this case your address will be “your-dyndns-address.forwarded-port”
Let me know if it works 🙂
Hi. Maybe you can help me. I have a smart robot car v4.0 and as we know it is alredy programmed and i can control it from it’s app. The problem is i must connect my phone to wifi AP of that car. I’d like to make this car to be able to connect my LAN and i do not need each time switch between APs. I found some code for that but the problem is during upload it says there is not #include <WiFi.h>. I copied libralries from here: https://github.com/espressif/arduino-esp32 but this time it says other liblraries missed. And each time it finds new missed file. Any idea?
Hi.
Did you install the ESP32 on your Arduino IDE and did you select an ESP32 board?
https://randomnerdtutorials.com/installing-the-esp32-board-in-arduino-ide-windows-instructions/
Regards,
Sara
Hi,
Great tutorial, thanks!
In relation to the code, I have a doubt:
I don’t understand the logic of the use of the variable “res” in this function:
“static esp_err_t cmd_handler(httpd_req_t *req)”
in particular I don’t understand how it can ever be changed from “0” (its initial value) or “-1”, so that this test:
“if(res){
return httpd_resp_send_500(req);
}”
can ever be true.
Can you tell me how it works?
Again thank you for this tutorial, it is very interesting and useful.
the video is not streaming in the web page.
Hi.
Make sure the board is relatively close to your router so that it can have a good wi-fi signal.
REgards,
Sara
Hi.
I would like to display the signal strength on the web page. I don’t know how to send variable value to the web page.
resolv
created an Asyncwebser on port 82 with websock
Hi Sara, I found your code is the most stable and it use the original esp_httpd library.
I have tried it using both AP mode and Client of the ESP32 and got stable video frames.
I also tried many websocket video stream code and the best one is only the case doing as an AP itself, when I use the same wifi router configuration (hardware as above) and ESP32 acting as an client, the video had many delays and lost frame.
I search other method of video stream such as websocket is that it is easier to make two way communication between the ESP32 and the web page, but it is very depressing no code in all the web sites I found worked in both AP & Client mode.
So, I back to the origin and wish to find efficient two way communications using http server only (modify your code), I found there is a method using ajax to refrash the web page, however, it jam the code and could not work easily, do you have successful two way communication using the code in this project? any hint?
how change this?
I’ve installed code and every works fine when using edge browser on laptop. But when I use safari or chrome on my iPhone, I get an extra tap.
For instance if I press forward on my iPhone, in the serial output I get forward, stop and forward again.
Any idea what’s wrong?
hi~
the event will be like this, you can try without touchstart and touchend event.
the event trigger sequence will be
touchstart => touchend => mousemove => mousedown => mouseup => click
medium.com/frochu/touch-and-mouse-together-76fb69114c04
HGi, very useful tutorial.
I just start my first project with ESP32.
Could you please help with few issues
1) I choose AI thinker ESP32 CAM board from menu, because I use ESP32-CAN , and it does not work , what board I I need to choose?
2) I have got big message in Serial monitor:
st:0x1(POWEO_EET,oot:0x13(SP_AS_LSH_OOT)
cnfgip ,SPIW:0xee
cl_r:00,qdrv:000,ddv00,s0_dv:0x0,h_r:x0wp_dv:0x0
oeDO lock dv:1
od03ff030,len1344
la:x407800,len:194
od0x4080400,ln:60
nry 0x00805f
What does it mean?
Thanks in advance
How to fetch the url of the image from this server using opencv
everything works perfectly with the exception of the turning controls when I hit the right button it goes left? is there a simple fix for that?Thanks
I switch the polarity of the motors to the motor controller and the only thing it did was make forward/backwards reversed but it fixed left to right..? Everything else is correctly wired?
Hi, nice project and got it working rather easily. My only issue is that it was more easy for me to install it vertically instead of horizontally, is it possible to rotate the image to the right of left 90 degrees, Thank for the project
Jacques
hi. can i change the network into an access point?
Hi.
You can read this : https://randomnerdtutorials.com/esp32-access-point-ap-web-server/
Regards,
Sara
Hi Sara,Rui
I recently bought your esp32 ebook; and couldn’t work on the sketches . Uninically reading autorized .I understand that they are protected. Thank you for helping me solve this problème . Have a good day . Kind regards . JCD
Hi.
If you’re having issues accessing the eBooks, please send us an email to our support: https://randomnerdtutorials.com/support/
Regards,
Sara
hi , the project works well for me on my local network , has anyone tried to port forward it using ngrok ? I was getting errors while doing it where it says that the device isnt communicating with the server. could anyone help me out with this who has done it successfully.
Hi, did you read my posts:
https://randomnerdtutorials.com/esp32-cam-car-robot-web-server/#comment-831934
https://randomnerdtutorials.com/esp32-cam-car-robot-web-server/#comment-829646
Hi Sara, Rui,
In my local network this robot car work very well thank you. Is it possible working in externe ? I make a redirectionnal port in my livebox, on 80 port . problem ! no image, uninically the buttons . Can you helping resolve this problem . Is the sketch must be changing ? sorry for my english it’s very bad !! thanks. Regards . Jean-Charles
You also have to forward port 81 for the livestream, see above post for more information.
Hi sir,
Thanks very much for your answer. I’m really a beginner and I’m not shure I can do thé right manipulations in my box. It’s complicated for me ! I look at your previous post and try to get of it . Thank you so much for sharing this problem.Cordially. JCD