ESP32 - Bestuurt Auto via Web
Deze handleiding laat zien hoe u met de ESP32 draadloos een robotauto bestuurt vanuit een webbrowser op uw smartphone of pc via WiFi. De bediening gebeurt via een grafische web interface met behulp van WebSocket, wat zorgt voor een vloeiende en dynamische besturing van de auto.
Of u kunt de volgende kits kopen:
Openbaarmaking: Sommige van de links in deze sectie zijn Amazon-affiliate links. We kunnen een commissie ontvangen voor aankopen die via deze links worden gedaan, zonder extra kosten voor u. We waarderen uw steun.
Waarom kiezen we voor WebSocket? Hier is het verhaal:
Zonder WebSocket zou het veranderen van rijrichting elke keer de pagina moeten herladen. Niet ideaal!
Met WebSocket maken we een speciale verbinding tussen de webpagina en de ESP32. Dit maakt het mogelijk om commando’s op de achtergrond naar de ESP32 te sturen zonder dat de pagina hoeft te herladen. Het resultaat? De robotauto bestuurt soepel en in realtime. Heel gaaf, toch?
Kortom, de WebSocket verbinding maakt vloeiende, realtime besturing van de robot mogelijk.
We hebben specifieke tutorials over de 2WD RC Auto en WebSocket. Elke tutorial bevat gedetailleerde informatie en stapsgewijze instructies over hardware pinout, werkingsprincipe, wiring naar ESP32, ESP32 code… Lees er meer over via de volgende links:
De ESP32 code creëert zowel een webserver als een WebSocket Server. Zo werkt het:
Wanneer u het IP-adres van de ESP32 invoert in een webbrowser, vraagt deze de webpagina (gebruikersinterface) op bij de ESP32.
De webserver van de ESP32 reageert door de inhoud van de webpagina te verzenden (HTML, CSS, JavaScript).
Uw webbrowser toont vervolgens de webpagina.
De JavaScript code in de pagina maakt een WebSocket verbinding met de WebSocket server op de ESP32.
Zodra deze WebSocket verbinding is gelegd, zal de JavaScript code bij het indrukken of loslaten van buttons op de webpagina stilletjes commando’s versturen naar de ESP32 via deze WebSocket verbinding op de achtergrond.
De WebSocket server op de ESP32 ontvangt de commando’s en bestuurt vervolgens de robotauto overeenkomstig.
De onderstaande tabel toont de lijst met commando’s die de webpagina naar de ESP32 stuurt op basis van de acties van de gebruiker:
| Gebruikersactie | Knop | Commando | Auto Actie |
| INSDRUKKEN | UP | 1 | VOORUIT RIJDEN |
| INSDRUKKEN | DOWN | 2 | ACHTERUIT RIJDEN |
| INSDRUKKEN | LEFT | 4 | LINKS DRAAIEN |
| INSDRUKKEN | RIGHT | 8 | RECHTS DRAAIEN |
| INSDRUKKEN | STOP | 0 | STOPPEN |
| LOSLATEN | UP | 0 | STOPPEN |
| LOSLATEN | DOWN | 0 | STOPPEN |
| LOSLATEN | LEFT | 0 | STOPPEN |
| LOSLATEN | RIGHT | 0 | STOPPEN |
| LOSLATEN | STOP | 0 | STOPPEN |

