LOCODUINO

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

mardi 19 mars 2024

Visiteurs connectés : 64

Le microcontrôleur ATtiny45 (9)

Commande d’un moteur pas à pas unipolaire

.
Par : Christian

DIFFICULTÉ :

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.

<

Article mis à jour le 30 mars 2022 pour préciser les caractéristiques techniques du moteur 28BYJ-48

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 dont la fiche technique est donnée ci-dessous. Un tour complet est obtenu en 32 pas entiers (ou 64 demi pas) et comme le moteur est équipé d’un réducteur 1/64, un tour entier sur l’arbre de sortie est obtenu en 2048 pas (32 * 64) ou 4096 demi pas (64 * 64).

Fiche technique 28BYJ-48

En modélisme ferroviaire, le choix de ce moteur s’impose 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 peut être 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
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.

Si on travaille en demi pas, celui-ci vaut 5,625° et il faut donc 64 pas commandés 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 du réducteur. Ceci confère donc une grande précision de positionnement à ce moteur qui peut être nécessaire dans certains cas (plaque tournante par exemple).

Mais dans la plupart des cas, on peut travailler en pas entier et il faut alors 2048 pas commandés pour faire faire un tour complet à l’arbre de sortie de l’ensemble moteur-réducteur.

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
Figure 2
L’interface à base du CI ULN2003

Schéma de montage

Le montage suivant permet de faire varier la vitesse du moteur et son sens de rotation avec un simple potentiomètre. La précision de positionnement n’étant pas nécessaire, on travaillera en pas entier, soit 2048 pas pour un tour complet.

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
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
Figure 4
Le 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.

//ATtiny-UNO_Pont_tournant.ino
/*
  Christian BEZANGER - Jean-Luc BECHENNEC - septembre 2019 
  *** Pour carte UNO ou µC ATtiny25/45/85 ***
  Commande la rotation du moteur pas a pas avec un potentiomètre.
  Peut servir a un pont tournant. 

  Les phases du moteur pas a pas sont reliees imperativement aux
  sorties PB0:3 : soit 8, 9, 10, 11 sur UNO et broches 5, 6, 7, 2 sur ATtiny25/45/85
  Le point milieu d un potentiometre est branche sur A2 (broche 3 sur ATtiny)
*/

//#define UNO  // a commenter si ATtiny
#define ATtiny  // a commenter si UNO 

#ifdef UNO
const int portSortie[] = {8, 9, 10, 11};
#endif

#ifdef ATtiny
const int portSortie[] = {0, 1, 2, 3};
#endif

void setup() {
  // les pins en sortie
  for (int i = 0; i < 4; i++) {
    pinMode(portSortie[i], OUTPUT);
  }
}

void loop() {
  int vitesse;  // plus petit implique plus rapide, sauf 0 = immobile
  bool sens;
  int potentiometre;  // valeur du potentiometre

  potentiometre = analogRead(A2);  // valeur du potentiomètre (de 0 a 1023)
  potentiometre = potentiometre - 512;  // maintenant de -512 a +511
  // Analyse de la valeur pour determiner le sens
  if(potentiometre < 0) sens = false; else sens = true;
  // Analyse de la valeur pour determiner la vitesse
  potentiometre = abs(potentiometre);  // on ne considere que la valeur absolue
  if(potentiometre < 100) {vitesse = 0;}
  if(potentiometre >= 100 && potentiometre < 150) {vitesse = 40;}
  if(potentiometre >= 150 && potentiometre < 200) {vitesse = 36;}
  if(potentiometre >= 200 && potentiometre < 250) {vitesse = 32;}
  if(potentiometre >= 250 && potentiometre < 300) {vitesse = 28;}
  if(potentiometre >= 300 && potentiometre < 350) {vitesse = 24;}
  if(potentiometre >= 350 && potentiometre < 400) {vitesse = 16;}
  if(potentiometre >= 400 && potentiometre < 450) {vitesse = 8;}
  if(potentiometre >= 450 && potentiometre < 500) {vitesse = 4;}
  if(potentiometre >= 500) {vitesse = 2;}
  // Rotation egale a un pas en fonction du sens 
  tourneUnPas(sens, vitesse);
}

