ESP32 - Servo Motor Besturen via Web

Deze handleiding legt uit hoe u de ESP32 gebruikt om een servo motor via het web te besturen, rechtstreeks vanuit een browser op uw smartphone of pc. We gebruiken iets genaamd WebSocket om de servo motor soepel en dynamisch te besturen via een grafische webgebruikersinterface.

De onderstaande video is een demonstratie:

Waarom WebSocket gebruiken? Hier is het idee:

Laten we beginnen!

Over Servo Motor en WebSocket

We hebben specifieke tutorials over servo motor en WebSocket. Elke tutorial bevat gedetailleerde informatie en stapsgewijze instructies over hardware pinout, werkingsprincipe, bedrading naar ESP32, ESP32 code… Meer leren over deze onderwerpen kan via de volgende links:

Hoe Werkt Het

De ESP32 code maakt zowel een webserver als een WebSocket-server aan. Zo werkt het:

  • Wanneer u het IP-adres van de ESP32 in een webbrowser invoert, wordt de webpagina (gebruikersinterface) opgevraagd bij de ESP32.
  • De webserver van de ESP32 reageert door de inhoud van de webpagina te versturen (HTML, CSS, JavaScript).
  • Uw webbrowser toont vervolgens de webpagina.
  • De JavaScript-code in de webpagina maakt een WebSocket-verbinding met de WebSocket-server op de ESP32.
  • Zodra deze WebSocket-verbinding tot stand is gebracht, stuurt de JavaScript-code ongemerkt de hoekwaarde naar de ESP32 via deze WebSocket-verbinding op de achtergrond, telkens wanneer u de hendel op de pagina draait.
  • De WebSocket-server op de ESP32 ontvangt de hoekwaarde en bestuurt de servo motor overeenkomstig.

Kortom, de WebSocket-verbinding maakt een soepele en realtime besturing van de hoek van de servo motor mogelijk.

Bedradingsschema tussen Servo Motor en ESP32

ESP32 Servo Motor Bedradingsschema

This image is created using Fritzing. Click to enlarge image

Als u niet weet hoe u ESP32 en andere componenten van stroom moet voorzien, vindt u instructies in de volgende tutorial: Hoe ESP32 van stroom te voorzien.

Voor de eenvoud wordt het bovenstaande bedradingsschema gebruikt voor test- of leerdoeleinden en voor servo motoren met een klein koppel. In de praktijk raden wij sterk aan om een externe voeding te gebruiken voor de servo motor. Het onderstaande bedradingsschema toont hoe de servo motor op een externe voedingsbron aangesloten kan worden.

ESP32 servo motor externe voeding bedradingsschema

This image is created using Fritzing. Click to enlarge image

Hieronder ziet u een echte bedrading tussen de servo motor en ESP32.

ESP32 servo motor voedingsbedrading

ESP32 Code

De inhoud van de webpagina (HTML, CSS, JavaScript) wordt apart opgeslagen in een index.h bestand. Dus, we hebben twee codebestanden in de Arduino IDE:

  • Een .ino bestand met de ESP32 code, dat een webserver en WebSocket-server aanmaakt en de servo motor bestuurt
  • Een .h bestand, dat de inhoud van de webpagina bevat

Snelle Stappen

  • Als u ESP32 voor het eerst gebruikt, zie dan hoe u de omgeving instelt voor ESP32 in Arduino IDE.
  • Maak de bedrading zoals hierboven in de afbeelding.
  • Sluit de ESP32 aan op uw pc via een micro USB-kabel.
  • Open Arduino IDE op uw pc.
  • Selecteer het juiste ESP32 board (bijv. ESP32 Dev Module) en de correcte COM-poort.
  • Open de Library Manager door te klikken op het Library Manager icoon in de linker navigatiebalk van Arduino IDE.
  • Zoek naar “DIYables ESP32 WebServer”, en vind dan de Web Server bibliotheek gemaakt door DIYables.
  • Klik op de Install knop om de Web Server bibliotheek te installeren.
ESP32 Web Server bibliotheek
  • Typ ESP32Servo in de zoekbalk en zoek naar de servo bibliotheek van Kevin Harrington, John K. Bennett.
  • Klik op de Install knop om de servo motor bibliotheek voor ESP32 te installeren.
ESP32 servo motor bibliotheek
  • Maak in Arduino IDE een nieuwe sketch aan, geef het een naam, bijvoorbeeld newbiely.com.ino
  • Kopieer de onderstaande code en open deze met Arduino IDE.
/* * Deze ESP32 code is ontwikkeld door newbiely.nl * Deze ESP32 code wordt zonder enige beperking aan het publiek beschikbaar gesteld. * Voor volledige instructies en schema's, bezoek: * https://newbiely.nl/tutorials/esp32/esp32-controls-servo-motor-via-web */ #include <ESP32Servo.h> #include <DIYables_ESP32_WebServer.h> #include "index.h" #define SERVO_PIN 26 // ESP32 pin GPIO26 connected to servo motor Servo servo; // WiFi credentials const char WIFI_SSID[] = "YOUR_WIFI_SSID"; const char WIFI_PASSWORD[] = "YOUR_WIFI_PASSWORD"; // Create web server instance DIYables_ESP32_WebServer server; DIYables_ESP32_WebSocket* webSocket; // Web Page handlers void handleHome(WiFiClient& client, const String& method, const String& request, const QueryParams& params, const String& jsonData) { // HTML_CONTENT from the index.h file server.sendResponse(client, HTML_CONTENT); } // WebSocket event handlers void onWebSocketOpen(net::WebSocket& ws) { Serial.println("New WebSocket connection"); // Send welcome message 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 angle_value = angle.toInt(); Serial.println(angle_value); servo.write(angle_value); } 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); servo.attach(SERVO_PIN); // attaches the servo on ESP32 pin Serial.println("ESP32 Web Server and 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() { // Then handle HTTP requests server.handleClient(); // Handle WebSocket server.handleWebSocket(); }
  • Pas de WiFi-gegevens aan (SSID en wachtwoord) in de code, zodat deze overeenkomen met uw eigen netwerkgegevens.
  • Maak het bestand index.h aan in Arduino IDE door:
    • Of te klikken op de knop net onder het serial monitor-icoon en kies New Tab, of gebruik de toetsencombinatie 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 de onderstaande code en plak deze in index.h.
    /* * Deze ESP32 code is ontwikkeld door newbiely.nl * Deze ESP32 code wordt zonder enige beperking aan het publiek beschikbaar gesteld. * Voor volledige instructies en schema's, bezoek: * https://newbiely.nl/tutorials/esp32/esp32-controls-servo-motor-via-web */ const char *HTML_CONTENT = R"=====( <!DOCTYPE html> <html> <head> <title>ESP32 Controls Servo Motor via Web</title> <meta name="viewport" content="width=device-width, initial-scale=0.7"> <style> body { text-align: center; } canvas { background-color: #ffffff; } </style> <script> var canvas_width = 401, canvas_height = 466; var pivot_x = 200, pivot_y = 200; var bracket_radius = 160, bracket_angle = 0; var bracket_img = new Image(); var click_state = 0; var last_angle = 0; var mouse_xyra = {x:0, y:0, r:0.0, a:0.0}; var ws; bracket_img.src = "https://esp32io.com/images/tutorial/servo-bracket.png"; function init() { var servo = document.getElementById("servo"); servo.width = canvas_width; servo.height = canvas_height; servo.style.backgroundImage = "url('https://esp32io.com/images/tutorial/servo-body.png')"; servo.style.backgroundPosition = "center"; servo.style.backgroundSize = "contain"; servo.addEventListener("touchstart", mouse_down); servo.addEventListener("touchend", mouse_up); servo.addEventListener("touchmove", mouse_move); servo.addEventListener("mousedown", mouse_down); servo.addEventListener("mouseup", mouse_up); servo.addEventListener("mousemove", mouse_move); var ctx = servo.getContext("2d"); ctx.translate(pivot_x, pivot_y); rotate_bracket(0); ws = new WebSocket("ws://" + window.location.host + ":81"); document.getElementById("ws_state").innerHTML = "CONNECTING"; ws.onopen = function(){ document.getElementById("ws_state").innerHTML = "CONNECTED" }; ws.onclose = function(){ document.getElementById("ws_state").innerHTML = "CLOSED"}; ws.onerror = function(){ alert("websocket error " + this.url) }; ws.onmessage = ws_onmessage; } function ws_onmessage(e_msg) { e_msg = e_msg || window.event; // MessageEvent alert("msg : " + e_msg.data); } function rotate_bracket(angle) { var servo = document.getElementById("servo"); var ctx = servo.getContext("2d"); ctx.clearRect(-pivot_x, -pivot_y, canvas_width, canvas_height); ctx.rotate(angle / 180 * Math.PI); ctx.drawImage(bracket_img, -pivot_x, -pivot_y); ctx.rotate(-angle / 180 * Math.PI); } function check_range_xyra(event, mouse_xyra) { var x, y, r, a, rc_x, rc_y, radian; var min_r, max_r, width; if(event.touches) { var touches = event.touches; x = (touches[0].pageX - touches[0].target.offsetLeft) - pivot_x; y = pivot_y - (touches[0].pageY - touches[0].target.offsetTop); min_r = 60; max_r = pivot_x; width = 40; } else { x = event.offsetX - pivot_x; y = pivot_y - event.offsetY; min_r = 60; max_r = bracket_radius; width = 20; } /* cartesian to polar coordinate conversion */ r = Math.sqrt(x * x + y * y); a = Math.atan2(y, x); mouse_xyra.x = x; mouse_xyra.y = y; mouse_xyra.r = r; mouse_xyra.a = a; radian = bracket_angle / 180 * Math.PI; /* rotate coordinate */ rc_x = x * Math.cos(radian) - y * Math.sin(radian); rc_y = x * Math.sin(radian) + y * Math.cos(radian); if((r < min_r) || (r > max_r)) return false; if((rc_y < -width) || (rc_y > width)) return false; return true; } function mouse_down() { if(event.touches && (event.touches.length > 1)) click_state = event.touches.length; if(click_state > 1) return; if(check_range_xyra(event, mouse_xyra)) { click_state = 1; last_angle = mouse_xyra.a / Math.PI * 180.0; } } function mouse_up() { click_state = 0; } function mouse_move() { var angle; if(event.touches && (event.touches.length > 1)) click_state = event.touches.length; if(click_state > 1) return; if(!click_state) return; if(!check_range_xyra(event, mouse_xyra)) { click_state = 0; return; } angle = mouse_xyra.a / Math.PI * 180.0; if((Math.abs(angle) > 90) && (angle * last_angle < 0)) { if(last_angle > 0) last_angle = -180; else last_angle = 180; } bracket_angle += (last_angle - angle); last_angle = angle; if(bracket_angle > 90) bracket_angle = 90; if(bracket_angle < -90) bracket_angle = -90; rotate_bracket(bracket_angle); if(ws.readyState == 1) ws.send(Math.floor(90 - bracket_angle) + "\r\n"); debug = document.getElementById("debug"); debug.innerHTML = Math.floor(90 - bracket_angle); event.preventDefault(); } window.onload = init; </script> </head> <body> <h2> ESP32 - Servo Motor via Web<br> <canvas id="servo"></canvas> <p> WebSocket : <span id="ws_state" style="color:blue">null</span><br> Angle : <span id="debug" style="color:blue">90</span> </p> </h2> <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 Upload knop in Arduino IDE om de code naar de ESP32 te uploaden.
    • Open de Serial Monitor.
    • Bekijk het resultaat in de Serial Monitor.
    COM6
    Send
    Connecting to WiFi... Connected to WiFi ESP32 Web Server's IP address IP address: 192.168.0.2
    Autoscroll Show timestamp
    Clear output
    9600 baud  
    Newline  
    • Noteer het weergegeven IP-adres en voer dit adres in de adresbalk van een webbrowser op uw smartphone of pc in.
    • U ziet de webpagina zoals hieronder:
    ESP32 bestuurt servo motor via webbrowser
    • De JavaScript-code van de webpagina maakt automatisch de WebSocket-verbinding met de ESP32 aan.
    • Nu kunt u de hoek van de servo motor via de webinterface bedienen.

    Om het geheugen van de ESP32 te besparen, worden de afbeeldingen van de servo motor NIET op de ESP32 opgeslagen. Ze worden in plaats daarvan via internet geladen, dus uw telefoon of pc moet verbinding hebben met internet om de afbeeldingen voor de webcontrolpagina te kunnen laden.

    ※ Notiz:

    • Als u de HTML-inhoud in index.h wijzigt zonder iets aan te passen in newbiely.com.ino, dan zal Arduino IDE de HTML-inhoud niet bijwerken bij het compileren en uploaden van de code naar ESP32.
    • Om Arduino IDE de HTML-inhoud in dit geval te laten bijwerken, brengt u een wijziging aan in het newbiely.com.ino bestand, bijvoorbeeld een lege regel toevoegen of een commentaarregel.

    Regel-voor-regel Code Uitleg

    De bovenstaande ESP32 code bevat uitleg regel voor regel. Lees de commentaren in de code alstublieft aandachtig!

※ 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!