This image is created using Fritzing. Click to enlarge image
Gewoonlijk heeft u twee stroombronnen nodig:
Maar u kunt het vereenvoudigen door slechts één stroombron te gebruiken – vier 1.5V batterijen (totaal 6V). Zo werkt het:
Verbind de batterijen met de L298N module zoals weergegeven.
Verwijder twee jumpers van de ENA en ENB pinnen naar de 5 volts op de L298N module.
Voeg een jumper toe met label 5VEN (gele cirkel op het schema).
Verbind de 12V pin op de L298N module met de Vin pin op de ESP32 om deze direct van de batterijen te voeden.
Omdat de 2WD RC auto een aan/uit-schakelaar heeft, kunt u optioneel de batterij via deze schakelaar aansluiten om de voeding van de auto in- of uit te schakelen. Wilt u het simpel houden, dan kunt u de schakelaar negeren.
De inhoud van de webpagina (HTML, CSS, JavaScript) is apart opgeslagen in een index.h bestand. U gebruikt dus twee codebestanden in Arduino IDE:
Een .ino bestand met de ESP32 code, die een webserver en een WebSocket Server creëert en de auto bestuurt
Een .h bestand dat de inhoud van de webpagina bevat
Maak de bedrading volgens bovenstaande afbeelding.
Verbind het ESP32 bord met uw pc via een micro USB kabel.
Open Arduino IDE op uw pc.
Selecteer het juiste ESP32 bord (bijv. ESP32 Dev Module) en de juiste COM-poort.
Open de Library Manager door te klikken op het Library Manager icoon in de linker zijbalk van Arduino IDE.
Zoek op “DIYables ESP32 WebServer” en vind de Web Server library gemaakt door DIYables.
Klik op de knop Installeren om de Web Server library te installeren.
Maak in Arduino IDE een nieuw sketch en geef het een naam, bijvoorbeeld newbiely.com.ino
Kopieer onderstaande code en open deze in Arduino IDE
#include <DIYables_ESP32_WebServer.h>
#include "index.h"
#define CMD_STOP 0
#define CMD_FORWARD 1
#define CMD_BACKWARD 2
#define CMD_LEFT 4
#define CMD_RIGHT 8
#define ENA_PIN 14
#define IN1_PIN 27
#define IN2_PIN 26
#define IN3_PIN 25
#define IN4_PIN 33
#define ENB_PIN 32
const char WIFI_SSID[] = "YOUR_WIFI_SSID";
const char WIFI_PASSWORD[] = "YOUR_WIFI_PASSWORD";
DIYables_ESP32_WebServer server;
DIYables_ESP32_WebSocket* webSocket;
void handleHome(WiFiClient& client, const String& method, const String& request, const QueryParams& params, const String& jsonData) {
server.sendResponse(client, HTML_CONTENT);
}
void onWebSocketOpen(net::WebSocket& ws) {
Serial.println("New WebSocket connection");
const char welcome[] = "Connected to ESP32 WebSocket Server!";
}
void onWebSocketMessage(net::WebSocket& ws, const net::WebSocket::DataType dataType, const char* message, uint16_t length) {
String angle = String(message);
int command = angle.toInt();
Serial.print("command: ");
Serial.println(command);
switch (command) {
case CMD_STOP:
Serial.println("Stop");
CAR_stop();
break;
case CMD_FORWARD:
Serial.println("Move Forward");
CAR_moveForward();
break;
case CMD_BACKWARD:
Serial.println("Move Backward");
CAR_moveBackward();
break;
case CMD_LEFT:
Serial.println("Turn Left");
CAR_turnLeft();
break;
case CMD_RIGHT:
Serial.println("Turn Right");
CAR_turnRight();
break;
default:
Serial.println("Unknown command");
}
}
void onWebSocketClose(net::WebSocket& ws, const net::WebSocket::CloseCode code, const char* reason, uint16_t length) {
Serial.println("WebSocket client disconnected");
}
void setup() {
Serial.begin(9600);
delay(1000);
pinMode(ENA_PIN, OUTPUT);
pinMode(IN1_PIN, OUTPUT);
pinMode(IN2_PIN, OUTPUT);
pinMode(IN3_PIN, OUTPUT);
pinMode(IN4_PIN, OUTPUT);
pinMode(ENB_PIN, OUTPUT);
digitalWrite(ENA_PIN, HIGH);
digitalWrite(ENB_PIN, HIGH);
Serial.println("ESP32 Web Server and WebSocket Server");
server.addRoute("/", handleHome);
server.begin(WIFI_SSID, WIFI_PASSWORD);
webSocket = server.enableWebSocket(81);
if (webSocket != nullptr) {
webSocket->onOpen(onWebSocketOpen);
webSocket->onMessage(onWebSocketMessage);
webSocket->onClose(onWebSocketClose);
} else {
Serial.println("Failed to start WebSocket server");
}
}
void loop() {
server.handleClient();
server.handleWebSocket();
}
void CAR_moveForward() {
digitalWrite(IN1_PIN, HIGH);
digitalWrite(IN2_PIN, LOW);
digitalWrite(IN3_PIN, HIGH);
digitalWrite(IN4_PIN, LOW);
}
void CAR_moveBackward() {
digitalWrite(IN1_PIN, LOW);
digitalWrite(IN2_PIN, HIGH);
digitalWrite(IN3_PIN, LOW);
digitalWrite(IN4_PIN, HIGH);
}
void CAR_turnLeft() {
digitalWrite(IN1_PIN, HIGH);
digitalWrite(IN2_PIN, LOW);
digitalWrite(IN3_PIN, LOW);
digitalWrite(IN4_PIN, LOW);
}
void CAR_turnRight() {
digitalWrite(IN1_PIN, LOW);
digitalWrite(IN2_PIN, LOW);
digitalWrite(IN3_PIN, HIGH);
digitalWrite(IN4_PIN, LOW);
}
void CAR_stop() {
digitalWrite(IN1_PIN, LOW);
digitalWrite(IN2_PIN, LOW);
digitalWrite(IN3_PIN, LOW);
digitalWrite(IN4_PIN, LOW);
}
Pas de WiFi gegevens (SSID en wachtwoord) in de code aan naar uw eigen netwerkgegevens.
Maak het index.h bestand aan in Arduino IDE door:


