Fonctionnement des servomoteurs AX-12

 Servomoteur AX-12

Quand on réalise un projet avec des moteurs, on souhaite contrôler leur position ou leur vitesse (par exemple pour fixer la vitesse de rotation d'une roue). Cela peut être fait en asservissant un moteur quelconque, mais la structure finale peut être assez lourde, surtout pour les débutants (avec les connexions pour le micro-contrôleur, la nécessité de laisser de l'espace pour la codeuse, …). Une méthode alternative consiste à prendre un pack “tout-en-un”, où tout cela est déjà intégré au moteur, qui devient un servo-moteur. On peut alors communiquer avec lui (via un micro-contrôleur) pour qu'il suive les commandes reçues. Les AX-12 sont un modèle de servo-moteurs qu'on utilise beaucoup dans les robots de la Coupe de France et dont on va expliquer le fonctionnement dans cet article en étudiant notamment sa datasheet, disponible ici.

 Intérieur d'un AX-12.

Panoramique

Les AX-12A sont un modèle de servo-moteur chez Dynamixel d'entrée de gamme malgré leur prix d'environ 45€, à première vue élevé (en comparaison, certains modèles de la gamme MX et RX peuvent atteindre les 500€). Ils ont été conçus pour des mécanismes à basse vitesse et bas couple.

Grandeur Valeurs
Tension (V) entre 7 et 10
Courant (A) max. 0,9
Couple (Nm) max. 1,62
Vitesse (tours min-1) max. 59
Amplitude angulaire (°) entre 0 et 300
Résolution angulaire (°) 0,35
Communication UART 8-bits 1-stop sans parité
Inputs Angle, vitesse angulaire, couple
Outputs Angle, vitesse angulaire, couple, température, …

Même si on peut fixer un angle de consigne seulement entre 0 et 300°, le moteur peut tourner à 360° si configuré en “Wheel Mode”. Cela verra défini dans une section ultérieure.

Communication

Les AX-12 communiquent par UART (Universal Asynchronous Receiver Transmitter) avec des données de 8 bits, 1 bit de STOP et sans parité à travers des ports à 3 pins. La vitesse de communication doit être comprise entre 7 343 bps (bits par seconde) et 1 Mbps (1 Mb par seconde).

 Ports de connexion du AX-12

Même s'il y en a deux, un seul est suffisant pour communiquer avec l'AX-12, ce qui permet d'utiliser l'autre port pour le connecter à un autre AX-12. On pourra commander le servomoteur qui nous intéresse en spécifiant l'ID du moteur (compris entre 0 et 253, 254 indiquant un message pour tous les servomoteurs). Si deux AX-12 ont le même ID, on ne pourra pas distinguer lequel est à la source de l'information, ni lequel il faut commander.

 Trois AX-12 connectés en chaîne

Le contrôleur à gauche de ce dessin peut être n'importe quel circuit qui peut communiquer en UART half duplex avec des niveaux de tension TTL, notamment la “Control Box” CM-5, à la base des robots d'entraînement Bioloid.

Le paquet à envoyer a la structure suivante:

0xFF 0xFF ID LENGTH INSTRUCTION PARAMETRES CHECKSUM

  • ID est l'identifiant du servomoteur, de 0 à 253 (si vous devez vous adresser à plusieurs servomoteurs, il faut utiliser l'ID 254, et il n'y aura pas de STATUS renvoyés)
  • LENGTH est la longueur du message. On peut la calculer ainsi: LENGTH = nombre paramètres + 2
  • INSTRUCTION est l'instruction à effectuer (voir la section dédiée)
  • PARAMETRES est l'ensemble des paramètres à passer à l'instruction (un octet par paramètre)
  • CHECKSUM est un octet utilisé pour vérifier l'intégrité du message (pas d'erreurs pendant l'envoi, par exemple), calculé selon la formule suivante: CHECKSUM = NOT(ID + LENGTH + INSTRUCTION + Σ PARAMETRES) & 0x00FF

Le paquet envoyé par le servomoteur en réponse a la structure suivante:

0xFF 0xFF ID LENGTH ERROR PARAMETRES CHECKSUM

Elle est égale au paquet envoyé, sauf pour ERROR, un octet dont les bits montrent quelles erreurs ont eu lieu (l'une n'excluant pas les autres).

Instructions

Les instructions disponibles soselon le tableau suivant:

