dimanche 26 août 2018

Moteur pas à pas contrôlé par WiFi (ESP8266 ou ESP32)


N.B. Ce tutoriel a été mis à jour le 2 août 2019 (ajout d'informations concernant l'ESP32).

Il y a quelques semaines, nous nous sommes amusés à contrôler un moteur à courant continu par WiFi grâce à un ESP8266 ou un ESP32.

L'expérience d'aujourd'hui est dans le même ordre d'idées, sauf  que nous contrôlerons cette fois-ci un moteur pas à pas.

Une page web nous permettra de choisir le nombre de pas effectués par le moteur, la direction de sa rotation (horaire ou antihoraire) ainsi que le temps écoulé entre deux pas consécutifs (ce qui influencera évidemment la vitesse de rotation du moteur).

Matériel nécessaire

Un moteur pas à pas (j'ai utilisé un moteur bipolaire provenant d'une vieille imprimante), une carte de développement munie d'un ESP8266 ou d'un ESP32, un double pont en H (j'ai utilisé un module L298N),  et un accès à un réseau WiFi.

Préparation de l'IDE Arduino

L'IDE Arduino ne dispose pas par défaut des fichiers nécessaires pour programmer l'ESP8266 ou l'ESP32: si ce n'est pas déjà fait, vous pouvez consulter une marche à suivre détaillée pour l'ESP8266 ou pour l'ESP32.

Le circuit

Sans trop de surprise, le circuit est très similaire à celui que nous avions utilisé pour le contrôle d'un moteur électrique conventionnel, sauf que le moteur pas à pas accapare toutes les sorties du module L298N.

Dans le sketch (disponible un peu plus loin), j'ai supposé que le moteur pas à pas allait être contrôlé par les broches GPIO 4, GPIO5, GPIO 14 et GPIO 16­.

Voici le schéma du circuit pour le module ESP32 que j'utilise (sur cette carte, la broche GPIO 16 est identifiée par "RX2"):


Avec une petite carte Wemos D1 Mini, ça donne ça (la numérotation sur la carte n'est pas le numéro de GPIO: on utilise D2, D1, D5 et D0):


Et voici sur le schéma et les instructions pour un module ESP-12 programmé au moyen d'un convertisseur USB-TTL:

L'ESP8266 nécessite une alimentation de 3,3 V, ce qui est trop faible pour la plupart des moteurs pas à pas, d'où les deux alimentations distinctes.
  • 3 broches de l'ESP8266 sont connectées à 3,3 V:  VCC, RST et CH_PD (aussi appelée "EN" sur certains modèles).
  • 2 broches de l'ESP8266 sont connectées à la masse:  GND et GPIO0.
  • La broche RXD de l'ESP8266 est reliée à la broche TX du convertisseur USB-TTL, et la broche TXD de l'ESP8266 est reliée à la broche RX du convertisseur USB-TTL.
  • Les broches GPIO4, GPIO5, GPIO14 et GPIO16 de l'ESP8266 sont branchées à IN1, IN2, IN3 et IN4 du module 298N, puisqu'elles sont responsables de contrôler le moteur.
  • Toutes les masses sont reliées ensemble (GND de l'ESP8266, du convertisseur USB-TTL et du module L298N).



Le sketch

La fonction "construitPage()" retourne une chaîne de caractères contenant la totalité de la page web, en langage html.  Cette page web contient un champ qui permettra à l'utilisateur de déterminer de combien de pas il veut faire tourner le moteur, une paire de boutons radio permettant de choisir le sens de rotation, un champ permettant de choisir le délai en millisecondes entre deux pas consécutifs, et finalement un bouton "appliquer" qu'on clique pour que les nouveaux paramètres soient pris en compte par le microcontrôleur.

La fonction "gestionPage()" est appelée lors d'un clic sur le bouton "Appliquer".  Elle met à jour quelques variables globales en fonction des choix faits par l'utilisateur de la page web, et indique les paramètres choisis dans le moniteur série (ce qui sera surtout utile pour le débogage).

prochainStep() et gestionMoteur() sont responsable de faire tourner le moteur avec les paramètres spécifiés (j'ai choisi de ne pas utiliser la bibliothèque Stepper).

/**********************************************************************
ESP8266 Pas à pas
Contrôle d'un moteur pas à pas au moyen d'une page Web.
Compatible ESP8266 et ESP32.
https://electroniqueamateur.blogspot.com/2018/08/moteur-pas-pas-controle-par-wifi-esp8266.html
***********************************************************************/
// inclusion des bibliothèques utiles
#if defined ARDUINO_ARCH_ESP8266 // s'il s'agit d'un ESP8266
#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>
#elif defined ARDUINO_ARCH_ESP32 // s'il s'agit d'un ESP32
#include "WiFi.h"
#include <WebServer.h>
#endif
// modifiez ces deux constantes pour qu'elles contiennent les caractéristiques de
// votre réseau Wifi
#define ssid "**********" // le nom (SSID) de votre réseau WiFi
#define password "**********" // votre mot de passe WiFi
// le moteur est contrôlé par les GPIO 4, 5, 14 ete 16 de l'ESP8266
#define pinMoteur1a 4
#define pinMoteur1b 5
#define pinMoteur2a 14
#define pinMoteur2b 16
#if defined ARDUINO_ARCH_ESP8266 // s'il s'agit d'un ESP8266
ESP8266WebServer server(80);
#elif defined ARDUINO_ARCH_ESP32 // s'il s'agit d'un ESP32
WebServer server(80);
#endif
// Les trois variables indiquant le sens, le nombre de pas et le delai entre chaque pas
// ce sont des strings, puisque leur contenu provient des champs de texte de la page web
String sensSTR = "1"; // peut prendre les valeurs 0 (horaire) ou 1 (antihoraire)
String nombrePasSTR = "10"; // nombre de pas
String delaiSTR = "100";
/* La fonction construitPage retourne un string qui contient toute notre page web */
String construitPage() {
String bouton1Str, bouton2Str;
// pour que le bon bouton demeure coché:
if (sensSTR == "1") {
bouton1Str = "checked";
}
if (sensSTR == "2") {
bouton2Str = "checked";
}
String page = "<html lang=fr-FR><head>";
page += "<title>ESP8266 / ESP32 Moteur pas &agrave; pas</title>";
page += "<style> body { background-color: #fffff; font-family: Arial, Helvetica, Sans-Serif; Color: #000088; }</style>";
page += "</head><body><h1>Moteur pas &agrave pas</h1>";
page += "<form action='/' method='POST'>";
page += "<h3>Nombre de pas:</h3>";
page += "<p><INPUT type='text' name='pas' value='" + nombrePasSTR + "'></p>";
page += "<h3>Sens de rotation:</h3>";
page += "<p><INPUT type='radio' name='sens' value='1' " + bouton1Str + ">horaire";
page += "<INPUT type='radio' name='sens' value='2' " + bouton2Str + ">antihoraire</p>";
page += "<h3>D&eacute;lai (en millisecondes):</h3>";
page += "<p><INPUT type='text' name='delai' value='" + delaiSTR + "'></p>";
page += "<INPUT type='submit' value='Appliquer'><br><br>";
page += "</body></html>";
return page;
}
/* La fonction gestionPage modifie les caractéristiques du moteur si le bouton
Appliquer a été cliqué. */
void gestionPage() {
if ( server.hasArg("sens") ) {
sensSTR = server.arg("sens");
nombrePasSTR = server.arg("pas");
delaiSTR = server.arg("delai");
Serial.print("Commande recue. Sens: ");
Serial.print(sensSTR);
Serial.print(" Nombre de pas: ");
Serial.print(nombrePasSTR);
Serial.print(" Delai: ");
Serial.println(delaiSTR);
gestionMoteur();
}
server.send ( 200, "text/html", construitPage() );
}
void prochainStep(int numero) {
if (numero == 0) {
digitalWrite(pinMoteur1a, true);
digitalWrite(pinMoteur1b, false);
digitalWrite(pinMoteur2a, true);
digitalWrite(pinMoteur2b, false);
}
if (numero == 1) {
digitalWrite(pinMoteur1a, false);
digitalWrite(pinMoteur1b, true);
digitalWrite(pinMoteur2a, true);
digitalWrite(pinMoteur2b, false);
}
if (numero == 2) {
digitalWrite(pinMoteur1a, false);
digitalWrite(pinMoteur1b, true);
digitalWrite(pinMoteur2a, false);
digitalWrite(pinMoteur2b, true);
}
if (numero == 3) {
digitalWrite(pinMoteur1a, true);
digitalWrite(pinMoteur1b, false);
digitalWrite(pinMoteur2a, false);
digitalWrite(pinMoteur2b, true);
}
}
/* Contrôle du moteur par les broches GPIO4 et GPIO5 */
void gestionMoteur() {
for (int i = 0; i <= nombrePasSTR.toInt(); i++) {
if (sensSTR == "1") { // sens horaire
prochainStep(i % 4);
}
if (sensSTR == "2") { // sens antihoraire
prochainStep(3 - (i % 4));
}
delay(delaiSTR.toInt());
}
}
void setup() {
// broches qui contrôlent le moteur
pinMode(pinMoteur1a, OUTPUT);
pinMode(pinMoteur1b, OUTPUT);
pinMode(pinMoteur2a, OUTPUT);
pinMode(pinMoteur2b, OUTPUT);
// pour affichage dans le moniteur série
Serial.begin ( 115200 );
// initialisation de la communication WiFi
WiFi.begin ( ssid, password );
while ( WiFi.status() != WL_CONNECTED ) {
delay ( 500 ); Serial.print ( "." );
}
Serial.println ( "" );
Serial.print ( "Maintenant connecte a " );
Serial.println ( ssid );
Serial.print ( "Adresse IP: " );
Serial.println ( WiFi.localIP() );
// On indique le nom de la fonction qui gère l'interraction avec la page web
server.on ( "/", gestionPage );
server.begin();
Serial.println ( "Serveur HTTP en fonction" );
}
void loop() {
server.handleClient();
}

Le résultat

Au démarrage du programme, l'adresse de la page web construite par l'ESP8266 ou l'ESP32  est affichée dans le moniteur série.  Il suffit de coller cette adresse dans un navigateur web pour accéder à la page.


La page web vous permet de choisir le nombre de pas de la prochaine rotation du moteur, le sens de cette rotation, et le délai en millisecondes entre chaque pas.  Le moteur devrait se mettre à tourner lorsque vous cliquez sur le bouton "Appliquer".


Yves Pelletier   (TwitterFacebook)

9 commentaires:

  1. Bonjour,

    Merci pour ce tuto,

    Je rencontre cependant un problème... A chaque fois que j'essaye de mettre en fonction le moteur tout ce coupe. J'ai essayé avec un ESP 8266 et un ESP 32 et avec deux moteur différents. Le problème semble venir du branchement entre la carte d'alimentation et le moteur mais malgré tous les tests que j'ai fais j'ai toujours le même problème :s avez vous une piste ?

    RépondreSupprimer
    Réponses
    1. Je m'attendrais à ce genre de comportement si le moteur et l'ESP partageaient la même alimentation: le moteur entraînerait alors des perturbations dans l'alimentation de l'ESP.

      Supprimer
    2. Merci pour votre réponse mais ce n'est pas le cas. Au moment d'alimenté le moteur reçoit un courant et le module L298N se coupe

      Supprimer
  2. j'essaie d'utiliser le sketch ci dessus mais j'ai une erreur de compilation m'indiquant LWIP OPEN SRC must be defined qu'estce cela siginifie ?

    RépondreSupprimer
  3. bonjour et merci pour cet excellent tutoriel.A la fin du televersement j ai le message d erreur suivant: class ESP8266WiFiClass' has no member named 'begin'.Sur le net j'ai pas trouve d explication satisfaisante.si possible pourriez m eclairer,merci par avance. mail:jean.soscia@orange.fr

    RépondreSupprimer
    Réponses
    1. Il faut probablement mettre à jour les fichiers pour l'ESP8266 (dans le gestionnaire de cartes de l'IDE Arduino).

      Supprimer
    2. Bonjour.Merci ce probleme est resolu.
      J ai realise le montage wifi moteur courant continu qui fonctionne parfaitement.Je viens de terminer le montage wifi moteur pas a pas; compilation telechargement OK. ssid et mdp a jour.Cependant je n arrive pas a avoir l adresse IP comme le premier montage. J ai beaucoup cherche! pas de solution. Pourriez vous avoir l amabilite de me repondre eventuellement. Merci par avance.

      Supprimer
    3. Pour obtenir l'adresse IP il suffit d'ouvrir le moniteur série (réglé sur 115000 je crois) puis d'appuyé sur le bouton res de votre carte.

      Supprimer
  4. Bonjour, merci pour ce tuto, j'ai réalisé et tout c'est bien passé.
    Je ne suis pas très fort en codage et je cherche à ajouté du code afin d'avoir le le nombre de pas déjà effectué avec possibilité de reset.
    Je cherche également à convertir le nombre de pas en cm.
    Toujours via une page web.
    Si vous avez vu passé des tutos qui explique cela, merci d'avance.
    Encore bravo pour ce tuto.

    RépondreSupprimer