Arduino - Servo Motor Besturen via Web

Deze tutorial laat u zien hoe u een Arduino gebruikt om een servo motor te besturen vanuit een webbrowser op uw smartphone of pc. We maken gebruik van WebSocket-technologie om een vloeiende en dynamische besturing van de servo motor te realiseren via een grafische webgebruikersinterface.

Arduino controls servo motor via web

Waarom gebruiken we WebSocket? Dit is waarom:

Laten we aan de slag gaan!

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 Arduino, Arduino code,... Leer meer over deze onderwerpen via de volgende links:

Hoe Werkt Het

De Arduino code richt zowel een webserver als een WebSocket-server in. Dit is het stappenplan:

  • Wanneer u het IP-adres van de Arduino in een webbrowser invoert, vraagt de browser de webpagina (gebruikersinterface) op die op de Arduino wordt gehost.
  • De webserver van de Arduino reageert door de inhoud van de webpagina (HTML, CSS, JavaScript) terug te sturen.
  • Uw webbrowser toont vervolgens de webpagina.
  • De JavaScript-code in de webpagina maakt een WebSocket-verbinding met de WebSocket-server op de Arduino.
  • Zodra de WebSocket-verbinding actief is, wordt bij het aanpassen van de schuifregelaar op de pagina de hoekwaarde via deze verbinding stilletjes naar de Arduino gestuurd, op de achtergrond.
  • De WebSocket-server op de Arduino ontvangt deze hoekwaarde en stelt de servo motor hierop in.

Kortom, de WebSocket-verbinding zorgt voor een vloeiende en realtime besturing van de hoek van de servo motor.

Bedradingsschema tussen Servo Motor en Arduino

Arduino Servo Motor Wiring Diagram

This image is created using Fritzing. Click to enlarge image

Voor de eenvoud is bovenstaand bedradingsschema bedoeld voor test- en leerdoeleinden en voor servo’s met geringe kracht. In de praktijk raden wij sterk aan om een externe voeding voor de servo motor te gebruiken. Het onderstaande bedrading schema toont hoe u de servo motor op een externe voedingsbron aansluit.

Arduino servo motor power supply wiring diagram

Arduino Code

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

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

Snelle Stappen

  • Gebruikt u voor het eerst de Arduino Uno R4? Bekijk dan hoe u de omgeving instelt voor Arduino Uno R4 in Arduino IDE.
  • Voer de bedrading uit zoals op de bovenstaande afbeelding.
  • Sluit de Arduino aan op uw pc via een micro USB-kabel.
  • Open de Arduino IDE op uw pc.
  • Selecteer het juiste Arduino board (bijvoorbeeld Arduino Uno R4 WiFi) en de juiste COM-poort.
  • Open de Library Manager door te klikken op het Library Manager icoon in de linker navigatiebalk van Arduino IDE.
  • Zoek naar Web Server for Arduino Uno R4 WiFi en vind de door DIYables gemaakte Web Server library.
  • Klik op de Install knop om de Web Server library te installeren.
Arduino UNO R4 Web Server library
  • Maak in Arduino IDE een nieuw sketch aan, geef het 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-servo-motor-via-web */ #include <Servo.h> #include <UnoR4WiFi_WebServer.h> #include "index.h" #define SERVO_PIN 9 // Arduino pin 9 connected to servo motor // 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; Servo servo; // 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 angle = String(message); int angle_value = angle.toInt(); servo.write(angle_value); Serial.print(F("Rotate Servo Motor to ")); Serial.println(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 Arduino pin Serial.println("Arduino Uno R4 WiFi - WebSocket Server controls Servo Motor"); // 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); }
  • 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:
    • 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 adds file
    • Geef het bestand de naam index.h en klik op OK.
    Arduino IDE 2 adds file index.h
    • Kopieer de 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-servo-motor-via-web */ const char *HTML_CONTENT = R"=====( <!DOCTYPE html> <html> <head> <title>Arduino 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> Arduino - 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> )=====";
    • U hebt nu code in twee bestanden: ArduinoGetStarted.com.ino en index.h.
    • Klik op de Upload knop in Arduino IDE om de code naar de Arduino te uploaden.
    • Open de Serial Monitor
    • Bekijk het resultaat in de Serial Monitor.
    COM6
    Send
    Arduino Uno R4 WiFi - WebSocket Server controls Servo Motor 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 getoonde IP-adres en voer dit adres in de adresbalk van een webbrowser in op uw smartphone of pc.
    • U ziet nu de volgende webpagina:
    Arduino controls servo motor via web browser
    • De JavaScript-code van de pagina maakt automatisch de WebSocket-verbinding met de Arduino.
    • Nu kunt u de hoek van de servo motor aanpassen door de schuifregelaar op de webinterface te draaien.
    • Kijk ook in de Serial Monitor, u ziet daar de hoekwaarden die vanaf het web binnenkomen.
    COM6
    Send
    WebSocket server enabled successfully WebSocket client connected from: 192.168.0.7 New WebSocket connection Rotate Servo Motor to 90 Rotate Servo Motor to 89 Rotate Servo Motor to 88 Rotate Servo Motor to 87
    Autoscroll Show timestamp
    Clear output
    9600 baud  
    Newline  

    Om geheugen op de Arduino te besparen, worden de afbeeldingen van de servo motor NIET op de Arduino opgeslagen. In plaats daarvan zijn ze online opgeslagen, waardoor uw telefoon of pc een internetverbinding nodig heeft om de afbeeldingen op de webbesturingspagina te laden.

    ※ Notiz:

    • Wanneer u alleen de HTML-inhoud in index.h wijzigt en niks aan het ArduinoGetStarted.com.ino bestand, zal Arduino IDE bij compileren en uploaden NIET de HTML-inhoud bijwerken.
    • Om Arduino IDE het HTML-bestand toch te laten updaten, voert u een kleine wijziging door in het ArduinoGetStarted.com.ino bestand (bijvoorbeeld een lege regel toevoegen of een commentaarregel toevoegen).

    Regelsgewijze Code Uitleg

    De bovenstaande Arduino code bevat al een regel-voor-regel uitleg in de commentaarregels. Lees deze a.u.b. goed door!

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