{"id":162234,"date":"2024-09-26T14:19:04","date_gmt":"2024-09-26T14:19:04","guid":{"rendered":"https:\/\/randomnerdtutorials.com\/?p=162234"},"modified":"2024-09-28T17:06:45","modified_gmt":"2024-09-28T17:06:45","slug":"esp32-wi-fi-car-robot-arduino","status":"publish","type":"post","link":"https:\/\/randomnerdtutorials.com\/esp32-wi-fi-car-robot-arduino\/","title":{"rendered":"ESP32 Remote-Controlled Wi-Fi Car Robot (Arduino IDE)"},"content":{"rendered":"\n<p>In this project, you&#8217;ll learn how to build an ESP32 Wi-Fi remote controlled car robot step by step. You&#8217;ll control the robot using a web server to make the robot move forward, backward, right, left, and stop. There&#8217;s also an option to control the speed of the robot. The ESP32 will be programmed using Arduino IDE.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img data-recalc-dims=\"1\" fetchpriority=\"high\" decoding=\"async\" width=\"1200\" height=\"675\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/09\/ESP32-Remote-Controlled-Wi-Fi-Car-Robot.jpg?resize=1200%2C675&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"ESP32 Remote-Controlled Wi-Fi Car Robot\" class=\"wp-image-162254\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/09\/ESP32-Remote-Controlled-Wi-Fi-Car-Robot.jpg?w=1920&amp;quality=100&amp;strip=all&amp;ssl=1 1920w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/09\/ESP32-Remote-Controlled-Wi-Fi-Car-Robot.jpg?resize=300%2C169&amp;quality=100&amp;strip=all&amp;ssl=1 300w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/09\/ESP32-Remote-Controlled-Wi-Fi-Car-Robot.jpg?resize=1024%2C576&amp;quality=100&amp;strip=all&amp;ssl=1 1024w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/09\/ESP32-Remote-Controlled-Wi-Fi-Car-Robot.jpg?resize=768%2C432&amp;quality=100&amp;strip=all&amp;ssl=1 768w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/09\/ESP32-Remote-Controlled-Wi-Fi-Car-Robot.jpg?resize=1536%2C864&amp;quality=100&amp;strip=all&amp;ssl=1 1536w\" sizes=\"(max-width: 1200px) 100vw, 1200px\" \/><\/figure><\/div>\n\n\n<h2 class=\"wp-block-heading\">Prerequisites<\/h2>\n\n\n\n<p>Before proceeding, make sure to check the following prerequisites.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">1. Arduino IDE<\/h3>\n\n\n\n<p>The ESP32 will be programmed using Arduino IDE. So, make sure you have the ESP32 boards installed. You can follow the next tutorial as a reference:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><a href=\"https:\/\/randomnerdtutorials.com\/installing-esp32-arduino-ide-2-0\/\" title=\"\">Installing ESP32 Board in Arduino IDE 2 (Windows, Mac OS X, Linux)<\/a><\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">2. Parts required:<\/h3>\n\n\n\n<p>Here\u2019s a list of the parts required to build the ESP32 Wi-Fi remote-controlled car robot:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><a href=\"https:\/\/makeradvisor.com\/tools\/esp32-dev-board-wi-fi-bluetooth\/\" target=\"_blank\" rel=\"noreferrer noopener\">ESP32 DOIT DEVKIT V1 Board<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/makeradvisor.com\/tools\/2wd-smart-robot-chassis-kit\/\" target=\"_blank\" rel=\"noreferrer noopener\">Smart Robot Chassis Kit<\/a>&nbsp;(or your own DIY robot chassis + 2x&nbsp;<a href=\"https:\/\/makeradvisor.com\/tools\/mini-dc-motor\/\" target=\"_blank\" rel=\"noreferrer noopener\">DC motors<\/a>)<\/li>\n\n\n\n<li><a href=\"https:\/\/makeradvisor.com\/tools\/l298n-motor-driver\/\" target=\"_blank\" rel=\"noreferrer noopener\">L298N motor driver<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/amzn.to\/2HGu9zO\" target=\"_blank\" rel=\"noreferrer noopener\">1x Power bank \u2013 portable charger<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/amzn.to\/2HKmjW4\" target=\"_blank\" rel=\"noreferrer noopener\">4x 1.5 AA batteries<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/makeradvisor.com\/tools\/ceramic-capacitors-kit\/\" target=\"_blank\" rel=\"noreferrer noopener\">2x 100nF ceramic capacitors<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/makeradvisor.com\/tools\/spdt-slide-switch\/\" target=\"_blank\" rel=\"noreferrer noopener\">1x SPDT Slide Switch<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/makeradvisor.com\/tools\/jumper-wires-kit-120-pieces\/\" target=\"_blank\" rel=\"noreferrer noopener\">Jumper wires<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/makeradvisor.com\/tools\/mb-102-solderless-breadboard-830-points\/\" target=\"_blank\" rel=\"noreferrer noopener\">Breadboard<\/a>&nbsp;or&nbsp;<a href=\"https:\/\/makeradvisor.com\/tools\/prototyping-circuit-board-stripboard\/\" target=\"_blank\" rel=\"noreferrer noopener\">stripboard<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/amzn.to\/2H5Sh1O\" target=\"_blank\" rel=\"noreferrer noopener\">Velcro tape<\/a><\/li>\n<\/ul>\n\n\n<p>You can use the preceding links or go directly to <a href=\"https:\/\/makeradvisor.com\/tools\/?utm_source=rnt&utm_medium=post&utm_campaign=post\" target=\"_blank\">MakerAdvisor.com\/tools<\/a> to find all the parts for your projects at the best price!<\/p><p style=\"text-align:center;\"><a href=\"https:\/\/makeradvisor.com\/tools\/?utm_source=rnt&utm_medium=post&utm_campaign=post\" target=\"_blank\"><img data-recalc-dims=\"1\" decoding=\"async\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2017\/10\/header-200.png?w=1200&#038;quality=100&#038;strip=all&#038;ssl=1\"><\/a><\/p>\n\n\n\n<h3 class=\"wp-block-heading\">3. DC Motors and the LN298 Motor Driver<\/h3>\n\n\n\n<p>To build the robot, we&#8217;ll use two DC motors controlled via a LN298 motor driver. Get familiar with controlling the speed and direction of a DC motor with the ESP32:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><a href=\"https:\/\/randomnerdtutorials.com\/esp32-dc-motor-l298n-motor-driver-control-speed-direction\/\">ESP32 with DC Motor and L298N Motor Driver \u2013 Control Speed and Direction<\/a><\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">4. The Robot Chassis Kit<\/h3>\n\n\n\n<p>We&#8217;ll use the <a href=\"https:\/\/makeradvisor.com\/2wd-smart-robot-chassis-kit\/\" target=\"_blank\" rel=\"noreferrer noopener\">Smart Robot Chassis Kit<\/a>. For instructions on how to assemble it, check the following tutorial:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><a href=\"https:\/\/randomnerdtutorials.com\/build-robot-car-chassis-kit-arduino\/\">Assembling the Robot Car Chassis Kit<\/a><\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">Project Overview<\/h2>\n\n\n\n<p>Before starting the project, we\u2019ll highlight the most important features and components to create the project.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Wi-Fi<\/h3>\n\n\n\n<p>The robot will be controlled via Wi-Fi using your ESP32. We\u2019ll create a web-based interface to control the robot that can be accessed on any device inside your local network.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Robot Controls<\/h3>\n\n\n\n<p>The web server has five control options: forward, reverse, right, left, and stop. There\u2019s also a slider to control the speed.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img data-recalc-dims=\"1\" decoding=\"async\" width=\"750\" height=\"422\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/09\/ESP32-web-server-control-robot.jpg?resize=750%2C422&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"\" class=\"wp-image-162237\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/09\/ESP32-web-server-control-robot.jpg?w=750&amp;quality=100&amp;strip=all&amp;ssl=1 750w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/09\/ESP32-web-server-control-robot.jpg?resize=300%2C169&amp;quality=100&amp;strip=all&amp;ssl=1 300w\" sizes=\"(max-width: 750px) 100vw, 750px\" \/><\/figure><\/div>\n\n\n<h3 class=\"wp-block-heading\">Smart Robot Chassis Kit<\/h3>\n\n\n\n<p>We\u2019re going to use the robot chassis kit shown in the figure below. That is the&nbsp;<a href=\"https:\/\/makeradvisor.com\/2wd-smart-robot-chassis-kit\/\" target=\"_blank\" rel=\"noreferrer noopener\">Smart Robot Chassis Kit<\/a>. You can find it in most online stores. The kit costs around $10, and it\u2019s easy to assemble. You can use any other chassis kit as long as it comes with two DC motors.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img data-recalc-dims=\"1\" decoding=\"async\" width=\"550\" height=\"392\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/09\/ESP32-robot-chassis-kit.jpg?resize=550%2C392&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"\" class=\"wp-image-162238\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/09\/ESP32-robot-chassis-kit.jpg?w=550&amp;quality=100&amp;strip=all&amp;ssl=1 550w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/09\/ESP32-robot-chassis-kit.jpg?resize=300%2C214&amp;quality=100&amp;strip=all&amp;ssl=1 300w\" sizes=\"(max-width: 550px) 100vw, 550px\" \/><\/figure><\/div>\n\n\n<h3 class=\"wp-block-heading\">L298N Motor Driver&nbsp;<\/h3>\n\n\n\n<p>There are many ways to control DC motors. We\u2019ll use the L298N motor driver that provides an easy way to control the speed and direction of 2 DC motors.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"750\" height=\"500\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2018\/05\/298n-motor-driver.jpg?resize=750%2C500&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"298N Motor Driver\" class=\"wp-image-146161\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2018\/05\/298n-motor-driver.jpg?w=750&amp;quality=100&amp;strip=all&amp;ssl=1 750w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2018\/05\/298n-motor-driver.jpg?resize=300%2C200&amp;quality=100&amp;strip=all&amp;ssl=1 300w\" sizes=\"(max-width: 750px) 100vw, 750px\" \/><\/figure><\/div>\n\n\n<h3 class=\"wp-block-heading\">Power<\/h3>\n\n\n\n<p>The motors draw a lot of current, so you need to use an external power supply. This means you need two different power sources. One will power the DC motors, and the other will power the ESP32. We\u2019ll power the ESP32 using a small portable charger (like the ones used to charge your smartphone).<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"750\" height=\"421\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/09\/portable-charger.jpg?resize=750%2C421&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"portable charger\" class=\"wp-image-162239\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/09\/portable-charger.jpg?w=750&amp;quality=100&amp;strip=all&amp;ssl=1 750w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/09\/portable-charger.jpg?resize=300%2C168&amp;quality=100&amp;strip=all&amp;ssl=1 300w\" sizes=\"(max-width: 750px) 100vw, 750px\" \/><\/figure><\/div>\n\n\n<p>The motors will be powered using 4 AA 1.5V batteries. You might consider using rechargeable batteries or any other suitable power supply.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"750\" height=\"422\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/09\/ESP32-robot-power-DC-motor-using-batteries.jpg?resize=750%2C422&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"\" class=\"wp-image-162240\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/09\/ESP32-robot-power-DC-motor-using-batteries.jpg?w=750&amp;quality=100&amp;strip=all&amp;ssl=1 750w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/09\/ESP32-robot-power-DC-motor-using-batteries.jpg?resize=300%2C169&amp;quality=100&amp;strip=all&amp;ssl=1 300w\" sizes=\"(max-width: 750px) 100vw, 750px\" \/><\/figure><\/div>\n\n\n<h2 class=\"wp-block-heading\">Control DC motors with the L298N<\/h2>\n\n\n\n<p>To get familiar with the L298N motor driver, we recommend reading the following tutorial:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><a href=\"https:\/\/randomnerdtutorials.com\/esp32-dc-motor-l298n-motor-driver-control-speed-direction\/\">ESP32 with DC Motor and L298N Motor Driver \u2013 Control Speed and Direction<\/a><\/li>\n<\/ul>\n\n\n\n<p>Let&#8217;s take a quick look at how to use the L298N motor driver to control the robot&#8217;s speed and direction.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"750\" height=\"500\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2018\/05\/L298N-label.jpg?resize=750%2C500&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"\" class=\"wp-image-61999\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2018\/05\/L298N-label.jpg?w=750&amp;quality=100&amp;strip=all&amp;ssl=1 750w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2018\/05\/L298N-label.jpg?resize=300%2C200&amp;quality=100&amp;strip=all&amp;ssl=1 300w\" sizes=\"(max-width: 750px) 100vw, 750px\" \/><\/figure><\/div>\n\n\n<h3 class=\"wp-block-heading\">The Enable Pins<\/h3>\n\n\n\n<p>The enable pins are like an ON and OFF switch for your motors. For example:<\/p>\n\n\n\n<p>If you send a HIGH signal to enable 1 pin, motor A is ready to be controlled and at the maximum speed. If you send a LOW signal to the enable 1 pin, motor A turns off.<\/p>\n\n\n\n<p>If you send a PWM signal, you can control the speed of the motor. The motor speed is proportional to the duty cycle. However, note that for small duty cycles, the motors might not spin, and make a continuous buzz sound.<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><tbody><tr><td>Signal Sent to the Enable Pin<\/td><td>Motor State<\/td><\/tr><tr><td>HIGH<\/td><td>Motor not enabled<\/td><\/tr><tr><td>LOW<\/td><td>Motor enabled<\/td><\/tr><tr><td>PWM<\/td><td>Motor enabled: speed proportional to the duty cycle<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\">The Input Pins<\/h3>\n\n\n\n<p>The input pins control the direction the motors are spinning. Input 1 and input 2 control motor A, and input 3 and 4 control motor B.<\/p>\n\n\n\n<p>If you apply LOW to input1 and HIGH to input 2, the motor will spin forward. If you apply power the other way around: HIGH to input 1 and LOW to input 2, the motor will rotate backwards. Motor B is controlled using the same method.<\/p>\n\n\n\n<p>So, if you want your robot to move forward, both motors should be rotating forward. To make it go backward, both should be rotating backward.<\/p>\n\n\n\n<p>To turn the robot in one direction, you need to spin the opposite motor faster. For example, to make the robot turn right, we\u2019ll enable the motor at the left, and disable the motor at the right.<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table><tbody><tr><td><strong>DIRECTION<\/strong><\/td><td><strong>INPUT 1<\/strong><\/td><td><strong>INPUT 2<\/strong><\/td><td><strong>INPUT 3<\/strong><\/td><td><strong>INPUT 4<\/strong><\/td><\/tr><tr><td><strong>Forward<\/strong><\/td><td>0<\/td><td>1<\/td><td>0<\/td><td>1<\/td><\/tr><tr><td><strong>Backward<\/strong><\/td><td>1<\/td><td>0<\/td><td>1<\/td><td>0<\/td><\/tr><tr><td><strong>Right <\/strong><\/td><td>0<\/td><td>1<\/td><td>0<\/td><td>0<\/td><\/tr><tr><td><strong>Left<\/strong><\/td><td>0<\/td><td>0<\/td><td>0<\/td><td>1<\/td><\/tr><tr><td><strong>Stop<\/strong><\/td><td>0<\/td><td>0<\/td><td>0<\/td><td>0<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">Wiring the Circuit<\/h2>\n\n\n\n<p>After assembling the robot chassis, you can wire the circuit by following the next schematic diagram.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"755\" height=\"706\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/09\/ESP32-two-dc-motors-robot-circuit.png?resize=755%2C706&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"ESP32 Circuit to Control Two DC Motors Robot\" class=\"wp-image-162241\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/09\/ESP32-two-dc-motors-robot-circuit.png?w=755&amp;quality=100&amp;strip=all&amp;ssl=1 755w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/09\/ESP32-two-dc-motors-robot-circuit.png?resize=300%2C281&amp;quality=100&amp;strip=all&amp;ssl=1 300w\" sizes=\"(max-width: 755px) 100vw, 755px\" \/><\/figure><\/div>\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><tbody><tr><td><strong>L298N MOTOR DRIVER<\/strong><\/td><td><strong>ESP32<\/strong><\/td><\/tr><tr><td>IN1<\/td><td>GPIO 27<\/td><\/tr><tr><td>IN2<\/td><td>GPIO 26<\/td><\/tr><tr><td>ENA (Enable pin for Motor A)<\/td><td>GPIO 14<\/td><\/tr><tr><td>IN3<\/td><td>GPIO 33<\/td><\/tr><tr><td>IN4<\/td><td>GPIO 25<\/td><\/tr><tr><td>ENB (Enable pin for Motor B)<\/td><td>GPIO 32<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p>Start by connecting the ESP32 to the motor driver as shown in the schematic diagram. You can either use a mini breadboard or a stripboard to place your ESP32 and build the circuit.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"750\" height=\"422\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/09\/ESP32-car-robot-on-a-stripboard.jpg?resize=750%2C422&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"ESP32 Car Robot - ESP32 on a chassis kit\" class=\"wp-image-162242\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/09\/ESP32-car-robot-on-a-stripboard.jpg?w=750&amp;quality=100&amp;strip=all&amp;ssl=1 750w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/09\/ESP32-car-robot-on-a-stripboard.jpg?resize=300%2C169&amp;quality=100&amp;strip=all&amp;ssl=1 300w\" sizes=\"(max-width: 750px) 100vw, 750px\" \/><\/figure><\/div>\n\n\n<p>After that, wire each motor to their terminal blocks. We recommend soldering a 0.1 uF ceramic capacitor to each motor&#8217;s positive and negative terminals, as shown in the diagram, to help smooth out any voltage spikes.<\/p>\n\n\n\n<p>Additionally, you can solder a slider switch to the red wire that comes from the battery pack. This way, you can turn the power to the motors and motor driver on and off. Finally, power the motors by connecting a 4 AA battery pack to the motor driver power blocks. Since you want your robot to be portable, the ESP32 will be powered using a portable charger.&nbsp;You can attach the portable charger to the robot chassis using velcro, for example.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"750\" height=\"422\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/09\/ESP32-car-robot-circuit-on-chassis-kit.jpg?resize=750%2C422&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"ESP32 Car Robot - ESP32 on a chassis kit\" class=\"wp-image-162243\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/09\/ESP32-car-robot-circuit-on-chassis-kit.jpg?w=750&amp;quality=100&amp;strip=all&amp;ssl=1 750w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/09\/ESP32-car-robot-circuit-on-chassis-kit.jpg?resize=300%2C169&amp;quality=100&amp;strip=all&amp;ssl=1 300w\" sizes=\"(max-width: 750px) 100vw, 750px\" \/><\/figure><\/div>\n\n\n<p>Don\u2019t connect the power bank yet, because first, you need to upload the code to the ESP32.<\/p>\n\n\n\n<p>Your robot should look similar to the following figure:<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"750\" height=\"422\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/09\/ESP32-car-robot-assembled.jpg?resize=750%2C422&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"\" class=\"wp-image-162244\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/09\/ESP32-car-robot-assembled.jpg?w=750&amp;quality=100&amp;strip=all&amp;ssl=1 750w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/09\/ESP32-car-robot-assembled.jpg?resize=300%2C169&amp;quality=100&amp;strip=all&amp;ssl=1 300w\" sizes=\"(max-width: 750px) 100vw, 750px\" \/><\/figure><\/div>\n\n\n<h2 class=\"wp-block-heading\">Building the Web Server<\/h2>\n\n\n\n<p>Let&#8217;s now create the web server. The following figure shows the web server we&#8217;ll build. You have five controls to move the robot forward, reverse, right, left, and stop. You also have a slider to control the speed. You can select 0, 25, 50, 75, or 100% to control the motor speed.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"750\" height=\"422\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/09\/ESP32-web-server-control-robot.jpg?resize=750%2C422&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"ESP32 Web Server to Control Robot\" class=\"wp-image-162237\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/09\/ESP32-web-server-control-robot.jpg?w=750&amp;quality=100&amp;strip=all&amp;ssl=1 750w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/09\/ESP32-web-server-control-robot.jpg?resize=300%2C169&amp;quality=100&amp;strip=all&amp;ssl=1 300w\" sizes=\"(max-width: 750px) 100vw, 750px\" \/><\/figure><\/div>\n\n\n<h2 class=\"wp-block-heading\">Arduino Code &#8211; ESP32 Remote-Controlled Wi-Fi Car Robot<\/h2>\n\n\n\n<p>To build the web server, we&#8217;ll use the <span class=\"rnthl rntliteral\">Webserver.h<\/span> library that is automatically installed when you install the ESP32 boards in Arduino IDE.<\/p>\n\n\n<pre style=\"max-height: 40em; margin-bottom: 20px;\"><code class=\"language-c\">\/*  \n  Rui Santos &amp; Sara Santos - Random Nerd Tutorials\n  https:\/\/RandomNerdTutorials.com\/esp32-wi-fi-car-robot-arduino\/\n  Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files.\n  The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n*\/\n\n#include &lt;WiFi.h&gt;\n#include &lt;WebServer.h&gt;\n\n\/\/ Replace with your network credentials\nconst char* ssid     = &quot;REPLACE_WITH_YOUR_SSID&quot;;\nconst char* password = &quot;REPLACE_WITH_YOUR_PASSWORD&quot;;\n\n\/\/ Create an instance of the WebServer on port 80\nWebServer server(80);\n\n\/\/ Motor 1\nint motor1Pin1 = 27; \nint motor1Pin2 = 26; \nint enable1Pin = 14;\n\n\/\/ Motor 2\nint motor2Pin1 = 33; \nint motor2Pin2 = 25; \nint enable2Pin = 32;\n\n\/\/ Setting PWM properties\nconst int freq = 30000;\nconst int resolution = 8;\nint dutyCycle = 0;\n\nString valueString = String(0);\n\nvoid handleRoot() {\n  const char html[] PROGMEM = R&quot;rawliteral(\n  &lt;!DOCTYPE HTML&gt;&lt;html&gt;\n  &lt;head&gt;\n    &lt;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1&quot;&gt;\n    &lt;link rel=&quot;icon&quot; href=&quot;data:,&quot;&gt;\n    &lt;style&gt;\n      html { font-family: Helvetica; display: inline-block; margin: 0px auto; text-align: center; }\n      .button { -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; user-select: none; background-color: #4CAF50; border: none; color: white; padding: 12px 28px; text-decoration: none; font-size: 26px; margin: 1px; cursor: pointer; }\n      .button2 {background-color: #555555;}\n    &lt;\/style&gt;\n    &lt;script&gt;\n      function moveForward() { fetch('\/forward'); }\n      function moveLeft() { fetch('\/left'); }\n      function stopRobot() { fetch('\/stop'); }\n      function moveRight() { fetch('\/right'); }\n      function moveReverse() { fetch('\/reverse'); }\n\n      function updateMotorSpeed(pos) {\n        document.getElementById('motorSpeed').innerHTML = pos;\n        fetch(`\/speed?value=${pos}`);\n      }\n    &lt;\/script&gt;\n  &lt;\/head&gt;\n  &lt;body&gt;\n    &lt;h1&gt;ESP32 Motor Control&lt;\/h1&gt;\n    &lt;p&gt;&lt;button class=&quot;button&quot; onclick=&quot;moveForward()&quot;&gt;FORWARD&lt;\/button&gt;&lt;\/p&gt;\n    &lt;div style=&quot;clear: both;&quot;&gt;\n      &lt;p&gt;\n        &lt;button class=&quot;button&quot; onclick=&quot;moveLeft()&quot;&gt;LEFT&lt;\/button&gt;\n        &lt;button class=&quot;button button2&quot; onclick=&quot;stopRobot()&quot;&gt;STOP&lt;\/button&gt;\n        &lt;button class=&quot;button&quot; onclick=&quot;moveRight()&quot;&gt;RIGHT&lt;\/button&gt;\n      &lt;\/p&gt;\n    &lt;\/div&gt;\n    &lt;p&gt;&lt;button class=&quot;button&quot; onclick=&quot;moveReverse()&quot;&gt;REVERSE&lt;\/button&gt;&lt;\/p&gt;\n    &lt;p&gt;Motor Speed: &lt;span id=&quot;motorSpeed&quot;&gt;0&lt;\/span&gt;&lt;\/p&gt;\n    &lt;input type=&quot;range&quot; min=&quot;0&quot; max=&quot;100&quot; step=&quot;25&quot; id=&quot;motorSlider&quot; oninput=&quot;updateMotorSpeed(this.value)&quot; value=&quot;0&quot;\/&gt;\n  &lt;\/body&gt;\n  &lt;\/html&gt;)rawliteral&quot;;\n  server.send(200, &quot;text\/html&quot;, html);\n}\n\nvoid handleForward() {\n  Serial.println(&quot;Forward&quot;);\n  digitalWrite(motor1Pin1, LOW);\n  digitalWrite(motor1Pin2, HIGH); \n  digitalWrite(motor2Pin1, LOW);\n  digitalWrite(motor2Pin2, HIGH);\n  server.send(200);\n}\n\nvoid handleLeft() {\n  Serial.println(&quot;Left&quot;);\n  digitalWrite(motor1Pin1, LOW); \n  digitalWrite(motor1Pin2, LOW); \n  digitalWrite(motor2Pin1, LOW);\n  digitalWrite(motor2Pin2, HIGH);\n  server.send(200);\n}\n\nvoid handleStop() {\n  Serial.println(&quot;Stop&quot;);\n  digitalWrite(motor1Pin1, LOW); \n  digitalWrite(motor1Pin2, LOW); \n  digitalWrite(motor2Pin1, LOW);\n  digitalWrite(motor2Pin2, LOW);   \n  server.send(200);\n}\n\nvoid handleRight() {\n  Serial.println(&quot;Right&quot;);\n  digitalWrite(motor1Pin1, LOW); \n  digitalWrite(motor1Pin2, HIGH); \n  digitalWrite(motor2Pin1, LOW);\n  digitalWrite(motor2Pin2, LOW);    \n  server.send(200);\n}\n\nvoid handleReverse() {\n  Serial.println(&quot;Reverse&quot;);\n  digitalWrite(motor1Pin1, HIGH);\n  digitalWrite(motor1Pin2, LOW); \n  digitalWrite(motor2Pin1, HIGH);\n  digitalWrite(motor2Pin2, LOW);          \n  server.send(200);\n}\n\nvoid handleSpeed() {\n  if (server.hasArg(&quot;value&quot;)) {\n    valueString = server.arg(&quot;value&quot;);\n    int value = valueString.toInt();\n    if (value == 0) {\n      ledcWrite(enable1Pin, 0);\n      ledcWrite(enable2Pin, 0);\n      digitalWrite(motor1Pin1, LOW); \n      digitalWrite(motor1Pin2, LOW); \n      digitalWrite(motor2Pin1, LOW);\n      digitalWrite(motor2Pin2, LOW);   \n    } else { \n      dutyCycle = map(value, 25, 100, 200, 255);\n      ledcWrite(enable1Pin, dutyCycle);\n      ledcWrite(enable2Pin, dutyCycle);\n      Serial.println(&quot;Motor speed set to &quot; + String(value));\n    }\n  }\n  server.send(200);\n}\n\nvoid setup() {\n  Serial.begin(115200);\n\n  \/\/ Set the Motor pins as outputs\n  pinMode(motor1Pin1, OUTPUT);\n  pinMode(motor1Pin2, OUTPUT);\n  pinMode(motor2Pin1, OUTPUT);\n  pinMode(motor2Pin2, OUTPUT);\n\n  \/\/ Configure PWM Pins\n  ledcAttach(enable1Pin, freq, resolution);\n  ledcAttach(enable2Pin, freq, resolution);\n    \n  \/\/ Initialize PWM with 0 duty cycle\n  ledcWrite(enable1Pin, 0);\n  ledcWrite(enable2Pin, 0);\n  \n  \/\/ Connect to Wi-Fi\n  Serial.print(&quot;Connecting to &quot;);\n  Serial.println(ssid);\n  WiFi.begin(ssid, password);\n  while (WiFi.status() != WL_CONNECTED) {\n    delay(500);\n    Serial.print(&quot;.&quot;);\n  }\n  Serial.println(&quot;&quot;);\n  Serial.println(&quot;WiFi connected.&quot;);\n  Serial.println(&quot;IP address: &quot;);\n  Serial.println(WiFi.localIP());\n\n  \/\/ Define routes\n  server.on(&quot;\/&quot;, handleRoot);\n  server.on(&quot;\/forward&quot;, handleForward);\n  server.on(&quot;\/left&quot;, handleLeft);\n  server.on(&quot;\/stop&quot;, handleStop);\n  server.on(&quot;\/right&quot;, handleRight);\n  server.on(&quot;\/reverse&quot;, handleReverse);\n  server.on(&quot;\/speed&quot;, handleSpeed);\n\n  \/\/ Start the server\n  server.begin();\n}\n\nvoid loop() {\n  server.handleClient();\n}\n<\/code><\/pre>\n\t<p style=\"text-align:center\"><a class=\"rntwhite\" href=\"https:\/\/github.com\/RuiSantosdotme\/Random-Nerd-Tutorials\/raw\/master\/Projects\/ESP32\/ESP32_Car_Robot_Web_Server.ino\" target=\"_blank\">View raw code<\/a><\/p>\n\n\n\n<h3 class=\"wp-block-heading\">How Does the Code Work?<\/h3>\n\n\n\n<p>Continue reading to learn how the code works, or skip to the <a href=\"#testing\" title=\"\">Demonstration section<\/a>.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Including Libraries<\/h4>\n\n\n\n<p>Start by including the required libraries. We&#8217;re using the WiFi.h library to handle internet connection and the WebServer.h library to build the web server. Both libraries are included by default.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>#include &lt;WiFi.h&gt;\n#include &lt;WebServer.h&gt;<\/code><\/pre>\n\n\n\n<h4 class=\"wp-block-heading\">Web Server Instance<\/h4>\n\n\n\n<p>Create a web server instance of the <span class=\"rnthl rntliteral\">WebServer<\/span> library on port 80 called <span class=\"rnthl rntliteral\">server<\/span>.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>\/\/ Create an instance of the WebServer on port 80\nWebServer server(80);<\/code><\/pre>\n\n\n\n<h4 class=\"wp-block-heading\">Setting your Network Credentials<\/h4>\n\n\n\n<p>Start by typing your network credentials in the following variables so that the ESP32 can connect to your local network.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>const char* ssid &nbsp; &nbsp; = \"REPLACE_WITH_YOUR_SSID\";\nconst char* password = \" REPLACE_WITH_YOUR_PASSWORD\";<\/code><\/pre>\n\n\n\n<h4 class=\"wp-block-heading\">Creating Variables for the Motor Driver Pins<\/h4>\n\n\n\n<p>Next, create variables for the motor input pins, and the motor enable pins. These pins are connected to the L298N motor driver, which controls the direction and speed of the motors.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>\/\/ Motor 1\nint motor1Pin1 = 27;\nint motor1Pin2 = 26;\nint enable1Pin = 14;\n\/\/ Motor 2\nint motor2Pin1 = 33;\nint motor2Pin2 = 25;\nint enable2Pin = 32;<\/code><\/pre>\n\n\n\n<h4 class=\"wp-block-heading\">Setting PWM Properties<\/h4>\n\n\n\n<p>To control the speed of the motors, you\u2019ll send PWM signals to the enable pins. Define the PWM settings as follows:<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>\/\/ Setting PWM properties\nconst int freq = 30000;\nconst int resolution = 8;\nint dutyCycle = 0;<\/code><\/pre>\n\n\n\n<p class=\"rntbox rntclgreen\">Recommended reading: <a href=\"https:\/\/randomnerdtutorials.com\/esp32-pwm-arduino-ide\/\">ESP32 PWM with Arduino IDE (Analog Output)<\/a><\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Slider Value<\/h4>\n\n\n\n<p>Create a variable called <span class=\"rnthl rntliteral\">valueString<\/span> to hold the slider value to control the speed of the motor.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>String valueString = String(0);<\/code><\/pre>\n\n\n\n<h4 class=\"wp-block-heading\">setup()<\/h4>\n\n\n\n<p>In the <span class=\"rnthl rntliteral\">setup()<\/span>, you set the motor pins as outputs:<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>\/\/ Set the Motor pins as outputs\npinMode(motor1Pin1, OUTPUT);\npinMode(motor1Pin2, OUTPUT);\npinMode(motor2Pin1, OUTPUT);\npinMode(motor2Pin2, OUTPUT);<\/code><\/pre>\n\n\n\n<p>Configure the enable pins as PWM outputs with the PWM properties defined earlier.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>\/\/ Configure PWM Pins\nledcAttach(enable1Pin, freq, resolution);\nledcAttach(enable2Pin, freq, resolution);<\/code><\/pre>\n\n\n\n<p>Generate the PWM signal with a defined duty cycle using the&nbsp;<span class=\"rnthl rntliteral\">ledcWrite()<\/span> function. When the code first starts, we want the motors to be off by default, so we\u2019re sending 0% duty cycle.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>\/\/ Initialize PWM with 0 duty cycle\nledcWrite(enable1Pin, 0);\nledcWrite(enable2Pin, 0);<\/code><\/pre>\n\n\n\n<p>The following code in the <span class=\"rnthl rntliteral\">setup()<\/span> connects your ESP32 to your local network and prints the IP address in the Serial Monitor.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>\/\/ Connect to Wi-Fi network with SSID and password\nSerial.print(\"Connecting to \");\nSerial.println(ssid);\nWiFi.begin(ssid, password);\nwhile (WiFi.status() != WL_CONNECTED) {\n&nbsp; delay(500);\n&nbsp; Serial.print(\".\");\n}\n\/\/ Print local IP address and start web server\nSerial.println(\"\");\nSerial.println(\"WiFi connected.\");\nSerial.println(\"IP address: \");\nSerial.println(WiFi.localIP());\nserver.begin();<\/code><\/pre>\n\n\n\n<h4 class=\"wp-block-heading\">Controlling the Robot<\/h4>\n\n\n\n<p>Each motor action, such as moving forward, turning left, stopping, etc., is handled by specific routes. On the web server, when you click on the buttons, it will make different requests on different routes.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>\/\/ Define routes\nserver.on(\"\/\", handleRoot);\nserver.on(\"\/forward\", handleForward);\nserver.on(\"\/left\", handleLeft);\nserver.on(\"\/stop\", handleStop);\nserver.on(\"\/right\", handleRight);\nserver.on(\"\/reverse\", handleReverse);\nserver.on(\"\/speed\", handleSpeed);<\/code><\/pre>\n\n\n\n<p>The <span class=\"rnthl rntliteral\">handleForward()<\/span>, <span class=\"rnthl rntliteral\">handleLeft()<\/span>, <span class=\"rnthl rntliteral\">handleStop()<\/span>, <span class=\"rnthl rntliteral\">handleRight()<\/span> and <span class=\"rnthl rntliteral\">handleReverse()<\/span> functions will turn the appropriate GPIOs on and off to achieve the desired result.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>void handleForward() {\n&nbsp; Serial.println(\"Forward\");\n&nbsp; digitalWrite(motor1Pin1, LOW);\n&nbsp; digitalWrite(motor1Pin2, HIGH);\n&nbsp; digitalWrite(motor2Pin1, LOW);\n&nbsp; digitalWrite(motor2Pin2, HIGH);\n&nbsp; server.send(200);\n}\nvoid handleLeft() {\n&nbsp; Serial.println(\"Left\");\n&nbsp; digitalWrite(motor1Pin1, LOW);\n&nbsp; digitalWrite(motor1Pin2, LOW);\n&nbsp; digitalWrite(motor2Pin1, LOW);\n&nbsp; digitalWrite(motor2Pin2, HIGH);\n&nbsp; server.send(200);\n}\nvoid handleStop() {\n&nbsp; Serial.println(\"Stop\");\n&nbsp; digitalWrite(motor1Pin1, LOW);\n&nbsp; digitalWrite(motor1Pin2, LOW);\n&nbsp; digitalWrite(motor2Pin1, LOW);\n&nbsp; digitalWrite(motor2Pin2, LOW); &nbsp;\n&nbsp; server.send(200);\n}\nvoid handleRight() {\n&nbsp; Serial.println(\"Right\");\n&nbsp; digitalWrite(motor1Pin1, LOW);\n&nbsp; digitalWrite(motor1Pin2, HIGH);\n&nbsp; digitalWrite(motor2Pin1, LOW);\n&nbsp; digitalWrite(motor2Pin2, LOW); &nbsp; \n&nbsp; server.send(200);\n}\n\nvoid handleReverse() {\n&nbsp; Serial.println(\"Reverse\");\n&nbsp; digitalWrite(motor1Pin1, HIGH);\n&nbsp; digitalWrite(motor1Pin2, LOW);\n&nbsp; digitalWrite(motor2Pin1, HIGH);\n&nbsp; digitalWrite(motor2Pin2, LOW); &nbsp; &nbsp; &nbsp; &nbsp; \n\n&nbsp; server.send(200);\n}<\/code><\/pre>\n\n\n\n<p>The combination of HIGH and LOW signals required to move the robot in a specific direction was explained previously.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Controlling the Speed<\/h4>\n\n\n\n<p>To control the motor speed using a slider, the slider&#8217;s value is sent to the server, which adjusts the PWM duty cycle accordingly.<\/p>\n\n\n\n<p>This is the part of the javascript code that sends a request to the server with the current slider value when you move the slider to a new position:<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>function updateMotorSpeed(pos) {\n&nbsp; document.getElementById('motorSpeed').innerHTML = pos;\n&nbsp; fetch(`\/speed?value=${pos}`);\n}<\/code><\/pre>\n\n\n\n<p>It will make a request with the following format:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\/speed?value=SELECTED_SPEED_VALUE<\/code><\/pre>\n\n\n\n<p>On the ESP32, on the <span class=\"rnthl rntliteral\">handleSpeed()<\/span> function, we start by getting the value of the slider and saving it on the <span class=\"rnthl rntliteral\">value<\/span> variable as follows.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>void handleSpeed() {\n&nbsp; if (server.hasArg(\"value\")) {\n&nbsp; &nbsp; valueString = server.arg(\"value\");\n&nbsp; &nbsp; int value = valueString.toInt();<\/code><\/pre>\n\n\n\n<p>If the slider value is zero, the motors are stopped. So, we set the duty cycle to <span class=\"rnthl rntliteral\">0<\/span> and all motor pins to <span class=\"rnthl rntliteral\">LOW<\/span>.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>if (value == 0) {\n&nbsp; ledcWrite(enable1Pin, 0);\n&nbsp; ledcWrite(enable2Pin, 0);\n&nbsp; digitalWrite(motor1Pin1, LOW);\n&nbsp; digitalWrite(motor1Pin2, LOW);\n&nbsp; digitalWrite(motor2Pin1, LOW);\n&nbsp; digitalWrite(motor2Pin2, LOW); &nbsp;\n}<\/code><\/pre>\n\n\n\n<p>Otherwise, we set the speed of the motors by adjusting the duty cycle taking into account the slider value.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>} else {\n&nbsp; dutyCycle = map(value, 25, 100, 200, 255);\n&nbsp; ledcWrite(enable1Pin, dutyCycle);\n&nbsp; ledcWrite(enable2Pin, dutyCycle);\n&nbsp; Serial.println(\"Motor speed set to \" + String(value));\n}<\/code><\/pre>\n\n\n\n<p>We calculate the duty cycle based on the slider value using the <span class=\"rnthl rntliteral\">map()<\/span>function (<a href=\"https:\/\/www.arduino.cc\/reference\/en\/language\/functions\/math\/map\/\" target=\"_blank\" rel=\"noreferrer noopener\">learn more about the Arduino map() function<\/a>). In this case, we set the duty cycle to start at 200 because lower values won\u2019t make the robot move, and the motors will make a weird buzz sound, you may need to adjust depending on the behavior of your motors.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Displaying the web page<\/h4>\n\n\n\n<p>The following part of the code displays a web page with 5 buttons to control the motor and a slider to set the motor speed. We use the javascript <span class=\"rnthl rntliteral\">fetch()<\/span> function to make requests when a button is clicked on.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>void handleRoot() {\n  const char html&#091;] PROGMEM = R\"rawliteral(\n  &lt;!DOCTYPE HTML&gt;&lt;html&gt;\n  &lt;head&gt;\n    &lt;meta name=\"viewport\" content=\"width=device-width, initial-scale=1\"&gt;\n    &lt;link rel=\"icon\" href=\"data:,\"&gt;\n    &lt;style&gt;\n      html { font-family: Helvetica; display: inline-block; margin: 0px auto; text-align: center; }\n      .button { -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; user-select: none; background-color: #4CAF50; border: none; color: white; padding: 12px 28px; text-decoration: none; font-size: 26px; margin: 1px; cursor: pointer; }\n      .button2 {background-color: #555555;}\n    &lt;\/style&gt;\n    &lt;script&gt;\n      function moveForward() { fetch('\/forward'); }\n      function moveLeft() { fetch('\/left'); }\n      function stopRobot() { fetch('\/stop'); }\n      function moveRight() { fetch('\/right'); }\n      function moveReverse() { fetch('\/reverse'); }\n\n      function updateMotorSpeed(pos) {\n        document.getElementById('motorSpeed').innerHTML = pos;\n        fetch(`\/speed?value=${pos}`);\n      }\n    &lt;\/script&gt;\n  &lt;\/head&gt;\n  &lt;body&gt;\n    &lt;h1&gt;ESP32 Motor Control&lt;\/h1&gt;\n    &lt;p&gt;&lt;button class=\"button\" onclick=\"moveForward()\"&gt;FORWARD&lt;\/button&gt;&lt;\/p&gt;\n    &lt;div style=\"clear: both;\"&gt;\n      &lt;p&gt;\n        &lt;button class=\"button\" onclick=\"moveLeft()\"&gt;LEFT&lt;\/button&gt;\n        &lt;button class=\"button button2\" onclick=\"stopRobot()\"&gt;STOP&lt;\/button&gt;\n        &lt;button class=\"button\" onclick=\"moveRight()\"&gt;RIGHT&lt;\/button&gt;\n      &lt;\/p&gt;\n    &lt;\/div&gt;\n    &lt;p&gt;&lt;button class=\"button\" onclick=\"moveReverse()\"&gt;REVERSE&lt;\/button&gt;&lt;\/p&gt;\n    &lt;p&gt;Motor Speed: &lt;span id=\"motorSpeed\"&gt;0&lt;\/span&gt;&lt;\/p&gt;\n    &lt;input type=\"range\" min=\"0\" max=\"100\" step=\"25\" id=\"motorSlider\" oninput=\"updateMotorSpeed(this.value)\" value=\"0\"\/&gt;\n  &lt;\/body&gt;\n  &lt;\/html&gt;)rawliteral\";\n  server.send(200, \"text\/html\", html);\n}<\/code><\/pre>\n\n\n\n<h4 class=\"wp-block-heading\">loop()<\/h4>\n\n\n\n<p>The following line in the <span class=\"rnthl rntliteral\">loop()<\/span> ensures that the ESP32 is always listening for incoming client requests.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>server.handleClient();<\/code><\/pre>\n\n\n\n<h1 class=\"wp-block-heading\" id=\"testing\">Testing the Web Server<\/h1>\n\n\n\n<p>Now, you can test the web server. Make sure you\u2019ve modified the code to include your network credentials. Don\u2019t forget to check if you have the right board and COM port selected. Then, click the upload button. When the upload is finished, open the Serial Monitor at a baud rate of 115200.<\/p>\n\n\n\n<p>Press the ESP32 Enable (EN) button, and you\u2019ll get the ESP32 IP address.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"666\" height=\"377\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/09\/esp32-robot-connected.png?resize=666%2C377&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"Getting ESP32 Web Server IP address\" class=\"wp-image-162249\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/09\/esp32-robot-connected.png?w=666&amp;quality=100&amp;strip=all&amp;ssl=1 666w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/09\/esp32-robot-connected.png?resize=300%2C170&amp;quality=100&amp;strip=all&amp;ssl=1 300w\" sizes=\"(max-width: 666px) 100vw, 666px\" \/><\/figure><\/div>\n\n\n<p>Disconnect the ESP32 from your computer and power it with the portable charger.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"750\" height=\"422\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/09\/powering-ESP32-robot-portable-charger.jpg?resize=750%2C422&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"powering ESP32 robot with portable charger\" class=\"wp-image-162250\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/09\/powering-ESP32-robot-portable-charger.jpg?w=750&amp;quality=100&amp;strip=all&amp;ssl=1 750w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/09\/powering-ESP32-robot-portable-charger.jpg?resize=300%2C169&amp;quality=100&amp;strip=all&amp;ssl=1 300w\" sizes=\"(max-width: 750px) 100vw, 750px\" \/><\/figure><\/div>\n\n\n<p>Make sure you also have the 4 AA batteries in place, and the slider switch turned on. Open your browser, and paste the ESP32 IP address to access the web server. You can use any device with a browser inside your local network to control the robot.<\/p>\n\n\n\n<p>Now, you can control your robot.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"750\" height=\"421\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/09\/control-robot-web-server-esp32.jpg?resize=750%2C421&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"ESP32 Wi-Fi Car Robot remote controlled demonstration\" class=\"wp-image-162251\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/09\/control-robot-web-server-esp32.jpg?w=750&amp;quality=100&amp;strip=all&amp;ssl=1 750w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/09\/control-robot-web-server-esp32.jpg?resize=300%2C168&amp;quality=100&amp;strip=all&amp;ssl=1 300w\" sizes=\"(max-width: 750px) 100vw, 750px\" \/><\/figure><\/div>\n\n\n<p><strong>Important:<\/strong> If the motors are spinning in the wrong direction, you can simply switch the motor wires. For example, switch the wire that goes to OUT1 with OUT2. Or OUT3 with OUT4. That should solve your problem.<\/p>\n\n\n\n<h1 class=\"wp-block-heading\">Demonstration<\/h1>\n\n\n\n<p>Congratulations! The ESP32 Wi-Fi Remote Controlled Car Robot is complete! You can make your robot go forward, backward, right, and left. You can stop it by tapping the STOP button. A cool feature of this robot is that you can also adjust the speed with the slider.<\/p>\n\n\n\n<p>The robot works pretty well and responds instantaneously to the commands.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"750\" height=\"422\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/09\/ESP32-Car-Robot-Final-Result.jpg?resize=750%2C422&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"ESP32 Wi-Fi Controlled Car Robot\" class=\"wp-image-162252\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/09\/ESP32-Car-Robot-Final-Result.jpg?w=750&amp;quality=100&amp;strip=all&amp;ssl=1 750w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/09\/ESP32-Car-Robot-Final-Result.jpg?resize=300%2C169&amp;quality=100&amp;strip=all&amp;ssl=1 300w\" sizes=\"(max-width: 750px) 100vw, 750px\" \/><\/figure><\/div>\n\n\n<h2 class=\"wp-block-heading\">Wrapping Up<\/h2>\n\n\n\n<p>Now, we encourage you to modify the robot with some upgrades. For example:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Add an <a href=\"https:\/\/randomnerdtutorials.com\/electronics-basics-how-do-rgb-leds-work\/\" title=\"\">RGB LED<\/a> that changes color depending on the direction the robot is moving;<\/li>\n\n\n\n<li>Add an <a href=\"https:\/\/randomnerdtutorials.com\/esp32-hc-sr04-ultrasonic-arduino\/\" title=\"\">ultrasonic sensor<\/a> that makes the robot stop when it senses &nbsp;an obstacle;<\/li>\n<\/ul>\n\n\n\n<p>We hope you had fun building the robot. Here are other similar projects you may like:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><a href=\"https:\/\/randomnerdtutorials.com\/esp32-cam-car-robot-web-server\/\">ESP32-CAM Remote Controlled Car Robot Web Server<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/randomnerdtutorials.com\/esp32-cam-pan-and-tilt-2-axis\/\">ESP32-CAM Pan and Tilt Video Streaming Web Server (2 Axis)<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/randomnerdtutorials.com\/esp32-web-server-dc-motor-arduino\/\">ESP32 Web Server: Control a DC Motor (Arduino IDE)<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/randomnerdtutorials.com\/esp32-servo-motor-web-server-arduino-ide\/\">ESP32 Servo Motor Web Server with Arduino IDE<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/randomnerdtutorials.com\/stepper-motor-esp32-websocket\/\">ESP32 Web Server: Control Stepper Motor (WebSocket)<\/a><\/li>\n<\/ul>\n\n\n\n<p>Learn more about the ESP32 with our resources:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><a href=\"https:\/\/randomnerdtutorials.com\/learn-esp32-with-arduino-ide\/\" title=\"\">Learn ESP32 with Arduino IDE (eBook)<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/randomnerdtutorials.com\/build-web-servers-esp32-esp8266-ebook\/\" title=\"\">Build Web Servers with ESP32 and ESP8266 (eBook)<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/randomnerdtutorials.com\/projects-esp32\/\">Free ESP32 Projects and Tutorials<\/a><\/li>\n<\/ul>\n\n\n\n<p>Thanks for reading.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In this project, you&#8217;ll learn how to build an ESP32 Wi-Fi remote controlled car robot step by step. You&#8217;ll control the robot using a web server to make the robot &#8230; <\/p>\n<p class=\"read-more-container\"><a title=\"ESP32 Remote-Controlled Wi-Fi Car Robot (Arduino IDE)\" class=\"read-more button\" href=\"https:\/\/randomnerdtutorials.com\/esp32-wi-fi-car-robot-arduino\/#more-162234\" aria-label=\"Read more about ESP32 Remote-Controlled Wi-Fi Car Robot (Arduino IDE)\">CONTINUE READING \u00bb<\/a><\/p>\n","protected":false},"author":5,"featured_media":162254,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[281,276,277,299,264],"tags":[],"class_list":["post-162234","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-esp32-project","category-esp32","category-esp32-arduino-ide","category-0-esp32","category-project"],"aioseo_notices":[],"jetpack_featured_media_url":"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/09\/ESP32-Remote-Controlled-Wi-Fi-Car-Robot.jpg?fit=1920%2C1080&quality=100&strip=all&ssl=1","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/posts\/162234","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/users\/5"}],"replies":[{"embeddable":true,"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/comments?post=162234"}],"version-history":[{"count":14,"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/posts\/162234\/revisions"}],"predecessor-version":[{"id":162781,"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/posts\/162234\/revisions\/162781"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/media\/162254"}],"wp:attachment":[{"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/media?parent=162234"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/categories?post=162234"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/tags?post=162234"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}