Rail motorisé pas à pas

De FunLab Documentation
Aller à : navigation, rechercher

Auteur : Nte


PILOTAGE ARDUINO D'UN MOTEUR PAS À PAS
Introduction

Ce qui suit constitue le compte-rendu, un retour d'expérience d'un projet bien particulier réalisé à l'été 2011.

Certains éléments ci-dessous pourraient cependant éclairer un projet à base de pilotage d'un moteur pas à pas à l'aide d'une carte Arduino.

Situation de départ
  • Projet de base : réaliser un circuit de contrôle d'un moteur pas à pas piloté par une carte Arduino
  • Usage final : à l'aide d'une courroie et d'un réducteur mécanique, ce moteur pas à pas doit contrôler précisément le mouvement d'un plateau (en terme de vitesse, distance de parcours, accélération, décélération).

Sur ce plateau est fixée un camescope de 500 g; il s'agit donc de fabriquer un mini-rail de travelling vidéo contrôlé par ordinateur.

  • Moteur pas à pas utilisé : récupéré d'un vieux scanner à plat. L'étiquette indique comme marque "Mitsumi" et comme modèle "M35SP-7T B".
  • Carte Arduino utilisée : version officielle "Uno R3" basée sur le circuit intégré ATmega328, achetée chez Selectronic
Difficultés rencontrées
  • Détermination précise du type de moteur pas à pas (bipolaire ou unipolaire) difficile
  • Écriture et adaptation des programmes à faire exécuter par la carte Arduino
Réalisation
  • Achat du circuit intégré en pont H "SN754410" chez Lextronic équivalent à l'ancien circuit référencé L293D
  • Test réussi du montage suivant avec une plaque de connexion sans soudure (fournie dans les "kits" de démarrage Arduino)


Ntepapbipolaire.png

  • Fabrication définitive par soudage sur une petite plaque du circuit de contrôle ci-dessus a connecter à la carte Arduino
  • Mise en œuvre des six programmes CtrlMotDemTest.pde, CtrlMotAllerRetour360.pde, CtrlMotCompteChqPas.pde, CtrlMotVitCteNbrepas.pde, CtrlMotAccelTest.pde et CtrlMotVitVbleNbrepas.pde

Trois remarques préalables indispensables avant la lecture ou la réutilisation de ces programmes :

  • Remarque 1 : ces programmes ne peuvent être opérationnels sans les bibliothèques suivantes : Stepper.h et Accelstepper.h
  • Remarque 2 : ces programmes ont été adaptés au fait que le pignon du moteur utilisé est couplé à un réducteur mécanique dont le rapport de transmission est
 FréquencePoulie = 21/240.FréquenceMoteur     


  • Remarque 3 : après des recherches et des tests, il s'avère que le moteur utilisé ne pouvait tourner efficacement sur une longue durée qu'à deux valeurs de vitesses de rotation possibles :

