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.
Waarom gebruiken we WebSocket? Dit is waarom:
Zonder WebSocket moet u telkens de webpagina vernieuwen om de hoek van de servo aan te passen. Dit is niet ideaal.
Met WebSocket creëren we echter een vaste verbinding tussen de webpagina en de Arduino. Hierdoor kunnen we de hoekwaarde op de achtergrond naar de Arduino sturen zonder de pagina te herladen. Dit zorgt voor een soepele werking en realtime respons van de servo. Indrukwekkend, toch?
Laten we aan de slag gaan!
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.
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:
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.

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.
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
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.
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
#include <Servo.h>
#include <UnoR4WiFi_WebServer.h>
#include "index.h"
#define SERVO_PIN 9
const char WIFI_SSID[] = "YOUR_WIFI_SSID";
const char WIFI_PASSWORD[] = "YOUR_WIFI_PASSWORD";
UnoR4WiFi_WebServer server(80);
UnoR4WiFi_WebSocket *webSocket;
Servo servo;
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 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);
Serial.println("Arduino Uno R4 WiFi - WebSocket Server controls Servo Motor");
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);
}
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>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:
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;
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;
}
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;
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.
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
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.
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
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).
De bovenstaande Arduino code bevat al een regel-voor-regel uitleg in de commentaarregels. Lees deze a.u.b. goed door!