Arduino - Contrôle d'un moteur servo via le Web

Ce tutoriel vous montrera comment utiliser un Arduino pour contrôler un moteur servo depuis un navigateur web sur votre smartphone ou PC. Nous utiliserons la technologie WebSocket pour permettre un contrôle fluide et dynamique du moteur servo via une interface utilisateur graphique web.

Arduino contrôle le servo-moteur via le web.

Maintenant, pourquoi devrions-nous utiliser WebSocket ? Voici pourquoi :

Commençons !

Préparation du matériel

1×Arduino UNO R4 WiFi
1×USB Cable Type-C
1×Servo Motor
1×Breadboard
1×Jumper Wires
1×(Optional) DC Power Jack
1×(Recommended) Screw Terminal Block Shield for Arduino Uno
1×(Optional) Transparent Acrylic Enclosure For Arduino Uno

Or you can buy the following sensor kits:

1×DIYables Sensor Kit (30 sensors/displays)
1×DIYables Sensor Kit (18 sensors/displays)
Divulgation : Certains des liens fournis dans cette section sont des liens affiliés Amazon. Nous pouvons recevoir une commission pour tout achat effectué via ces liens, sans coût supplémentaire pour vous. Nous vous remercions de votre soutien.

À propos du servo-moteur et de WebSocket

Nous avons des tutoriels spécifiques sur le servo-moteur et le WebSocket. Chaque tutoriel contient des informations détaillées et des instructions étape par étape sur le brochage du matériel, le principe de fonctionnement, la connexion de câblage à Arduino, le code Arduino... Pour en savoir plus sur ces sujets, consultez les liens suivants :

Comment ça marche

Le code Arduino configure à la fois un serveur web et un serveur WebSocket. Voici le processus étape par étape :

  • Lorsque vous entrez l'adresse IP de l'Arduino dans un navigateur web, cela envoie une demande pour la page web (Interface Utilisateur) hébergée sur l'Arduino.
  • Le serveur web de l'Arduino répond en renvoyant le contenu de la page web (HTML, CSS, JavaScript).
  • Votre navigateur web affiche alors la page web.
  • Le code JavaScript intégré dans la page web initie une connexion WebSocket avec le serveur WebSocket sur l'Arduino.
  • Une fois la connexion WebSocket active, si vous ajustez la manette sur la page web, le code JavaScript transmet discrètement la valeur de l'angle à l'Arduino via cette connexion WebSocket en arrière-plan.
  • Le serveur WebSocket sur l'Arduino, après avoir reçu cette valeur d'angle, ajuste le moteur servo en conséquence.

En essence, la connexion WebSocket facilite le contrôle fluide et en temps réel de l'angle du moteur servo.

Schéma de câblage entre le servo-moteur et Arduino

Schéma de câblage du moteur Servo Arduino

This image is created using Fritzing. Click to enlarge image

Pour des raisons de simplicité, le schéma de câblage ci-dessus est utilisé pour des fins de test ou d'apprentissage, et pour un servo-moteur à faible couple. En pratique, nous recommandons fortement d'utiliser une alimentation externe pour le servo-moteur. Le schéma de câblage ci-dessous montre comment connecter un servo-moteur à une source d'alimentation externe.

Schéma de câblage de l'alimentation du moteur servo Arduino

Code Arduino

Le contenu de la page web (HTML, CSS, JavaScript) est stocké séparément dans un fichier index.h. Ainsi, nous aurons deux fichiers de code sur l'IDE Arduino :

  • Un fichier .ino qui est un code Arduino, lequel crée un serveur web et un serveur WebSocket, et contrôle un moteur servo.
  • Un fichier .h, qui contient le contenu de la page web.

Étapes rapides

  • Si c'est la première fois que vous utilisez Arduino Uno R4, consultez comment configurer l'environnement pour Arduino Uno R4 sur Arduino IDE.
  • Réalisez le câblage comme sur l'image ci-dessus.
  • Connectez la carte Arduino à votre PC via un câble micro USB.
  • Ouvrez Arduino IDE sur votre PC.
  • Sélectionnez la bonne carte Arduino (par exemple, Arduino Uno R4 WiFi) et le port COM.
  • Ouvrez le gestionnaire de bibliothèques en cliquant sur l'icône Gestionnaire de bibliothèques dans la barre de navigation gauche de l'Arduino IDE.
  • Recherchez "mWebSockets", puis trouvez mWebSockets créé par Dawid Kurek.
  • Cliquez sur le bouton Install pour installer la bibliothèque mWebSockets.
Bibliothèque mWebSockets Arduino
  • Sur Arduino IDE, créez un nouveau sketch, nommez-le, par exemple, ArduinoGetStarted.com.ino
  • Copiez le code ci-dessous et ouvrez-le avec Arduino IDE
/* * Ce code Arduino a été développé par newbiely.fr * Ce code Arduino est mis à disposition du public sans aucune restriction. * Pour des instructions complètes et des schémas de câblage, veuillez visiter: * https://newbiely.fr/tutorials/arduino/arduino-controls-servo-motor-via-web */ #include <Servo.h> #include <WiFiS3.h> #include <WebSocketServer.h> #include "index.h" using namespace net; #define SERVO_PIN 9 // Arduino pin 9 connected to servo motor Servo servo; const char *ssid = "YOUR_WIFI_SSID"; // CHANGE IT const char *password = "YOUR_WIFI_PASSWORD"; // CHANGE IT WebSocketServer webSocket(81); WiFiServer server(80); int status = WL_IDLE_STATUS; void setup() { //Initialize serial and wait for port to open: Serial.begin(9600); servo.attach(SERVO_PIN); // attaches the servo on Arduino pin String fv = WiFi.firmwareVersion(); if (fv < WIFI_FIRMWARE_LATEST_VERSION) Serial.println("Please upgrade the firmware"); // attempt to connect to WiFi network: while (status != WL_CONNECTED) { Serial.print("Attempting to connect to SSID: "); Serial.println(ssid); // Connect to WPA/WPA2 network. Change this line if using open or WEP network: status = WiFi.begin(ssid, password); // wait 4 seconds for connection: delay(4000); } // print your board's IP address: Serial.print("IP Address: "); Serial.println(WiFi.localIP()); server.begin(); webSocket.onConnection([](WebSocket &ws) { const auto protocol = ws.getProtocol(); if (protocol) { Serial.print(F("Client protocol: ")); Serial.println(protocol); } ws.onMessage([](WebSocket &ws, const WebSocket::DataType dataType, const char *message, uint16_t length) { switch (dataType) { case WebSocket::DataType::TEXT: { String angle = String((char *)message); int angle_value = angle.toInt(); servo.write(angle_value); Serial.print(F("Rotate Servo Motor to ")); Serial.println(angle_value); } break; case WebSocket::DataType::BINARY: Serial.println(F("Received binary data")); break; } }); ws.onClose([](WebSocket &, const WebSocket::CloseCode, const char *, uint16_t) { Serial.println(F("Disconnected")); }); Serial.print(F("New WebSocket Connnection from client: ")); Serial.println(ws.getRemoteIP()); }); webSocket.begin(); } void loop() { webSocket.listen(); // listen for incoming clients WiFiClient client = server.available(); if (client) { // read the HTTP request header line by line while (client.connected()) { if (client.available()) { String HTTP_header = client.readStringUntil('\n'); // read the header line of HTTP request if (HTTP_header.equals("\r")) // the end of HTTP request break; Serial.print("<< "); Serial.println(HTTP_header); // print HTTP request to Serial Monitor } } // send the HTTP response header client.println("HTTP/1.1 200 OK"); client.println("Content-Type: text/html"); client.println("Connection: close"); // the connection will be closed after completion of the response client.println(); // the separator between HTTP header and body String html = String(HTML_CONTENT); client.println(html); client.flush(); // give the web browser time to receive the data delay(50); // close the connection: client.stop(); } }
  • Modifiez les informations WiFi (SSID et mot de passe) dans le code pour qu'elles correspondent à vos propres identifiants de réseau.
  • Créez le fichier index.h sur l'IDE Arduino en :
    • Cliquant soit sur le bouton juste en dessous de l'icône du moniteur série et choisissez Nouvel Onglet, soit en utilisant les touches Ctrl+Shift+N.
    Arduino IDE 2 ajoute un fichier
    • Nommez le fichier index.h et cliquez sur le bouton OK.
    Arduino IDE 2 ajoute le fichier index.h.
    • Copiez le code ci-dessous et collez-le dans le fichier index.h.
    /* * Ce code Arduino a été développé par newbiely.fr * Ce code Arduino est mis à disposition du public sans aucune restriction. * Pour des instructions complètes et des schémas de câblage, veuillez visiter: * https://newbiely.fr/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> )=====";
    • Vous avez maintenant le code dans deux fichiers : ArduinoGetStarted.com.ino et index.h
    • Cliquez sur le bouton Upload dans l'IDE Arduino pour téléverser le code sur Arduino

    Vous verrez une erreur comme ci-dessous :

    In file included from c:\Users\YOU_ACCOUNT\Documents\Arduino\libraries\mWebSockets\src/utility.h:3:0, from c:\Users\YOU_ACCOUNT\Documents\Arduino\libraries\mWebSockets\src/WebSocket.h:5, from c:\Users\YOU_ACCOUNT\Documents\Arduino\libraries\mWebSockets\src/WebSocketServer.h:5, from C:\Users\YOU_ACCOUNT\Documents\Arduino\ArduinoGetStarted.com\ArduinoGetStarted.com.ino:2: C:\Users\YOU_ACCOUNT\Documents\Arduino\libraries\mWebSockets\src/platform.h:54:12: fatal error: Ethernet.h: No such file or directory # include <Ethernet.h> ^~~~~~~~~~~~ compilation terminated. exit status 1

    Pour corriger cette erreur :

    • Accédez au répertoire C:\Users\VOTRE_COMPTE\Documents\Arduino\libraries\mWebSockets\src\.
    • Trouvez le fichier config.h et ouvrez-le avec un éditeur de texte.
    • Regardez à la ligne 26, vous la verrez comme ci-dessous :
    #define NETWORK_CONTROLLER ETHERNET_CONTROLLER_W5X00
    • Modifiez cette ligne par celle ci-dessous et enregistrez-la :
    #define NETWORK_CONTROLLER NETWORK_CONTROLLER_WIFI
    • Cliquez sur le bouton Upload dans l'IDE Arduino pour téléverser le code vers Arduino.
    • Ouvrez le moniteur série
    • Vérifiez le résultat sur le moniteur série.
    COM6
    Send
    Connecting to WiFi... Connected to WiFi Arduino Web Server's IP address IP address: 192.168.0.2
    Autoscroll Show timestamp
    Clear output
    9600 baud  
    Newline  
    • Prenez note de l'adresse IP affichée, et saisissez cette adresse dans la barre d'adresse d'un navigateur web sur votre smartphone ou PC.
    • Vous verrez la page web comme ci-dessous :
    Arduino contrôle le servo-moteur via le navigateur web
    • Le code JavaScript de la page web crée automatiquement la connexion WebSocket avec l'Arduino.
    • Vous pouvez maintenant contrôler l'angle du moteur servo en tournant la poignée du moteur sur l'interface web.

    Pour économiser la mémoire de l'Arduino, les images du moteur servo ne sont PAS stockées sur l'Arduino. Au lieu de cela, elles sont stockées sur Internet ; ainsi, votre téléphone ou PC doit être connecté à Internet pour charger les images pour la page de contrôle web.

    ※ NOTE THAT:

    Si vous modifiez le contenu HTML dans le fichier index.h et que vous ne touchez à rien dans le fichier ArduinoGetStarted.com.ino, lorsque vous compilez et téléchargez le code sur Arduino, l'IDE Arduino ne mettra pas à jour le contenu HTML. Pour faire en sorte que l'IDE Arduino mette à jour le contenu HTML dans ce cas, apportez une modification dans le fichier ArduinoGetStarted.com.ino (par exemple, ajouter une ligne vide, ajouter un commentaire...).

    Explication du code ligne par ligne

    Le code Arduino ci-dessus contient des explications ligne par ligne. Veuillez lire les commentaires dans le code !

※ OUR MESSAGES

  • Please feel free to share the link of this tutorial. However, Please do not use our content on any other websites. We invested a lot of effort and time to create the content, please respect our work!