LOCODUINO

Forum de discussion
Dépôt GIT Locoduino
Flux RSS

vendredi 15 novembre 2019

83 visiteurs en ce moment

Le microcontrôleur ATtiny45 (9)

Commande d’un moteur pas à pas unipolaire

. Par : Christian

Certaines applications pour un réseau de trains miniatures ne requièrent pas toute la puissance d’un module Arduino/Genuino Uno et on peut trouver dommage de monopoliser un tel module pour si peu. La solution est de les confier à un microcontrôleur moins puissant, donc moins coûteux. Cette série d’articles vous présente le microcontrôleur ATtiny45 du constructeur Atmel et ses possibilités dans le domaine du modélisme ferroviaire.

Dans cet article, nous allons découvrir comment commander un moteur pas à pas unipolaire avec un ATtiny et un potentiomètre, ce qui permet de motoriser nos plaques tournantes ou d’autres accessoires comme des portes de hangar par exemple.

Qu’est-ce qu’un moteur pas à pas

Un moteur pas à pas est un moteur qui transforme une impulsion électrique en mouvement angulaire.

Il existe trois types de moteur pas à pas (reluctance variable, à aimants permanents ou hybride qui est une combinaison des deux). Dans tous les cas, le moteur est composé de bobines et d’un rotor en fer doux ou bien aimanté. Suivant la façon dont on alimente les bobines, le rotor se déplace d’un certain angle appelé pas. Pour faire un tour complet, il suffit alors de parcourir plusieurs pas de suite jusqu’à ce que la somme fasse 360°.

Par exemple, imaginons un moteur constitué de quatre bobines numérotées de 1 à 4, positionnées à 90° autour d’un rotor constitué d’un aimant. Quand on alimente une bobine, supposons qu’il se crée un pôle nord au plus près du rotor : le pôle sud du rotor sera attiré par ce pôle nord et le rotor tournera d’une certaine quantité. Pour faire tourner le rotor dans un sens, il suffit d’alimenter les bobines dans l’ordre 1, 2, 3, 4 alors que si on les alimente dans l’ordre inverse 4, 3, 2, 1, le rotor tournera dans l’autre sens.

L’avantage d’un moteur pas à pas par rapport à un moteur à courant continu est qu’il peut prendre et conserver une position très précise ; il suffit de maintenir le courant dans la dernière bobine alimentée. C’est pourquoi on les utilise couramment dans les imprimantes ou dans les scanners et cette propriété est très intéressante en modélisme ferroviaire pour positionner une plaque tournante très précisément face aux rails de sortie.

Les bobines du moteur pas à pas peuvent être de deux sortes, bipolaires ou unipolaires. Une bobine bipolaire peut être alimentée dans les deux sens, ce qui inverse donc le champ magnétique créé. Une bobine unipolaire comprend un point milieu, ce qui la divise en deux demi-bobines toujours alimentées dans un seul sens, ce qui rend la commande plus facile. Les moteurs bipolaires ont quatre fils pour alimenter les bobines alors que les moteurs unipolaires ont 5 ou 6 fils.

Les moteurs pas à pas peuvent fonctionner par pas entiers, par demi-pas ou encore avec un couple maximal : tout dépend de la façon dont on alimente les bobines. Il y aurait beaucoup à dire sur les moteurs pas à pas et ce n’est pas le but de cet article. Pour comprendre les différentes possibilités de leur fonctionnement, je vous renvoie à ce site internet que je trouve assez bien fait puisqu’il dispose d’un simulateur qui vous permettra de comparer différentes options.

Choix d’un moteur pas à pas pour le modélisme ferroviaire

Le choix du moteur dépend avant tout de ce que vous voulez en faire : commander un mouvement ou bien obtenir un positionnement très précis ? Dans la plupart des cas, n’importe quel moteur pas à pas devrait pouvoir convenir et on peut par exemple se contenter de récupérer le moteur dans une imprimante ou scanner hors service. Ce qui doit guider votre choix est avant tout la valeur du pas en degrés. Mais il faut aussi penser à l’interface électronique de commande, suivant que le moteur est bipolaire ou unipolaire.