Octet Instruction Explication Nombre de paramètres
0x01 PING Le moteur appelé va répondre par un paquet Status 0
0x02 READ_DATA Le moteur appelé renvoie la valeur demandée 2
0x03 WRITE_DATA Le moteur appelé écrit les valeurs envoyées dans les cases mémoires spécifiées au moins 2
0x04 REG_WRITE Comme WRITE_DATA, mais les modifications auront lieu quand l'instruction ACTION sera envoyée au moins 2
0x05 ACTION Applique les instructions stockées avec REG_WRITE 0
0x06 RESET Le moteur appelé va être réinitialisé à ses valeurs de sortie d'usine (les valeurs par défaut) 0
0x83 SYNC_WRITE La mémoire aux mêmes adresses des moteurs appelés va être modifiée en même temps au moins 4

Structure des paquets envoyés pour chaque instruction:

  • PING: 0xFF 0xFF ID 0x02 0x01 CHECKSUM
  • READ_DATA: 0xFF 0xFF ID 0x04 0x02 Adresse de la case mémoire de départ Nombre de cases à lire CHECKSUM
  • WRITE_DATA: 0xFF 0xFF ID N+3 0x03 Adresse de la case mémoire de départ Valeur à écrire 1 (à la case de départ) Valeur à écrire 2 (à la case suivante) Valeur à écrire N (à la case N-1 après celle de départ) CHECKSUM
  • REG_WRITE: 0xFF 0xFF ID N+3 0x04 Adresse de la case mémoire de départ Valeur à écrire 1 (à la case de départ) Valeur à écrire 2 (à la case suivante) Valeur à écrire N (à la case N-1 après celle de départ) CHECKSUM
  • ACTION: 0xFF 0xFF ID 0x02 0x05 CHECKSUM
  • SYNC_WRITE: 0xFF 0xFF 0xFE (L+1)*N+4 0x83 Adresse de la case mémoire de départ Nombre de données à écrire (L) ID du 1er servomoteur Valeur à écrire 1 (à la case de départ) Valeur à écrire 2 (à la case suivante) Valeur à écrire L (à la case L-1 après celle de départ) ID du 2ième servomoteur Valeur à écrire 1 (à la case de départ) Valeur à écrire 2 (à la case suivante) Valeur à écrire L (à la case L-1 après celle de départ) ID du dernier servomoteur (le N-ième) Valeur à écrire 1 (à la case de départ) Valeur à écrire 2 (à la case suivante) Valeur à écrire L (à la case L-1 après celle de départ) CHECKSUM

Réponses aux paquets précédents:

  • PING: 0xFF 0xFF ID 0x02 ERROR CHECKSUM
  • READ_DATA: 0xFF 0xFF ID Nombre de cases à lire (N) + 2 ERROR Valeur de la case 1 Valeur de la case 2Valeur de la case N CHECKSUM
  • WRITE_DATA: 0xFF 0xFF ID 0x02 ERROR CHECKSUM
  • REG_WRITE: 0xFF 0xFF ID 0x02 ERROR CHECKSUM
  • ACTION: 0xFF 0xFF ID 0x02 ERROR CHECKSUM
  • RESET: 0xFF 0xFF ID avant le RESET 0x02 ERROR CHECKSUM
  • SYNC_WRITE: pas de message renvoyé

Mémoire

La mémoire du servomoteur est structurée ainsi:

