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.

Arduino bestuurt robotauto via Web

Over 2WD RC Auto en WebSocket

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:

Hoe Het Werkt

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

Bedradingsschema tussen 2WD RC Auto en Arduino

Arduino 2WD RC Auto Bedradingsschema

This image is created using Fritzing. Click to enlarge image

Normaal gesproken zijn er twee aparte voedingsbronnen nodig:

  • Eén voor de motor.
  • Een andere voor zowel het Arduino-bord als de L298N-module (de motor driver).

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.

Arduino Code

De inhoud van de webpagina (HTML, CSS, JavaScript) wordt opgeslagen in een aparte index.h-bestand. Op Arduino IDE heeft u dus twee codebestanden:

  • Een .ino-bestand met Arduino code die een webserver en WebSocket-server opzet en de auto aanstuurt
  • Een .h-bestand met de inhoud van de webpagina

Snelle Stappen

  • Als u voor het eerst de Arduino Uno R4 gebruikt, bekijk dan eerst hoe u de omgeving voor Arduino Uno R4 instelt in de Arduino IDE.
  • 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.
Arduino UNO R4 Web Server bibliotheek
  • 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
/* * Deze Arduino code is ontwikkeld door newbiely.nl * Deze Arduino code wordt zonder enige beperking aan het publiek beschikbaar gesteld. * Voor volledige instructies en schema's, bezoek: * https://newbiely.nl/tutorials/arduino/arduino-controls-car-via-web */ #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 // The Arduino pin connected to the ENA pin L298N #define IN1_PIN 6 // The Arduino pin connected to the IN1 pin L298N #define IN2_PIN 5 // The Arduino pin connected to the IN2 pin L298N #define IN3_PIN 4 // The Arduino pin connected to the IN3 pin L298N #define IN4_PIN 3 // The Arduino pin connected to the IN4 pin L298N #define ENB_PIN 2 // The Arduino pin connected to the ENB pin L298N // WiFi credentials const char WIFI_SSID[] = "YOUR_WIFI_SSID"; const char WIFI_PASSWORD[] = "YOUR_WIFI_PASSWORD"; // Create web server instance UnoR4WiFi_WebServer server(80); UnoR4WiFi_WebSocket *webSocket; // Page handlers void handleHome(WiFiClient& client, const String& method, const String& request, const QueryParams& params, const String& jsonData) { server.sendResponse(client, HTML_CONTENT); } // WebSocket event handlers 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); // set full speed digitalWrite(ENB_PIN, HIGH); // set full speed Serial.println("Arduino Uno R4 WiFi - WebSocket Server"); // Configure web server routes server.addRoute("/", handleHome); // Start web server with WiFi connection server.begin(WIFI_SSID, WIFI_PASSWORD); // Enable WebSocket functionality webSocket = server.enableWebSocket(81); if (webSocket != nullptr) { // Set up WebSocket event handlers webSocket->onOpen(onWebSocketOpen); webSocket->onMessage(onWebSocketMessage); webSocket->onClose(onWebSocketClose); } else { Serial.println("Failed to start WebSocket server"); } } void loop() { // Handle HTTP requests and WebSocket connections using the library 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:
    • Ofwel te klikken op de knop net onder het seriële monitor-icoon en dan New Tab te kiezen, of gebruik Ctrl+Shift+N.
    Arduino IDE 2 voegt bestand toe
    • Geef het bestand de naam index.h en klik op OK.
    Arduino IDE 2 voegt bestand index.h toe
    • Kopieer onderstaande code en plak deze in index.h.
    /* * Deze Arduino code is ontwikkeld door newbiely.nl * Deze Arduino code wordt zonder enige beperking aan het publiek beschikbaar gesteld. * Voor volledige instructies en schema's, bezoek: * https://newbiely.nl/tutorials/arduino/arduino-controls-car-via-web */ 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; // MessageEvent //alert("msg : " + e_msg.data); } 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://" + window.location.host + ":81"); 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.
    COM6
    Send
    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
    Autoscroll Show timestamp
    Clear output
    9600 baud  
    Newline  
    • Noteer het IP-adres dat getoond wordt en voer dit in de adresbalk van een webbrowser op uw smartphone of pc in.
    • U ziet de webpagina zoals hieronder:
    Arduino bestuurt auto via webbrowser
    • 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).

    Regel-voor-regel uitleg van de code

    De bovenstaande Arduino code bevat commentaar met regel-voor-regel uitleg. Lees de opmerkingen in de code zorgvuldig!

※ ONZE BERICHTEN

  • U bent welkom om de link naar deze tutorial te delen. Gebruik onze inhoud echter niet op andere websites. We hebben veel moeite en tijd gestoken in het maken van de inhoud, respecteer alstublieft ons werk!