Comme nous l’avons vu, un moteur unipolaire est plus simple à commander et c’est ce genre de moteur que nous allons privilégier. Pour illustrer cet article, mon choix s’est porté sur le moteur 28BYJ-48 pour plusieurs raisons :

  • Sa tension d’alimentation est de +5 V qu’on trouve couramment sur nos montages puisque c’est également la tension d’alimentation de l’ATtiny.
  • Il se trouve très facilement sur internet pour un prix très modique et est vendu avec une interface électronique à base d’UNL2003 qui amplifie les signaux du microcontrôleur de façon à alimenter les bobines.
  • Sa taille le prédestine à une utilisation facile quelle que soit l’échelle pratiquée.
  • Son positionnement est précis puisque son pas est de 5,625° et que le moteur comporte une démultiplication par 64.

La figure 1 montre ce moteur et son interface de commande.

Figure 1 : moteur et interface
Figure 1 : moteur et interface

Caractéristiques détaillées du moteur unipolaire 28BYJ-48

Comme le montre la figure 1, ce moteur dispose de 5 fils qui correspondent à quatre phases et un fil commun de retour. Pour le faire tourner, il suffit d’alimenter les phases les unes après les autres ; c’est le rôle du microcontrôleur ATtiny mais comme le courant que délivre un µC est trop faible, les signaux doivent être amplifiés pour alimenter les phases et ceci est le rôle du circuit ULN2003 de l’interface de commande.

Le fil correspondant au commun (points milieu des bobines) est de couleur rouge. La phase 1 est reliée au fil bleu, la 2 au fil rose, la 3 au fil jaune et la 4 au fil orange. Le moteur étant muni d’une prise avec détrompeur, vous n’avez pas à vous soucier de cette correspondance fils-phases.

Le pas est de 5,625° et il faut donc 64 pas pour faire 360°. Comme le moteur comporte un réducteur de 1/64, il faut donc faire 64 tours complets de moteur pour obtenir un tour complet en sortie d’arbre du réducteur ou ce qui revient au même parcourir 4096 pas (64 x 64) pour faire faire un tour complet à l’arbre moteur. Ceci confère donc une grande précision de positionnement à ce moteur.

La figure 2 montre l’interface de commande. On remarque le circuit ULN2003 qui est l’équivalent du circuit ULN2803 décrit dans l’article Amplifier le signal de sortie d’un ARDUINO avec un ULN 2803 à part que le 2003 ne possède que 7 transistors alors que le 2803 en possède 8, ce qui n’est pas un problème vu qu’on n’en utilise que quatre. On remarque également la présence de quatre LED qui permettent de contrôler quelle phase est alimentée. Le connecteur blanc permet de relier l’interface au moteur alors que les picots noirs (IN1 à IN4) sont à relier aux sorties du microcontrôleur.

Figure 2 : l'interface à base du CI ULN2003
Figure 2 : l’interface à base du CI ULN2003

Schéma de montage

On utilise les broches 5, 6, 7 et 2 pour commander les phases du moteur ; elles correspondent aux lignes 0 à 3 du PORT B du microcontrôleur (notées PB0:3), comme nous l’avons décrit dans le premier article de cette série Le microcontrôleur ATtiny45 (1). On utilise également la broche 3 qui correspond à une entrée analogique (ADC2) pour lire la tension récupérée sur un potentiomètre de 10 kΩ dont les points extrêmes sont reliés à GND et +5 V. Le point milieu du potentiomètre est à une tension comprise entre 0 et +5 V suivant la position du curseur.

La figure 3 montre le montage à réaliser.

Figure 3 : le câblage
Figure 3 : le câblage

Le convertisseur analogique numérique (CAN) de l’ATtiny convertit la tension sur l’entrée ADC2 en un entier compris entre 0 et 1023. En retranchant 512, l’entier évolue dans l’intervalle [-512, 511] et le zéro est alors situé au milieu de la plage de débattement. En fait, le programme crée une petite plage autour de cette position correspondant à l’arrêt du moteur. Si on tourne le bouton du potentiomètre dans le sens des aiguilles d’une montre pour s’écarter de cette position, le moteur tourne dans le sens des aiguilles d’une montre (quand on le regarde face à l’arbre de sortie). Si on tourne le bouton dans le sens opposé, le moteur tourne dans le sens opposé. Dans les deux cas, plus on s’éloigne de la position stop et plus le moteur tourne vite.

Si vous préférez obtenir l’inversion des sens de rotation, il suffit d’intervertir les phases sur l’interface et de réaliser le montage de la figure 4.

Figure 4 : câblage pour inverser les sens de rotation
Figure 4 : câblage pour inverser les sens de rotation

Comme vous le constatez, grâce à l’interface à base d’ULN2003, le montage est très simple et se résume à 4 câbles et un potentiomètre à relier. Et bien-sûr, prévoir une alimentation en 5 V DC.

Le programme

Tel qu’il est livré, le programme fonctionne pour un ATtiny25/45/85 qu’il suffit de programmer en suivant la procédure expliquée dans l’article Le microcontrôleur ATtiny45 (2). Mais le programme est aussi conçu pour commander un moteur pas à pas avec une carte UNO pour ceux qui n’ont pas d’ATtiny sous la main ; il suffit de dé-commenter la ligne 12 et de commenter la ligne 13 pour choisir entre UNO ou ATtiny. Ce sont les sorties 8, 9, 10 et 11 de la carte UNO qui sont utilisées pour commander les phases 1 à 4 du moteur. Quant au potentiomètre, il se connecte de la même façon sur l’entrée analogique A2 de la carte UNO.

  1. //ATtiny-UNO_Pont_tournant.ino
  2. /*
  3.   Christian BEZANGER - Jean-Luc BECHENNEC - septembre 2019
  4.   *** Pour carte UNO ou µC ATtiny25/45/85 ***
  5.   Commande la rotation du moteur pas a pas avec un potentiomètre.
  6.   Peut servir a un pont tournant.
  7.  
  8.   Les phases du moteur pas a pas sont reliees imperativement aux
  9.   sorties PB0:3 : soit 8, 9, 10, 11 sur UNO et broches 5, 6, 7, 2 sur ATtiny25/45/85
  10.   Le point milieu d un potentiometre est branche sur A2 (broche 3 sur ATtiny)
  11. */
  12.  
  13. //#define UNO // a commenter si ATtiny
  14. #define ATtiny // a commenter si UNO
  15.  
  16. #ifdef UNO
  17. const int portSortie[] = {8, 9, 10, 11};
  18. #endif
  19.  
  20. #ifdef ATtiny
  21. const int portSortie[] = {0, 1, 2, 3};
  22. #endif
  23.  
  24. void setup() {
  25. // les pins en sortie
  26. for (int i = 0; i < 4; i++) {
  27. pinMode(portSortie[i], OUTPUT);
  28. }
  29. }
  30.  
  31. void loop() {
  32. int vitesse; // plus petit implique plus rapide, sauf 0 = immobile
  33. bool sens;
  34. int potentiometre; // valeur du potentiometre
  35.  
  36. potentiometre = analogRead(A2); // valeur du potentiomètre (de 0 a 1023)
  37. potentiometre = potentiometre - 512; // maintenant de -512 a +511
  38. // Analyse de la valeur pour determiner le sens
  39. if(potentiometre < 0) sens = false; else sens = true;
  40. // Analyse de la valeur pour determiner la vitesse
  41. potentiometre = abs(potentiometre); // on ne considere que la valeur absolue
  42. if(potentiometre < 100) {vitesse = 0;}
  43. if(potentiometre >= 100 && potentiometre < 150) {vitesse = 40;}
  44. if(potentiometre >= 150 && potentiometre < 200) {vitesse = 36;}
  45. if(potentiometre >= 200 && potentiometre < 250) {vitesse = 32;}
  46. if(potentiometre >= 250 && potentiometre < 300) {vitesse = 28;}
  47. if(potentiometre >= 300 && potentiometre < 350) {vitesse = 24;}
  48. if(potentiometre >= 350 && potentiometre < 400) {vitesse = 16;}
  49. if(potentiometre >= 400 && potentiometre < 450) {vitesse = 8;}
  50. if(potentiometre >= 450 && potentiometre < 500) {vitesse = 4;}
  51. if(potentiometre >= 500) {vitesse = 2;}
  52. // Rotation egale a un pas en fonction du sens
  53. tourneUnPas(sens, vitesse);
  54. }
  55.  
  56. void tourneUnPas(bool dir, int ms) {
  57. // tableau pour la phase
  58. const byte phases[] = {HIGH, LOW, LOW, LOW};
  59. // variable "phaseIndex". Une variable static se comporte comme une variable globale.
  60. // en ce qui concerne sa durée de vie : elle existe avant que le programme ne commence
  61. // et donc en dehors de la fonction où elle est déclarée ; et comme une variable locale
  62. // en ce qui concerne son 'scope' : elle n'est accessible que de tourneUnPas comme
  63. // si il s'agissait d'une variable locale.
  64. static byte phaseIndex = 0;
  65. // La valeur de cette variable indique quelle phase du moteur est alimentee.
  66. // On augmente (ou diminue) cette valeur de 1 unite pour alimenter la phase suivante,
  67. // selon sens de rotation. phaseIndex reste egal a 0, 1, 2, 3 par operation modulo %
  68. if(ms>0) { // moteur non immobile
  69. if(dir) { // decalage vers la gauche
  70. phaseIndex = (phaseIndex+1)%4;
  71. }
  72. else { // decalage vers la droite
  73. phaseIndex = (phaseIndex-1)%4;
  74. }
  75. for(int i=0;i<4;i++) { // ecriture sur les lignes PB0:3
  76. digitalWrite(portSortie[i], phases[(phaseIndex+i)%4]);
  77. }
  78. delay(ms);
  79. }
  80. }

Télécharger

Le setup met en sortie les broches utilisées pour commander les phases. Remarquez qu’il n’est pas nécessaire de déclarer en entrée la broche lisant la tension du potentiomètre.

La loop commence par lire la valeur de tension du potentiomètre et donne un résultat compris entre 0 et 1023. On le ramène dans l’intervalle -512 à 511. Si la valeur est négative, on adopte un sens de rotation et si elle est positive, le sens opposé. Une fois qu’on a déterminé le sens de rotation, on s’intéresse à la valeur absolue (toujours positive) de cette valeur et on la compare à plusieurs intervalles pour en déterminer une valeur de la variable vitesse (plus cette variable est petite et plus la vitesse de rotation est grande en dehors de la valeur 0 qui indique que le moteur est arrêté). On peut remarquer, au vu des valeurs affectées à la variable vitesse, que la vitesse de rotation du moteur n’est pas une fonction linéaire de la position du potentiomètre ; cet effet est voulu et peut d’ailleurs être adapté pour obtenir des vitesses de rotation plus ou moins lentes. En fin de loop, on appelle la fonction tourneUnPas qui permet de faire tourner le moteur de la valeur d’un pas (suivant le sens de rotation déterminé).

La fonction tourneUnPas a deux arguments, d’une part la direction du mouvement (sens de rotation du moteur) et d’autre part le petit délai à attendre avant de rendre la main (plus ce délai est court et plus les pas se succèdent à grande vitesse). On utilise une variable static byte phaseIndex sur un seul octet (byte) pour désigner quelle phase est commandée (numérotée de 0 à 3). Cette variable doit pouvoir être retrouvée à chaque appel de la fonction et c’est pourquoi elle est déclarée static ; à chaque appel, la fonction augmente ou diminue d’une unité la valeur de cette variable en fonction du sens de rotation. La variable phaseIndex ne doit avoir que les valeurs 0, 1, 2, 3, ce qui est réalisé par l’opérateur modulo (%). Une boucle for permet ensuite de positionner les sorties à LOW ou HIGH de manière à n’alimenter que la phase concernée.

Conclusion

Voici donc une commande de moteur pas à pas à un prix défiant toute concurrence. Si vous l’adoptez pour motoriser une plaque tournante, l’angle entre les différentes voies de sortie doit être un multiple de 5,625 (le plus petit pas possible du moteur), par exemple 22,5°. Comme le moteur dispose d’un réducteur de 1/64, la précision d’arrêt est de 5,625 / 64 soit 0,09° : pas de quoi faire dérailler un train pour peu que les rails soient légèrement biseautés comme ils le sont parfois à l’interface entre deux modules. Enfin, ce montage peut aussi être amélioré en remplaçant le potentiomètre de commande par un clavier où on entre la voie de sortie et où c’est le microcontrôleur qui calcule le nombre de pas à faire et la direction à adopter pour rejoindre cette voie (tout en gérant la torsion des fils alimentant la voie de la plaque tournante !). Et pourquoi-pas aussi prévoir un affichage LCD donnant la voie d’entrée, de sortie, le sens de rotation et le nombre de pas. Vous voici occupé pour un petit moment alors amusez-vous bien !

7 Messages

Réagissez à « Le microcontrôleur ATtiny45 (9) »

Qui êtes-vous ?
Votre message

Pour créer des paragraphes, laissez simplement des lignes vides.

Lien hypertexte

(Si votre message se réfère à un article publié sur le Web, ou à une page fournissant plus d’informations, vous pouvez indiquer ci-après le titre de la page et son adresse.)

Rubrique « Matériel »

Fonctionnement et pilotage d’une DEL

Qu’est ce qu’une carte Arduino ?

Amplifier le signal de sortie d’un ARDUINO avec un ULN 2803

Résistances, kézako ?

Les cartes Teensy

Relais électromagnétique

Les diodes classiques

Détecteurs à ultrasons

La carte Arduino Uno

Bouton poussoir

Les différents types de mouvements d’un servomoteur

Les encodeurs en quadrature

Les écrans LCD alphanumériques

Des bus de communication pour l’Arduino

Les interrupteurs

Signaux lumineux et Arduino

Les shields de prototypage et de connexion

Commande de moteur à courant continu

Choisir sa carte Arduino

Une station DCC complète, polyvalente et économique avec JMRI.

Écran couleur tactile Kuman

Les derniers articles

Le microcontrôleur ATtiny45 (9)


Christian

Écran couleur tactile Kuman


Christian

Une station DCC complète, polyvalente et économique avec JMRI.


bobyAndCo

Les cartes Teensy


Christian, Jean-Luc

Choisir sa carte Arduino


Christian

Le microcontrôleur ATtiny45 (8)


Christian

Le microcontrôleur ATtiny45 (7)


Christian

Commande de moteur à courant continu


Christian

Le microcontrôleur ATtiny45 (6)


Christian

Les shields de prototypage et de connexion


Christian

Les articles les plus lus

Commande de moteur à courant continu

Qu’est ce qu’une carte Arduino ?

Les cartes Teensy

Une station DCC complète, polyvalente et économique avec JMRI.

Bouton poussoir

Détecteurs à ultrasons

La carte Arduino Uno

Les encodeurs en quadrature

Le microcontrôleur ATtiny45 (2)

Le microcontrôleur ATtiny45 (1)