const char *HTML_CONTENT = R"=====(
<!DOCTYPE html>
<html>
<head>
<title>ESP32 Control Car via Web</title>
<meta name="viewport" content="width=device-width, initial-scale=0.7, maximum-scale=1, user-scalable=no">
<style type="text/css">
body { text-align: center; font-size: 24px;}
button { text-align: center; font-size: 24px;}
#container {
margin-right: auto;
margin-left: auto;
width: 400px;
height: 400px;
position: relative;
margin-bottom: 10px;
}
div[class^='button'] { position: absolute; }
.button_up, .button_down { width:214px; height:104px;}
.button_left, .button_right { width:104px; height:214px;}
.button_stop { width:178px; height:178px;}
.button_up {
background: url('https://esp32io.com/images/tutorial/up_inactive.png') no-repeat;
background-size: contain;
left: 200px;
top: 0px;
transform: translateX(-50%);
}
.button_down {
background: url('https://esp32io.com/images/tutorial/down_inactive.png') no-repeat;
background-size: contain;
left:200px;
bottom: 0px;
transform: translateX(-50%);
}
.button_right {
background: url('https://esp32io.com/images/tutorial/right_inactive.png') no-repeat;
background-size: contain;
right: 0px;
top: 200px;
transform: translateY(-50%);
}
.button_left {
background: url('https://esp32io.com/images/tutorial/left_inactive.png') no-repeat;
background-size: contain;
left:0px;
top: 200px;
transform: translateY(-50%);
}
.button_stop {
background: url('https://esp32io.com/images/tutorial/stop_inactive.png') no-repeat;
background-size: contain;
left:200px;
top: 200px;
transform: translate(-50%, -50%);
}
</style>
<script>
var CMD_STOP = 0;
var CMD_FORWARD = 1;
var CMD_BACKWARD = 2;
var CMD_LEFT = 4;
var CMD_RIGHT = 8;
var img_name_lookup = {
[CMD_STOP]: "stop",
[CMD_FORWARD]: "up",
[CMD_BACKWARD]: "down",
[CMD_LEFT]: "left",
[CMD_RIGHT]: "right"
}
var ws = null;
function init()
{
var container = document.querySelector("#container");
container.addEventListener("touchstart", mouse_down);
container.addEventListener("touchend", mouse_up);
container.addEventListener("touchcancel", mouse_up);
container.addEventListener("mousedown", mouse_down);
container.addEventListener("mouseup", mouse_up);
container.addEventListener("mouseout", mouse_up);
}
function ws_onmessage(e_msg)
{
e_msg = e_msg || window.event;
}
function ws_onopen()
{
document.getElementById("ws_state").innerHTML = "OPEN";
document.getElementById("wc_conn").innerHTML = "Disconnect";
}
function ws_onclose()
{
document.getElementById("ws_state").innerHTML = "CLOSED";
document.getElementById("wc_conn").innerHTML = "Connect";
console.log("socket was closed");
ws.onopen = null;
ws.onclose = null;
ws.onmessage = null;
ws = null;
}
function wc_onclick()
{
if(ws == null)
{
ws = new WebSocket("ws:
document.getElementById("ws_state").innerHTML = "CONNECTING";
ws.onopen = ws_onopen;
ws.onclose = ws_onclose;
ws.onmessage = ws_onmessage;
}
else
ws.close();
}
function mouse_down(event)
{
if (event.target !== event.currentTarget)
{
var id = event.target.id;
send_command(id);
event.target.style.backgroundImage = "url('https://esp32io.com/images/tutorial/" + img_name_lookup[id] + "_active.png')";
}
event.stopPropagation();
event.preventDefault();
}
function mouse_up(event)
{
if (event.target !== event.currentTarget)
{
var id = event.target.id;
send_command(CMD_STOP);
event.target.style.backgroundImage = "url('https://esp32io.com/images/tutorial/" + img_name_lookup[id] + "_inactive.png')";
}
event.stopPropagation();
event.preventDefault();
}
function send_command(cmd)
{
if(ws != null)
if(ws.readyState == 1)
ws.send(cmd + "\r\n");
}
window.onload = init;
</script>
</head>
<body>
<h2>ESP32 - RC Car via Web</h2>
<div id="container">
<div id="0" class="button_stop"></div>
<div id="1" class="button_up"></div>
<div id="2" class="button_down"></div>
<div id="8" class="button_right"></div>
<div id="4" class="button_left"></div>
</div>
<p>
WebSocket : <span id="ws_state" style="color:blue">closed</span><br>
</p>
<button id="wc_conn" type="button" onclick="wc_onclick();">Connect</button>
<br>
<br>
<div class="sponsor">Sponsored by <a href="https://amazon.com/diyables">DIYables</a></div>
</body>
</html>
)=====";
Nu heeft u de code in twee bestanden: newbiely.com.ino en index.h.
Klik op de knop Upload in Arduino IDE om de code naar de ESP32 te uploaden.
Open de Serial Monitor.
Bekijk het resultaat in de Serial Monitor.
Connecting to WiFi...
Connected to WiFi
ESP32 Web Server's IP address IP address: 192.168.0.2
De JavaScript code van de webpagina maakt automatisch de WebSocket-verbinding met de ESP32.
Nu kunt u via de webinterface de auto vooruit/achteruit laten rijden, en links/rechts laten draaien.
Om het geheugen van de ESP32 te sparen, zijn de afbeeldingen van de bedieningsknoppen NIET opgeslagen op de ESP32. In plaats daarvan worden ze van het internet geladen, dus uw telefoon of pc moet verbonden zijn met internet om deze afbeeldingen te kunnen laden voor de webbediening.
※ Notiz:
Als u de HTML-inhoud in het index.h bestand wijzigt en het newbiely.com.ino bestand ongemoeid laat, zal Arduino IDE bij compileren en uploaden de HTML-inhoud niet bijwerken.
Om Arduino IDE in dit geval de HTML-inhoud te laten updaten, maak dan een kleine wijziging in het newbiely.com.ino bestand (bijvoorbeeld een lege regel toevoegen, een commentaar toevoegen...).
De bovenstaande ESP32 code bevat een regel-voor-regel uitleg in de comments. Lees de opmerkingen in de code goed door!