400 tours/min (320 pas/s car l'angle de pas est de 7,5 °) et 625 tours/min (500 pas/s)
Nteardui3.jpg

CtrlMotDemTest.pde
/*   Programme permettant de faire tourner en boucle un MOTEUR PAP BIPOLAIRE POUR UNE VITESSE DE ROTATION DONNEE.  Le MOTEUR PAP doit être connecté aux broches 8 à 11 de la carte Arduino. */

#include <Stepper.h>                                // Permettra d'utilser des fonctions de la librairie externe Stepper.h,
                                                   // librairie spécifique pour contrôler les MOTEURS PAP.
const int nbrepas360 = 48;                        // Fixe le nombre de pas pour faire un tour complet, c'est-à-dire 360°.
Stepper monmoteur (nbrepas360, 8, 9, 10, 11);    // Initialise la librairie Stepper.h

void setup()
{
monmoteur.setSpeed(400);                  // Fixe une vitesse de n tours par min, n est l'argument de la fonction setSpeed.
}

void loop()
{
//delay (5000);
monmoteur.step(1);                      // Avance de n pas, n est l'argument de la fonction step.
}
CCtrlMotAllerRetour360.pde
/*   Programme permettant à un MOTEUR PAP BIPOLAIRE d'effectuer un tour complet dans un sens puis dans l'autre.  Le MOTEUR PAP doit être connecté aux broches 8 à 11 de la carte Arduino. */

#include <Stepper.h>                                // Permettra d'utilser des fonctions de la librairie externe Stepper.h,
                                                   // librairie spécifique pour contrôler les MOTEURS PAP.
const int nbrepas360 = 48;                        // Fixe le nombre de pas pour faire un tour complet, c'est-à-dire 360°.
Stepper monmoteur (nbrepas360, 8, 9, 10, 11);    // Initialise la librairie Stepper.h

void setup()
{
    monmoteur.setSpeed(400);                  // Fixe une vitesse de n tours par min, n est l'argument de la fonction setSpeed.
}

void loop()
{
   monmoteur.step(nbrepas360);              // Effectue un tour complet dans un sens.
   delay(500);                             // Pause d'une demi seconde.

   monmoteur.step(-nbrepas360);           // Effectue un tour complet dans l'autre sens.
   delay(500);                           // Pause d'une demi seconde.
}
CtrlMotCompteChqPas.pde
/*   Programme permettant de faire tourner l'axe d'un MOTEUR PAP BIPOLAIRE très lentement  (un pas à la fois), de compter et d'afficher via le moniteur série  d'un ordinateur chaque pas effectué.  Le MOTEUR PAP doit être connecté aux broches 8 à 11 de la carte Arduino.  Programme pouvant servir à tester que les 4 fils du moteur sont  bien connectés. Si c'est le cas, le moteur tournera dans le même sens. */

#include <Stepper.h>                                // Permettra d'utilser des fonctions de la librairie externe Stepper.h,
                                                   // librairie spécifique pour contrôler les MOTEURS PAP.
const int nbrepas360 = 48;                        // Fixe le nombre de pas pour faire un tour complet, c'est-à-dire 360°.
Stepper monmoteur (nbrepas360, 8, 9, 10, 11);    // Initialise la librairie Stepper.h
int cptepas = 0;                                // Stockera le nombre de pas compté.

void setup()
{
  Serial.begin(9600);                    // Ouvre le port de communication en série de la carte et initialise sa vitesse.
                                        // Cela permettra d'envoyer des donnés ou des commandes depuis ou vers
                                       // un ordinateur connecté au port série de la carte Arduino.
  delay (5000);                      // Pause de 5 secondes repérer le début de la boucle.
}

void loop()
{
  monmoteur.step(1);                   // Avance de 1 pas.
  Serial.print("nombre de pas:" );    // Affiche dans le moniteur "série"
  Serial.println(cptepas);           // le nbre de pas effectué.
  cptepas++;                        // Incrémente la variable cptepas pour compter les pas.
  delay(500);                      // Pause d'une demi seconde entre chaque pas.
}
CtrlMotVitCteNbrepas.pde
/*  Programme permettant de contrôler, via le moniteur série d'un ordinateur, un MOTEUR PAP BIPOLAIRE.    L'utilisateur choisit :   • La VITESSE (fréquence) CONSTANTE  • Le NOMBRE DE PAS à effectuer  • Le SENS de ROTATION    Le MOTEUR PAP doit être connecté aux broches 8 à 11 de la carte Arduino. */

#include <Stepper.h>                                 // Permettra d'utilser des fonctions de la librairie externe Stepper.h,
                                                    // librairie spécifique pour contrôler les MOTEURS PAP.
const int nbrepas360 = 48;                         // Fixe le nombre de pas pour faire un tour complet, c'est-à-dire 360°.
Stepper monmoteur (nbrepas360, 8, 9, 10, 11);     // Initialise la librairie Stepper.h
int vitlente = 400;                              // La vitesse du moteur en mode lent.
int vitrapide = 625;                            // La vitesse du moteur en mode rapide.
int vit = 0;                                   // Stockera la vitesse de rotation choisie par l'utilisateur.
int nbrepas = 0;                              // Stockera le nombre de pas à effectuer.
int stocktmp = 0;                            // Stockera temporairement les valeurs numériques à partir des chiffres entrés au clavier.

// Permettra de faire afficher des messages avec des valeurs retournées par le programme.
#define concat(A, B, C, D) {Serial.print((A));Serial.print((B));Serial.print((C));Serial.println((D));}

void setup()
{
    Serial.begin(9600);                 // Ouvre le port de communication en série et fixe sa vitesse.
                                       // Cela permettra d'envoyer des donnés ou des commandes depuis ou vers
                                      // un ordinateur connecté au port série de la carte Arduino.

    concat("Le moteur fait : ", nbrepas360, " pas par tours.","");
    concat("VITESSES (TOURS/MIN.) : 2 choix possibles !!! ", vitlente, " ou ", vitrapide);
    Serial.println ("SYNTAXE : vitvSEND, nbrepasnSEND, + ou -SEND dans CET ORDRE !!");
    Serial.println ();
}

void loop()
{

  if ( Serial.available())                                                             // Si des données envoyées depuis le moniteur de l'ordinateur sont reçues...
  {

    char cartap = Serial.read();                                                       // Stocke l'un après l'autre dans une variable de type char la série des caractères
                                                                                       //  tapés depuis le moniteur de l'ordinateur puis envoyés à la carte Arduino.

    if(cartap >= '0' && cartap &lt;= '9')  {stocktmp = stocktmp * 10 + cartap - '0';}     // Tant qu'il s'agit d'un chiffre, on crée un nombre à partir du précédent chiffre.

    else if(cartap == 'v')                                                             // Si le caractère suivant est la lettre v
         {
           vit=stocktmp;                                                               // on stocke le nombre tapé juste avant. Ce sera la vitesse, valant vit.
           concat ("REGLAGE de la VITESSE OK :    ", vit, " TOURS/MIN.", "");
           stocktmp=0;                                                                 // Remise à zéro de la variable servant à accumuler les chiffres tapés depuis le moniteur de l'ordinateur.
         }

    else if(cartap == 'n')                                                            // Si le caractère suivant est la lettre n
           {
            nbrepas=stocktmp;                                                         // on stocke le nombre tapé juste avant. Ce sera le nombre de pas, valant nbrepas.
            concat ("REGLAGE du NBRE de pas OK :      ", nbrepas, " PAS", "");
            stocktmp=0;                                                               // Remise à zéro de la variable servant à accumuler les chiffres tapés depuis le moniteur de l'ordinateur.
         }

    else if(cartap == '+')                                                            // Si le carcatère suivant est +
          {
            Serial.println ();
            Serial.println ("ROTATION du MOTEUR PAP en COURS !");
            Serial.println ("-------------------------------");
            concat (vit, " TOURS/MIN. (soit ", vit * nbrepas360 / 60, " PAS/SEC.)");
            concat (nbrepas, " PAS      (soit ~ ", nbrepas / (vit * nbrepas360 / 60), " SEC. de rotation)");
            concat (nbrepas / (240 * nbrepas360 / 66), " cm    parcourus ", "dans le ", "SENS HORAIRE &lt;-");
            Serial.println ();
            Serial.println ();
            monmoteur.setSpeed(vit);                                                // Fixe une vitesse de vit tours par min, vit est l'argument de la fonction setSpeed.
            monmoteur.step(nbrepas);                                                // Fait tourner le moteur de nbrepas pas dans le sens horaire, nbrepas est l'argument de la fonction step.
            vit = 0;                                                                // Remise à zéro de la variable servant à stocker la vitesse.
            nbrepas=0;                                                              // Remise à zéro de la variable servant à stocker le nombre de pas.
          }

    else if(cartap == '-')                                                          // Si le carcatère suivant est -
          {
            Serial.println ();
            Serial.println ("ROTATION du MOTEUR PAP en COURS !");
            Serial.println ("-------------------------------");
            concat (vit, " TOURS/MIN. (soit ", vit * nbrepas360 / 60, " PAS/SEC.)");
            concat (nbrepas, " PAS      (soit ~ ", nbrepas / (vit * nbrepas360 / 60), " SEC. de rotation)");
            concat (nbrepas / (240 * nbrepas360 / 66), " cm    parcourus ", "dans le ", "SENS ANTI-HORAIRE -&gt;");
            Serial.println ();
            Serial.println ();
            monmoteur.setSpeed(vit);                                                // Fixe une vitesse de vit tours par min, vit est l'argument de la fonction setSpeed.
            monmoteur.step(nbrepas *
 -1);                                           // Fait tourner le moteur de nbrepas pas dans le sens antihoraire, nbrepas est l'argument de la fonction step.
            vit = 0;                                                                // Remise à zéro de la variable servant à stocker la vitesse.
            nbrepas=0;                                                              // Remise à zéro de la variable servant à stocker le nombre de pas.
          }
  }
}
CtrlMotAccelTest.pde
/*   Programme permettant de faire des allers et retour d'un MOTEUR PAP BIPOLAIRE  jusqu'à une position donnée. Accélère et décélère en début et fin de course.  Le MOTEUR PAP doit être connecté aux broches 8 à 11 de la carte Arduino. */

#include <AccelStepper.h>
AccelStepper monmoteur;       // Initialise la librairie AccelStepper.h en
                              // définissant le type de moteur et le câblage.
                              // Ici, par défaut, MOTEUR PAP 4 fils et broches 8 à 11 de la carte Arduino.

void setup()
{
    monmoteur.setMaxSpeed(500.0); // Fixe une vitesse de n (nombre à virgule) pas par sec, n est l'argument de la fonction setMaxSpeed.
    monmoteur.setAcceleration(100.0);
    monmoteur.move(-5000);
    delay (5000);
}

void loop()
{
      //if (monmoteur.distanceToGo() == 0)
        //  {monmoteur.moveTo(-monmoteur.currentPosition());}  // Change de direction quand le nombre de pas est atteint.
      monmoteur.run();
}
CtrlMotVitVbleNbrepas.pde
/*  Programme permettant de contrôler, via le moniteur série d'un ordinateur, un MOTEUR PAP BIPOLAIRE.    L'utilisateur choisit :   • Le NOMBRE DE PAS à effectuer  • La VITESSE (fréquence) LIMITE  • L'ACCELERATION à appliquer  • Le SENS de ROTATION  Le moteur pap accélère et décélère en début et fin de fonctionnement.    Le MOTEUR PAP doit être connecté aux broches 8 à 11 de la carte Arduino. */

#include <AccelStepper.h>
AccelStepper monmoteur;                                // Initialise la librairie AccelStepper.h en
                                                      // définissant le type de moteur et le câblage.
                                                     // Ici, par défaut, MOTEUR PAP 4 fils et broches 8 à 11 de la carte Arduino.
int vitlente = 320;                                 // La vitesse limite du moteur en mode lent.
int vitrapide = 500;                               // La vitesse limite du moteur en mode rapide.
long nbrepas = 0;                                 // Stockera le nombre de pas à effectuer.
float vitlim = 0;                                // Stockera la vitesse limite de rotation choisie par l'utilisateur.
float accel = 0;                                // Stockera l'accélération choisie par l'utilisateur.
int stocktmp = 0;                              // Stockera temporairement les valeurs numériques à partir des chiffres entrés au clavier.

// Permettra de faire afficher des messages avec des valeurs retournées par le programme.
#define concat(A, B, C, D) {Serial.print((A));Serial.print((B));Serial.print((C));Serial.println((D));}

void setup()
{
    Serial.begin(9600);                 // Ouvre le port de communication en série et fixe sa vitesse.
                                       // Cela permettra d'envoyer des donnés ou des commandes depuis ou vers
                                      // un ordinateur connecté au port série de la carte Arduino.
    concat("VITESSES LIMITES (PAS/SEC.) : 2 choix possibles !!! ", vitlente, " ou ", vitrapide);
    Serial.println ("SYNTAXE : nbrepasnSEND, vitlimvSEND, accelaSEND, + ou -SEND dans CET ORDRE !!");
    Serial.println ();
}

void loop()
{

  if ( Serial.available())                                                                  // Si des données envoyées depuis le moniteur de l'ordinateur sont reçues...
  {

    char cartap = Serial.read();                                                            // Stocke l'un après l'autre dans une variable de type char la série des caractères
                                                                                            //  tapés depuis le moniteur de l'ordinateur puis envoyés à la carte Arduino.

    if(cartap >= '0' && cartap &lt;= '9')  {stocktmp = stocktmp * 10 + cartap - '0';}          // Tant qu'il s'agit d'un chiffre, on crée un nombre à partir du précédent chiffre.

    else if(cartap == 'n')                                                                  // Si le caractère suivant est la lettre n
           {
            nbrepas=stocktmp;                                                               // on stocke le nombre tapé juste avant. Ce sera le nombre de pas, valant nbrepas.
            concat ("REGLAGE du NBRE de pas OK :          ", nbrepas, " PAS", "");
            stocktmp=0;                                                                     // Remise à zéro de la variable servant à accumuler les chiffres tapés depuis le moniteur de l'ordinateur.
         }

    else if(cartap == 'v')                                                                   // Si le caractère suivant est la lettre v
         {
           vitlim=stocktmp;                                                                  // on stocke le nombre tapé juste avant. Ce sera la vitesse limite, valant vitlim.
           concat ("REGLAGE de la VITESSE LIMITE OK :      ", vitlim, " PAS/SEC.", "");
           stocktmp=0;                                                                       // Remise à zéro de la variable servant à accumuler les chiffres tapés depuis le moniteur de l'ordinateur.
         }

    else if(cartap == 'a')                                                                  // Si le caractère suivant est la lettre a
           {
            accel=stocktmp;                                                                 // on stocke le nombre tapé juste avant. Ce sera l'accélération, valant accel.
            concat ("REGLAGE de  l'ACCELERATION OK :      ", accel, " PAS/SEC. au CARRE", "");                       stocktmp=0;                                                                     // Remise à zéro de la variable servant à accumuler les chiffres tapés depuis le moniteur de l'ordinateur.
         }

    else if(cartap == '+')                                                                  // Si le carcatère suivant est +
          {
            Serial.println ();
            Serial.println ("ROTATION du MOTEUR PAP en COURS !");
            Serial.println ("-------------------------------");
            concat (nbrepas, " dans le", " SENS HORAIRE &lt;-", "");
            concat (vitlim, " PAS/SEC.", " comme VITESSE LIMITE", "");
            concat (accel, " PAS/SEC. au CARRE", " comme ACCELERATION appliquee", "");
            Serial.println ();
            Serial.println ();
            monmoteur.move(nbrepas);                                                        // Fixe un nombre de pas de nbrepas à effectuer dans le sens horaire, nbrepas est l'argument de la fonction move.
            monmoteur.setMaxSpeed(vitlim);                                                 // Fixe une vitesse limite de vitlim pas par sec, vitlim est l'argument de la fonction setMaxSpeed.
            monmoteur.setAcceleration(accel);                                             // Fixe une accélaration de accel pas par sec, accel est l'argument de la fonction setAcceleration.
            nbrepas = 0;                                                                 // Remise à zéro de la variable servant à stocker le nombre de pas.
            vitlim = 0;                                                                 // Remise à zéro de la variable servant à stocker la vitesse limite.
            accel = 0;                                                                 // Remise à zéro de la variable servant à stocker l'accélaration.
          }

    else if(cartap == '-')                                                                  // Si le carcatère suivant est -
          {
            Serial.println ();
            Serial.println ("ROTATION du MOTEUR PAP en COURS !");
            Serial.println ("-------------------------------");
            concat (nbrepas, " dans le", " SENS ANTI-HORAIRE -&gt;", "");
            concat (vitlim, " PAS/SEC.", " comme VITESSE LIMITE", "");
            concat (accel, " PAS/SEC. au CARRE", " comme ACCELERATION appliquee", "");
            Serial.println ();
            Serial.println ();
            monmoteur.move(nbrepas *
 -1);                                                   // Fixe un nombre de pas de nbrepas à effectuer dans le sens anti-horaire, nbrepas est l'argument de la fonction move.
            monmoteur.setMaxSpeed(vitlim);                                                 // Fixe une vitesse limite de vitlim pas par sec, vitlim est l'argument de la fonction setMaxSpeed.
            monmoteur.setAcceleration(accel);                                             // Fixe une accélaration de accel pas par sec, accel est l'argument de la fonction setAcceleration.
            nbrepas = 0;                                                                 // Remise à zéro de la variable servant à stocker le nombre de pas.
            vitlim = 0;                                                                 // Remise à zéro de la variable servant à stocker la vitesse limite.
            accel = 0;                                                                 // Remise à zéro de la variable servant à stocker l'accélaration.
          }
   }
 monmoteur.run();                                                                   // Fait tourner le moteur de nbrepas selon les paramètres entrés par l'utilisateur.
}
Conclusions
  • Le mini-rail de travelling est opérationnel concernant la partie "Arduino", mais il reste des affinages à réaliser sur la partie mécanique (micro-vibrations perceptibles à l'image, lorsque le camescope se déplace).

Voici un aperçu de la structure finale :

Nteardui2.jpg

  • La grosse difficulté pour contrôler via Arduino un moteur pas à pas récupéré dans un scanner est :

DE DÉTERMINER LES CARACTÉRISTIQUES TECHNIQUES EXACTES DU DIT MOTEUR (uni ou bipolaire, tension de fonctionnement, vitesses constantes de rotation…) !

Sans cela, on ne peut choisir la bonne solution Arduino.

Or la nomenclature du modèle est parfois obscure ainsi que les spécifications correspondantes du constructeur  !

  • Si on souhaite se simplifier la vie pour se lancer dans un projet similaire sans contrôler "numériquement" un moteur pas à pas, deux solutions sont envisageables :
    • Économique : acheter un moteur à courant continu contrôlé manuellement par un potentiomètre
    • Onéreuse : acheter ce dispositif

Documenté en mars 2014 par Nte alias Nicolas Terrasson