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

Ce tutoriel vous explique comment utiliser l'Arduino Nano ESP32 pour contrôler un moteur servo via le web depuis un navigateur sur votre smartphone ou votre PC. Nous utiliserons quelque chose appelé WebSocket pour contrôler le moteur servo de manière fluide et dynamique via une interface utilisateur web graphique.

Arduino Nano ESP32 contrôle le moteur servo via le Web

Maintenant, pourquoi utiliser WebSocket ? Voici l'idée :

Commençons !

Préparation du matériel

1×Arduino Nano ESP32
1×USB Cable Type-C
1×Servo Motor
1×Breadboard
1×Jumper Wires
1×(Optional) DC Power Jack
1×(Recommended) Screw Terminal Adapter for Arduino Nano

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 servomoteur et du WebSocket

Nous avons des tutoriels spécifiques sur le moteur servo et WebSocket. Chaque tutoriel contient des informations détaillées et des instructions pas à pas sur le brochage du matériel, le principe de fonctionnement, la connexion de câblage à l'ESP32, le code Arduino Nano ESP32... Apprenez-en plus à leur sujet aux liens suivants :

Comment ça fonctionne

Le code Arduino Nano ESP32 crée à la fois un serveur web et un serveur WebSocket. Voici comment cela fonctionne :

  • Lorsque vous saisissez l'adresse IP de l'ESP32 dans un navigateur web, il demande la page web (Interface Utilisateur) à l'Arduino Nano ESP32.
  • Le serveur web de l'ESP32 répond en envoyant le contenu de la page web (HTML, CSS, JavaScript).
  • Votre navigateur web affiche ensuite la page web.
  • Le code JavaScript à l'intérieur de la page web établit une connexion WebSocket avec le serveur WebSocket sur l'Arduino Nano ESP32.
  • Une fois cette connexion WebSocket établie, si vous tournez la poignée sur la page web, le code JavaScript envoie discrètement la valeur de l'angle à l'Arduino Nano ESP32 via cette connexion WebSocket en arrière-plan.
  • Le serveur WebSocket sur l'ESP32, après avoir reçu la valeur de l'angle, contrôle le servo moteur en conséquence.

En quelques mots, la connexion WebSocket permet un contrôle fluide et en temps réel de l'angle du moteur servo.

Schéma de câblage entre le servo-moteur et l'Arduino Nano ESP32

  • Lors de l'alimentation de la carte Arduino Nano ESP32 via le port USB.
Schéma de câblage du moteur servo Arduino Nano ESP32

This image is created using Fritzing. Click to enlarge image

  • Lors de l'alimentation de la carte Arduino Nano ESP32 via la broche Vin.
Schéma de câblage de l'alimentation électrique externe du moteur servo Arduino Nano ESP32

This image is created using Fritzing. Click to enlarge image

※ NOTE THAT:

Lors de l'alimentation de la carte Arduino Nano ESP32 via le port USB, elle ne doit PAS alimenter le moteur servo via la broche Vin VBUS. Si vous alimentez le moteur servo via cette broche, votre carte pourrait brûler.

Code Arduino Nano ESP32

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

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

Étapes rapides

Pour commencer avec l'Arduino Nano ESP32, suivez ces étapes :

  • Si vous débutez avec l'Arduino Nano ESP32, consultez le tutoriel sur comment configurer l'environnement pour Arduino Nano ESP32 dans l'Arduino IDE.
  • Câblez les composants selon le schéma fourni.
  • Connectez la carte Arduino Nano ESP32 à votre ordinateur à l'aide d'un câble USB.
  • Lancez l'Arduino IDE sur votre ordinateur.
  • Sélectionnez la carte Arduino Nano ESP32 et son port COM correspondant.
  • 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 "ESPAsyncWebServer", puis trouvez l'ESPAsyncWebServer créé par lacamera.
  • Cliquez sur le bouton Install pour installer la bibliothèque ESPAsyncWebServer.
Bibliothèque ESPAsyncWebServer pour Arduino Nano ESP32
  • Vous serez invité à installer la dépendance. Cliquez sur le bouton Install All.
Bibliothèque de dépendances ESPAsyncWebServer pour Arduino Nano ESP32
  • Recherchez « WebSockets », puis trouvez les WebSockets créés par Markus Sattler.
  • Cliquez sur le bouton Install pour installer la bibliothèque WebSockets.
Bibliothèque WebSockets pour Arduino Nano ESP32
  • Tapez ServoESP32 dans la boîte de recherche, puis cherchez la bibliothèque servo de Jaroslav Paral. Veuillez noter que les versions 1.1.1 et 1.1.0 comportent des bugs. Merci de choisir une version différente.
  • Cliquez sur le bouton Install pour installer la bibliothèque de moteur servo pour Arduino Nano ESP32.