void tourneUnPas(bool dir, int ms) {
  // tableau pour la phase
  const byte phases[] = {HIGH, LOW, LOW, LOW};
  // variable "phaseIndex". Une variable static se comporte comme une variable globale.
  // en ce qui concerne sa durée de vie : elle existe avant que le programme ne commence
  // et donc en dehors de la fonction où elle est déclarée ; et comme une variable locale
  // en ce qui concerne son 'scope' : elle n'est accessible que de tourneUnPas comme
  // si il s'agissait d'une variable locale.
  static byte phaseIndex = 0;
  // La valeur de cette variable indique quelle phase du moteur est alimentee.
  // On augmente (ou diminue) cette valeur de 1 unite pour alimenter la phase suivante,
  // selon sens de rotation. phaseIndex reste egal a 0, 1, 2, 3 par operation modulo % 
  if(ms>0) {  // moteur non immobile
    if(dir) { // decalage vers la gauche
      phaseIndex = (phaseIndex+1)%4;
    }
    else {  // decalage vers la droite
      phaseIndex = (phaseIndex-1)%4;
    }
    for(int i=0;i<4;i++) {  // ecriture sur les lignes PB0:3
      digitalWrite(portSortie[i], phases[(phaseIndex+i)%4]);
    }
    delay(ms);
  }
}

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, je vous conseille de travailler en demi pas en modifiant le programme donné. Dans ce cas, 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 !

8 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

Un minimum pour jouer rapidement avec un Arduino

Où acheter ?

Résistances, kézako ?

Les cartes Teensy

Relais électromagnétique

Les diodes classiques

Détecteurs à ultrasons

De nouveaux composants pour continuer à jouer

La carte Arduino Uno

Bouton poussoir

Les différents types de mouvements d’un servomoteur

Les encodeurs en quadrature

Les indispensables du prototypage

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

Capteurs à effet Hall

Programmation des ATtiny Digispark

Ma première centrale DCC

Ma première manette DCC (1)

Une station DCC minimale avec boutons de commande et écran Oled

Ma première manette DCC (2)

Le Raspberry Pi Pico

Signalisation et sonorisation du va-et-vient pour deux trains

Configurateur de CV sur base de la station DCC minimale

Fabrication d’un programmateur pour microcontrôleurs ATtiny

Détection RailCom© avec ESP32 (ou Arduino)

Adieu Uno, bonjour Uno !

Ma nouvelle manette DCC avec ESP32 (1)

Ma nouvelle manette DCC avec ESP32 (2)

LES SATELLITES AUTONOMES : une nouvelle approche du concept de Satellites Locoduino. (1)

LES SATELLITES AUTONOMES : une nouvelle approche du concept de Satellites Locoduino. (2)

LES SATELLITES AUTONOMES : une nouvelle approche du concept de Satellites Locoduino. (3)

LES SATELLITES AUTONOMES : une nouvelle approche du concept de Satellites Locoduino.(4)

LES SATELLITES AUTONOMES : une nouvelle approche du concept de Satellites Locoduino. (5)

Les derniers articles

LES SATELLITES AUTONOMES : une nouvelle approche du concept de Satellites Locoduino. (5)


bobyAndCo

LES SATELLITES AUTONOMES : une nouvelle approche du concept de Satellites Locoduino.(4)


bobyAndCo

LES SATELLITES AUTONOMES : une nouvelle approche du concept de Satellites Locoduino. (3)


bobyAndCo

LES SATELLITES AUTONOMES : une nouvelle approche du concept de Satellites Locoduino. (2)


bobyAndCo

LES SATELLITES AUTONOMES : une nouvelle approche du concept de Satellites Locoduino. (1)


bobyAndCo

Détection RailCom© avec ESP32 (ou Arduino)


bobyAndCo, catplus

Ma nouvelle manette DCC avec ESP32 (2)


msport

Ma nouvelle manette DCC avec ESP32 (1)


msport

Adieu Uno, bonjour Uno !


Christian

Fabrication d’un programmateur pour microcontrôleurs ATtiny


Christian, Dominique, Jean-Luc

Les articles les plus lus

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

Commande de moteur à courant continu

Capteurs à effet Hall

Les différents types de mouvements d’un servomoteur

Relais électromagnétique

Programmation des ATtiny Digispark

LES SATELLITES AUTONOMES : une nouvelle approche du concept de Satellites Locoduino. (5)

Le Raspberry Pi Pico

Ma première centrale DCC

Des bus de communication pour l’Arduino