Aquila Reloaded – Chapitre 2 : piloter des moteurs pas à pas avec un Arduino

Hello world,

Maintenant que j’ai acheté et démonté un de mes 2 scans, il est temps de passer à la suite, à savoir piloter mes moteurs.

Pour réaliser ces tests, j’ai choisi d’utiliser l’Arduino Nano v3. Il est déprécié chez Arduino, mais qu’à cela ne tienne, on peut toujours compiler des programmes dessus et il a un prix très abordable dans sa version compatible (on peut le trouver autour de 3 à 4€ sur Aliexpress)

Un peu de théorie sur les PAP

Types de moteurs PAP : bipolaires vs unipolaires

Les moteurs pas à pas sont des moteurs permettant d’effectuer des rotations de précisions, Il existe deux familles de moteurs pas à pas : les moteurs bipolaires et les moteurs unipolaires. Le but n’est pas de faire un cours, mais si vous voulez des détails vous pouvez consulter ce document.

Pour faire simple :

  • Les moteurs bipolaires disposent de deux bobinages (donc 4 fils). Pour faire tourner le moteur, on alimente tour à tour les bobinages et en inversant la polarité. On utilise généralement un montage avec un pont en H pour gérer les inversions de polarité des deux bobinages.
  • Les moteurs unipolaires disposent également de deux bobinages, mais ces derniers ont chacun un point-milieu (donc 6 fils). Ils sont plus faciles à piloter puisqu’on alimente indépendamment les 4 « demi-bobinages » sans inversion de polarité. A noter que si on fait abstraction du « point-milieu », un moteur unipolaire peut être piloté comme un moteur bipolaire.

Pas entiers, demi-pas, couple maximal ?

Un moteur PAP est caractérisé par son nombre de pas par tour. Dans le cas de l’Aquila Reloaded, ce sont des moteurs à 200 pas par tour. Autrement dit, lors de l’exécution d’un pas, le rotor effectue une rotation de 1,8 degrés.

Il est possible de piloter les moteurs en « demi-pas », ce qui signifie que l’on alimentera deux bobinages consécutifs simultanément afin que le magnétisme place le rotor à cheval entre les 2 bobines. De ce fait un moteur de l’Aquila piloté en demi-pas pourra effectuer 400 pas par tour, et aura donc une précision de 0,9 degrés.

Enfin, il est aussi possible de piloter les moteurs PAP en « couple maximal ». Dans ce dernier cas, on alimente les bobines opposées de chaque moteur.

Câblage d’un PAP

Dans notre cas, on a des moteurs unipolaires donc ils vont être facile à câbler, mais bien évidemment, on ne peut pas câbler les moteurs directement sur l’Arduino. Sur le circuit d’origine, on dispose d’amplificateurs ULN2803A, qui sont des circuits intégrés disposant de 8 transistors Darlington, de 8 diodes « de roue libre » ainsi que de 8 résistances sur chacune des bases. (Datasheet consultable ici)

Avec un tel composant, on peut alimenter deux moteurs indépendamment l’un de l’autre, comme le montre le schéma ci-dessous :

Cela utilise en tout 16 fils pour nos 4 moteurs.

Astuces pour économiser le nombre de broches de l’Arduino

L’Arduino n’a pas un nombre de broches infinis et on pourrait être très vite limité si on décide de câbler plusieurs moteurs. Heureusement il existe quelques astuces pour réduire la consommation du nombre de broches.

Câblage avec 2 fils au lieu de 4

En pas complet, lorsqu’un « demi-bobinage » est alimenté, l’autre demi-bobinage ne l’est pas, et inversement. De ce fait, en utilisant 2 transistors cablés comme une fonction NON, il est possible de gérer ce cas, et de ce fait d’adresser le moteur avec 2 fils uniquement. Dans le schéma ci-dessous, on utilise 2 transistors supplémentaires du circuit intégré, mais on pourrait très bien utiliser 2 transistors NPN conventionnels.

On peut donc consommer uniquement 8 fils au lieu de 16 pour alimenter les 4 moteurs de l’Aquila. En contrepartie il nous sera impossible de les adresser en « demi-pas ».

NB : pour ceux qui auraient des moteurs bipolaires, il existe une variante de ce schéma avec un pont en H.

Multiplexage

Le circuit d’origine de l’Aquila dispose de deux SN74HC573N. Comme dit dans l’article précédent, il s’agit d’une bascule D sur 8 bits. La bascule D permet de garder l’état de ses sorties « gelées » tant que la patte de commande n’est pas à l’état haut. De ce fait, il est possible de multiplexer l’alimentation des moteurs en les groupant par paires sur une bascule D 8 bits. On aurait donc 8 fils pour alimenter 2 paires de moteurs, et 2 fils « sélecteurs » pour activer la bascule D idoine. Au total, on aurait 10 fils au lieu de 16. En utilisant 4 bascules D sur 4 bits, on pourrait réduire l’utilisation à 8 fils. En contrepartie, il ne sera pas possible de piloter les 4 moteurs « simultanément ». (mais les temps de traitement de l’Arduino rendront cela insignifiant)