Bibliothèque de moteur servo Arduino Nano ESP32
  • Sur l'IDE Arduino, créez un nouveau sketch, nommez-le, par exemple, newbiely.fr.ino
  • Copiez le code ci-dessous et ouvrez-le avec l'IDE Arduino.
/* * Ce code Arduino Nano ESP32 a été développé par newbiely.fr * Ce code Arduino Nano ESP32 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-nano-esp32/arduino-nano-esp32-controls-servo-motor-via-web */ #include <Servo.h> #include <WiFi.h> #include <ESPAsyncWebServer.h> #include <WebSocketsServer.h> #include "index.h" #define SERVO_PIN D2 // The Arduino Nano ESP32 pin connected to servo motor Servo servo; const char* ssid = "YOUR_WIFI_SSID"; // CHANGE IT const char* password = "YOUR_WIFI_PASSWORD"; // CHANGE IT AsyncWebServer server(80); WebSocketsServer webSocket = WebSocketsServer(81); // WebSocket server on port 81 void webSocketEvent(uint8_t num, WStype_t type, uint8_t* payload, size_t length) { switch (type) { case WStype_DISCONNECTED: Serial.printf("[%u] Disconnected!\n", num); break; case WStype_CONNECTED: { IPAddress ip = webSocket.remoteIP(num); Serial.printf("[%u] Connected from %d.%d.%d.%d\n", num, ip[0], ip[1], ip[2], ip[3]); } break; case WStype_TEXT: //Serial.printf("[%u] Received text: %s\n", num, payload); String angle = String((char*)payload); int angle_value = angle.toInt(); Serial.println(angle_value); servo.write(angle_value); break; } } void setup() { Serial.begin(9600); servo.attach(SERVO_PIN); // attaches the servo on ESP32 pin // Connect to Wi-Fi WiFi.begin(ssid, password); while (WiFi.status() != WL_CONNECTED) { delay(1000); Serial.println("Connecting to WiFi..."); } Serial.println("Connected to WiFi"); // Initialize WebSocket server webSocket.begin(); webSocket.onEvent(webSocketEvent); // Serve a basic HTML page with JavaScript to create the WebSocket connection server.on("/", HTTP_GET, [](AsyncWebServerRequest* request) { Serial.println("Web Server: received a web page request"); String html = HTML_CONTENT; // Use the HTML content from the index.h file request->send(200, "text/html", html); }); server.begin(); Serial.print("Arduino Nano ESP32 Web Server's IP address: "); Serial.println(WiFi.localIP()); } void loop() { webSocket.loop(); }
  • Créez le fichier index.h sur Arduino IDE 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.
    L'IDE Arduino 2 ajoute le fichier index.h
    • Copiez le code ci-dessous et collez-le dans index.h.
    /* * Ce code Arduino Nano ESP32 a été développé par newbiely.fr * Ce code Arduino Nano ESP32 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-nano-esp32/arduino-nano-esp32-controls-servo-motor-via-web */ const char *HTML_CONTENT = R"=====( <!DOCTYPE html> <html> <head> <title>Arduino Nano 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> Arduino Nano 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> )=====";
    • Maintenant, vous avez le code dans deux fichiers : newbiely.fr.ino et index.h
    • Cliquez sur le bouton Upload de l’IDE Arduino pour téléverser le code sur Arduino Nano ESP32
    • Ouvrez le moniteur série
    • Vérifiez le résultat sur le moniteur série.
    COM6
    Send
    Connecting to WiFi... Connected to WiFi Arduino Nano ESP32 Web Server's IP address IP address: 192.168.0.3
    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 Nano ESP32 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 Nano ESP32.
    • Vous pouvez maintenant contrôler l'angle du moteur servo via l'interface web.

    Pour économiser la mémoire de l'ESP32, les images du moteur servo ne sont PAS stockées sur l'Arduino Nano ESP32. Au lieu de cela, elles sont stockées sur Internet, donc, 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 index.h et que vous ne touchez à rien dans le fichier newbiely.fr.ino, lorsque vous compilez et téléchargez le code sur l'ESP32, l'Arduino IDE ne mettra pas à jour le contenu HTML.
    • Pour que l'Arduino IDE mette à jour le contenu HTML dans ce cas, apportez une modification dans le fichier newbiely.fr.ino (par exemple, ajouter une ligne vide, ajouter un commentaire....)

    Explication du code ligne par ligne

    Le code Arduino Nano ESP32 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!