Instruction Accessible en … Octet Valeur par défaut Valeur minimale Valeur maximale
Lecture Ecriture
Area EEPROM
Nombre de modèle (octet “bas”) X 0x00 12 - -
Nombre de modèle (octet “haut”) X 0x01 0 - -
Version du firmware X 0x02 variable - -
ID X X 0x03 1 0 253
Baud Rate X X 0x04 1 0 254
Temps de retour X X 0x05 250 0 254
Angle limite (octet “bas”) (sens horaire) X X 0x06 0 255
Angle limite (octet “haut”) (sens horaire) X X 0x07 0 0 3
Angle limite (octet “bas”) (sens antihoraire) X X 0x08 255 0 255
Angle limite (octet “haut”) (sens antihoraire) X X 0x09 3 0 3
[espace réservé] 0x0A 0 - -
Température maximale X X 0x0B 85 0 190
Tension minimale X X 0x0C 60 50 250
Tension maximale X X 0x0D 190 50 250
Couple maximal (octet “bas”) X X 0x0E 255 0 255
Couple maximal (octet “haut”) X X 0x0F 3 0 3
Niveau de retour des status X X 0x10 2 0 2
LED d'alarme X X 0x11 4 0 127
Extinction de l'alarme X X 0x12 4 0 127
[espace réservé] X X 0x13 0 0 1
Calibration basse (octet “bas”) X 0x14 variable - -
Calibration basse (octet “haut”) X 0x15 variable - -
Calibration haute (octet “bas”) X 0x16 variable - -
Calibration haute (octet “haut”) X 0x17 variable - -
Activation du couple X X 0x18 0 0 1
LED X X 0x19 0 0 1
Marge d'erreur pour rotation horaire X X 0x1A 0 0 254
Marge d'erreur pour rotation antihoraire X X 0x1B 0 0 254
Marge de pente pour rotation horaire X X 0x1C 32 1 254
Marge de pente pour rotation antihoraire X X 0x1D 32 1 254
Position objectif (octet “bas”) X X 0x1E valeur à l'adresse 0x24 [position actuelle (octet “bas”)] 0 255
Position objectif (octet “haut”) X X 0x1F valeur à l'adresse 0x25 [position actuelle (octet “haut”)] 0 3
Vitesse objectif (octet “bas”) X X 0x20 0 0 255
Vitesse objectif (octet “haut”) X X 0x21 0 0 3
Couple limite (octet “bas”) X X 0x22 valeur à l'adresse 0x0E [ Couple maximal (octet “bas”)] 0 255
Couple limite (octet “haut”) X X 0x23 valeur à l'adresse 0x0F [ Couple maximal (octet “haut”)] 0 3
Area RAM
Position actuelle (octet “bas”) X 0x24 variable - -
Position actuelle (octet “haut”) X 0x25 variable - -
Vitesse actuelle (octet “bas”) X 0x26 variable - -
Vitesse actuelle (octet “haut”) X 0x27 variable - -
Couple actuel (octet “bas”) X 0x28 variable - -
Couple actuel (octet “haut”) X 0x29 variable - -
Tension actuelle X 0x2A variable - -
Température actuelle X 0x2B variable - -
Instruction enregistrée X X 0x2C 0 0 1
[espace réservé] 0x2D 0 - -
Mouvement X 0x2E 0 0 1
Verrouillage X X 0x2F 0 1 1
Courant minimal (octet “bas”) X X 0x30 32 0 255
Courant minimal (octet “haut”) X X 0x31 0 0 3

Les données dans la partie EEPROM (mémoire non-volatile) ne seront pas réinitialisées quand le moteur est allumé, contrairement à la RAM (mémoire volatile). Par exemple, si l'ID est 25 et la vitesse objectif est de 150, une fois le moteur éteint et rallumé l'ID vaudra toujours 25, mais la vitesse objectif vaudra 0.

Bit Nom erreur Explication
1xxx_xxxx [non utilisé?] -
x1xx_xxxx Erreur de l'instruction Instruction non définie ou instruction d'action envoyée sans l'instruction Reg_Write (voir plus loin)
xx1x_xxxx Erreur de charge excessive Le moteur ne peut pas bouger la charge en appliquant le couple maximal autorisé
xxx1_xxxx Erreur de checksum Le checksum est incorrect
xxxx_1xxx Erreur d'intervalle Les paramètres de l'instruction ne sont pas dans l'intervalle autorisé (par exemple quand on veut fixer un couple trop élevé)
xxxx_x1xx Erreur de surchauffe La température du servomoteur est supérieure à la limite autorisée
xxxx_xx1x Erreur d'angle limite L'angle objectif n'est pas dans l'intervalle fixé par les angles limites pour les sens horaire et antihoraire
xxxx_xxx1 Erreur de tension La tension d'entrée n'est pas dans l'intervalle autorisé

Cases mémoire

Voici l'explication détaillée des cases mémoire du AX-12 (pour plus de détails, voir la datasheet).