Partie logicielle

Librairie « Stepper »

Il existe une librairie prête à l’emploi chez Arduino, à savoir la librairie « Stepper ». Elle est très simple d’emploi, elle permet de piloter un moteur PAP sur 2 ou 4 fils. Elle prend en paramètres le nombre de pas par tour du moteur, et les sorties de l’Arduino à utiliser.

Ensuite, l’objet créé possède 2 méthodes : une méthode « setSpeed » et « steps », qui comme leur nom l’indique servent respectivement à configurer la vitesse (en nombre de tours par minute) et le nombre de pas à faire.

La fonction « stepper » a quelques problèmes… elle ne sait pas fonctionner en tâche de fond, ce qui empêchera la réception de commandes DMX pendant le fonctionnement des moteurs.

J’ai donc travaillé avec une méthode simple : faire bouger le moteur d’un pas à chaque « tour de loop() ». Pour chaque moteur, je stocke la position cible à atteindre (reçue en DMX), et la position actuelle. Ça me permet de savoir combien de pas il me reste à faire. Ensuite le moteur bougera au rythme des « loops ».

Pour voir un exemple d’utilisation, cliquer ici.

Librairie « AccelStepper »

La librairie AccelStepper améliore drastiquement la fonction Stepper en lui ajoutant le support de coefficients d’accélération et décélération. La fonction supporte également les déplacements de moteurs synchronisés (par exemple pour les imprimantes 3D), et apporte également le support du fonctionnement des moteurs sans stopper l’exécution du programme.

Tous ces atouts font que je préfère utiliser cette librairie.

Installation d’AccelStepper

Cette librairie étant de type « third party », il faut au préalable l’installer. Pour cela il faut cliquer sur « Croquis > Inclure une bibliothèque > Gérer les bibiliothèques« .

Ensuite, rechercher AccelStepper, choisir la version à installer, puis cliquer sur Installer. Et voilà, la librairie est prête à être utilisée.

On peut accéder aux différents exemples liés à la librairie en allant dans « Fichier > Exemples > AccelStepper« .

Utilisation de la librairie

Pour faire simple, et si les exemples ne suffisent pas, voici comment utiliser rapidement la librairie.

Tout d’abord il faut créer un objet « AccelStepper » en global. Ici je vais créer un moteur « moteur1 » de type demi-pas, avec 4 fils.

AccelStepper moteur1(AccelStepper::HALF4WIRE, 2, 3, 4, 5);

Ensuite, je vais définir la vitesse maximale du moteur : plus le paramètre est élevé, plus le moteur tournera vite.

moteur1.setMaxSpeed(300);

Puis, je vais définir le coefficient d’accélération du moteur : plus le paramètre est élevé, plus le moteur accélérera vite.

moteur1.setAcceleration(100);

Puis on définit que la position actuelle du moteur est la position 0. Dans notre cas c’est déjà le cas, je met ce morceau de code uniquement pour l’exemple, après une calibration par exemple.

moteur1.setCurrentPosition(0);

Enfin, je vais définir à quelle position je souhaite déplacer le moteur, en nombre de pas. On considère que le moteur est actuellement en position 0 au démarrage du programme.

moteur1.moveTo(200);

Attention, dans notre cas, le moteur de l’Aquila fait 200 pas par tour. Or je l’adresse en demi-pas. Ce qui signifie qu’en effectuant un mouvement de 200 pas, le moteur tournera de 180 degrés uniquement. Pour effectuer un tour complet, il faut faire :

moteur1.moveTo(400);

Enfin, pour que le moteur se déplace il est nécessaire de placer ce petit morceau de code dans loop();

moteur1.run();

La fonction adaptera le rythme des moteurs en fonction de la charge du programme. Toutefois, il ne faut pas placer de « delay » dans le code, faute de quoi le programme ralentira les moteurs quoi qu’il advienne !

Voici le résultat final :

#include <AccelStepper.h>

AccelStepper moteur1(AccelStepper::HALF4WIRE, 2, 3, 4, 5);

void setup() {
 moteur1.setMaxSpeed(300);
 moteur1.setAcceleration(100);
 moteur1.setCurrentPosition(0);
 moteur1.moveTo(400);
}

void loop() {
 moteur1.run();
}

Voila, vous savez maintenant piloter des moteurs pas à pas. La suite au prochain épisode 🙂

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *