Arduino - besturing van auto via Web
Deze tutorial legt uit hoe u draadloos een robotauto bestuurt met een Arduino via een webbrowser op uw smartphone of pc via WiFi. De besturing verloopt via een grafische webgebruikersinterface die gebruikmaakt van WebSocket-technologie, waardoor soepele en dynamische bediening van de auto mogelijk is.
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 voor WebSocket? Hieronder de redenen:
Zonder WebSocket zou u elke keer de pagina moeten herladen wanneer u de rijrichting van de auto wilt veranderen. Dat is niet efficiënt!
Met WebSocket wordt er een speciale verbinding opgezet tussen de webpagina en de Arduino. Dit maakt het mogelijk om commando’s op de achtergrond naar de Arduino te sturen, zonder de pagina te hoeven herladen. Het resultaat? De robotauto reageert soepel en direct. Best indrukwekkend, toch?
Kortom, WebSocket zorgt voor een vloeiende, real-time besturing van de robotauto.
We hebben aparte tutorials over de 2WD RC Auto en WebSocket. Elke tutorial bevat gedetailleerde informatie en stapsgewijze instructies over hardware pinout, werkingsprincipe, bekabeling met Arduino, Arduino code... Leer er meer over via de volgende links:
De Arduino code zet zowel een webserver als een WebSocket server op. Zo werkt het:
Wanneer u het IP-adres van de Arduino intypt in een webbrowser, vraagt deze een webpagina (gebruikersinterface) op bij de Arduino.
De webserver van de Arduino reageert door de inhoud van de webpagina (HTML, CSS, JavaScript) te versturen.
Uw webbrowser toont vervolgens deze webpagina.
Binnen deze pagina start de JavaScript-code een WebSocket-verbinding met de WebSocket-server op de Arduino.
Zodra de WebSocket-verbinding actief is, stuurt de JavaScript discreet commando’s naar de Arduino telkens u een knop indrukt of loslaat op de webpagina.
De WebSocket-server op de Arduino ontvangt deze commando’s en bestuurt de robotauto overeenkomstig.
Hieronder vindt u een tabel met de lijst van commando’s die de webpagina naar de Arduino stuurt, afhankelijk van de gebruikersactie:
| Gebruikersactie | Knop | Commando | Actie auto |
| DRUKKEN | UP | 1 | VOORWAARTS RIJDEN |
| DRUKKEN | DOWN | 2 | ACHTERWAARTS RIJDEN |
| DRUKKEN | LEFT | 4 | LINKS DRAAIEN |
| DRUKKEN | RIGHT | 8 | RECHTS DRAAIEN |
| DRUKKEN | STOP | 0 | STOPPEN |
| LOSSEN | UP | 0 | STOPPEN |
| LOSSEN | DOWN | 0 | STOPPEN |
| LOSSEN | LEFT | 0 | STOPPEN |
| LOSSEN | RIGHT | 0 | STOPPEN |
| LOSSEN | STOP | 0 | STOPPEN |

This image is created using Fritzing. Click to enlarge image
Normaal gesproken zijn er twee aparte voedingsbronnen nodig:
U kunt deze opstelling vereenvoudigen door slechts één voeding te gebruiken – vier 1.5V batterijen die samen 6V leveren. Zo werkt het:
Sluit de batterijen aan op de L298N-module zoals aangegeven.
Verwijder de twee jumpers van de ENA- en ENB-pinnen naar de 5 volt op de L298N-module.
Plaats een jumper gemarkeerd 5VEN (aangeduid door een gele cirkel in het schema).
Verbind de 12V-pin op de L298N-module met de Vin-pin van de Arduino. Zo krijgt de Arduino direct stroom van de batterijen.
De 2WD RC auto is uitgerust met een aan/uit-schakelaar, waarmee u de batterij via de schakelaar kunt verbinden. Hiermee kunt u de stroom naar de auto eenvoudig aan- en uitzetten. Wilt u het liever simpel houden, dan kunt u de schakelaar ook geheel overslaan.
De inhoud van de webpagina (HTML, CSS, JavaScript) wordt opgeslagen in een aparte index.h-bestand. Op Arduino IDE heeft u dus twee codebestanden:
Maak de verbindingen zoals in bovenstaand schema.
Verbind het Arduino-bord met uw pc via een micro USB-kabel.
Open Arduino IDE op uw pc.
Selecteer het juiste Arduino-bord (Arduino Uno R4 WiFi) en de juiste COM-poort.
Open de Library Manager door te klikken op het Library Manager icoon in de linkernavigatiebalk van Arduino IDE.
Zoek naar Web Server for Arduino Uno R4 WiFi en vind de Web Server-bibliotheek gemaakt door DIYables.
Klik op de Installeren knop om de Web Server library te installeren.
Maak in Arduino IDE een nieuwe sketch aan, geef deze een naam, bijvoorbeeld ArduinoGetStarted.com.ino
Kopieer onderstaande code en open deze met Arduino IDE
#include <UnoR4WiFi_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 7
#define IN1_PIN 6
#define IN2_PIN 5
#define IN3_PIN 4
#define IN4_PIN 3
#define ENB_PIN 2
const char WIFI_SSID[] = "YOUR_WIFI_SSID";
const char WIFI_PASSWORD[] = "YOUR_WIFI_PASSWORD";
UnoR4WiFi_WebServer server(80);
UnoR4WiFi_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");
}
void onWebSocketMessage(net::WebSocket& ws, const net::WebSocket::DataType dataType, const char* message, uint16_t length) {
String cmd_str = String((char*)message);
int command = cmd_str.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("Arduino Uno R4 WiFi - 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();
delay(10);
}
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 zodat deze overeenkomen met uw eigen netwerk.
Maak het bestand index.h aan in Arduino IDE door:


const char *HTML_CONTENT = R"=====(
<!DOCTYPE html>
<html>
<head>
<title>Arduino 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>Arduino - 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 twee codebestanden: ArduinoGetStarted.com.ino en index.h
Klik op de Upload knop in Arduino IDE om de code naar de Arduino te uploaden.
Open de Seriële Monitor
Kijk wat er op de Seriële Monitor verschijnt.
Arduino Uno R4 WiFi - WebSocket Server
Connected! IP Address: 192.168.0.254
SSID: YOUR_WIFI_SSID
IP Address: 192.168.0.254
Signal strength (RSSI): -44 dBm
WebSocket server started on port 81
WebSocket URL: ws://192.168.0.254:81
WebSocket server enabled successfully
Klik op de CONNECT-knop om de webpagina via WebSocket met Arduino te verbinden.
Nu kunt u de auto besturen en laten links/rechts draaien, voorwaarts/achterwaarts rijden via de webinterface.
Om Arduino-geheugen te besparen, worden de afbeeldingen van de bedieningsknoppen NIET op Arduino opgeslagen. In plaats daarvan staan ze op het internet, dus uw telefoon of pc moet met internet verbonden zijn om de afbeeldingen voor de webbediening te laden.
※ Notiz:
Als u de HTML-inhoud in index.h wijzigt zonder iets aan te passen in het ArduinoGetStarted.com.ino bestand, dan update de Arduino IDE de HTML-inhoud niet bij compileren en uploaden.
Om Arduino IDE de HTML-inhoud toch te laten updaten, maakt u een kleine wijziging in het ArduinoGetStarted.com.ino bestand (bijvoorbeeld een lege regel toevoegen of een commentaarregel).
De bovenstaande Arduino code bevat commentaar met regel-voor-regel uitleg. Lees de opmerkingen in de code zorgvuldig!