0x00 et 0x01: numéro du modèle du servomoteur (0x000C ou 12 pour l'AX-12)
0x02: version du firmware (lecture seule)
0x03: ID du servomoteur. Il doit être différent pour chaque servomoteur dans le même réseau.
0x04: coefficient pour déterminer le Baud Rate: Baud Rate = 2 000 000 / (1 + valeur de la case). La tolérance du UART (et donc l'erreur maximale tolérée) est d'environ 3%.
0x05: coefficient pour déterminer le délai entre le paquet d'instruction et celui de status selon la formule: t = (2 * valeur de la case ) µs
0x06 à 0x09: limites angulaires. Il faut: angle limite horaireangle objectifangle limite antihoraire, sinon l'erreur d'angle limite sera déclenchée.
0x0B: température maximale autorisée (en °C). La dépasser déclenchera l'erreur de surchauffe.
0x0C et 0x0D: limites de tension autorisées, avec tension minimaletension actuelletension maximale, sinon l'erreur de tension sera déclenchée. La valeur de ces cases est la tension souhaitée multipliée par 10 (la tension minimale par défaut est donc 8,0 V).
0x0E et 0x0F: couple maximal autorisé (copié au démarrage du moteur dans les cases 0x22 et 0x23). Si leur valeur est 0, le servomoteur passe en mode “rotation infinie” (Endless Turn), et donc on peut faire un asservissement en vitesse. La vitesse objectif est alors définie par les cases 0x1E et 0x1F (0000 0xpp pppp pppp, avec p la vitesse en valeur absolue et x le sens de rotation, 0 en sens antihoraire et 1 en sens horaire)
0x10: niveau de retour STATUS. Il peut prendre ces valeurs:

  • 0: le servomoteur ne renvoie pas de STATUS
  • 1: le servomoteur renvoie un STATUS seulement pour une instruction READ_DATA
  • 2: le servomoteur renvoie toujours un STATUS

:!: Si le message est envoyé à tous les servomoteurs (ID 254) il n'y aura pas de STATUS
0x11: cet octet indique quand la LED clignote suite à une erreur. Si le bit de l'erreur est à 1, la LED clignote si cette erreur survient, et elle s'arrête deux secondes après que l'erreur a été résolue.
0x12: cet octet se comporte comme le précédent, mais le moteur est désactivé (couple ramené à 0) si l'erreur survient. Pour redémarrer le servomoteur, il faut écrire 1 à l'adresse 0x18.
0x14 à 0x17: constantes de calibration pour le servomoteur (lecture seule)
0x18: si cette case est à 0, le moteur est en mode roue libre (couple nul), si à 1 il peut appliquer un couple à la charge.
0x19: la LED est allumée si cette case est à 1 et éteinte si elle est à 0.
0x1A à 0x1D: variables pour déterminer le comportement du moteur pour atteindre la position objectif: 0x1A et 0x1B indiquent l'intervalle dans lequel doit être la position pour être considérée égale à l'objectif, 0x1C et 0x1D indiquent l'intervalle dans lequel la vitesse de rotation diminue quand la position se rapproche de l'objectif.

 Schéma montrant la vitesse de rotation en fonction de l'erreur de position 0x1E et 0x1F: position objectif, dans le sens antihoraire et à moitie à la verticale (0x0000: 5h, 0x01ff: 12h, 0x03ff: 7h).

 Schéma montrant la position du servomoteur en fonction de la valeur stockée dans les deux cases mémoire. 0x20 et 0x21: vitesse maximale pour atteindre la position objectif (s'il y a assez de puissance en entrée). 0x03ff correspond à 114 tours par minute, et 0x0001 est la vitesse minimale. 0x0000 désactive le contrôle de vitesse, qui sera la maximale pour la tension en entrée donnée.
0x22 et 0x23: couple maximal. Cette valeur fixe la limite actuelle, alors que les cases 0x0E et 0x0F servent à initialiser cette valeur au démarrage du moteur.
0x24 et 0x25: position actuelle du moteur. La même convention que pour la position objectif s'applique.
0x26 et 0x27: vitesse actuelle du servomoteur.
0x28 et 0x29: charge appliquée au servomoteur: 0000 0xpp pppp pppp avec p la charge en valeur absolue et x le sens de la charge (0: antihoraire, 1: horaire).
0x2A: tension appliquée au moteur (V+ = valeur de la case * 0.1)
0x2B: température du servomoteur (en °C)
0x2C: cette case passe à 1 si une instruction REG_WRITE a été exécutée et elle passe à 0 quand ACTION a été exécutée
0x2E: cette case passe à 1 si le servomoteur est en train de tourner (et pas de se faire tourner) et à 0 sinon.
0x2F: si cette case passe à 1, les seules cases pouvant être modifiées sont celles allant de 0x18 à 0x23 (mode de rotation, LED, marges, position objectif, vitesse maximale et couple maximal), la lecture restant autorisée. Une fois bloqué, le servomoteur ne peut être débloqué qu'en le débranchant et en le rebranchant.
0x30 et 0x31: valeur de courant minimal quand le moteur tourne.

Nouveau article écrit par FAGAN Patrick

Article originel écrit par BERNARDI GRA Thibaut

9 février 2010