Aller au contenu


Keuronde

Inscrit(e) (le) 01 mai 2025
Déconnecté Dernière activité août 27 2025 09:05
-----

Messages que j'ai postés

Dans le sujet : Encore une présentation des servomoteurs Feetech

16 août 2025 - 01:43

Le mode pas à pas (Mode 3)
 
Avis personnel : je n'aime pas les moteurs pas à pas. Cherchez pas, c'est comme ça...
 
Les servomoteurs Feetech offrent un mode "pas à pas". Ce mode se construit par dessus le mode 0 (enfin c'est comme ça que je le conçois). Les correcteurs en vitesse et en position sont utilisés.
 
Le mode pas à pas s'active ainsi :

sms_sts.writeByte(SERVO_ID, SMS_STS_MODE, 3);

Pour commander un mouvement, vous utilisez la même fonction qu'en mode 0 (mode servo) sauf que la consigne de position à une signification légèrement différente. En effet, plus qu'un mode pas à pas, il faut le voir un mode de déplacement relatif à la position actuelle.
 
Pour demande un déplacement d'un nombre de pas égal à pas_servo, à la vitesse vitesse, vous utiliserez cette fonction :

sms_sts.WritePosEx(SERVO_ID, pas_servo, vitesse);

La première surprise que vous risquez de rencontrer, c'est que les butées logicielles sont actives dans ce mode. Je n'ai pas essayé de voir ce qui se passait si leur valeur dépassait 4096. Bref, pour les désactiver, mettez la butée min et la butée max à 0 :

sms_sts.writeByte(SERVO_ID, 0x09, 0); // Butée min à 0
sms_sts.writeByte(SERVO_ID, 0x0A, 0); // Butée min à 0
sms_sts.writeByte(SERVO_ID, 0x0B, 0); // Buté max à 0, désactivation de la butée
sms_sts.writeByte(SERVO_ID, 0x0C, 0); // Buté max à 0, désactivation de la butée

La lecture de la position actuelle pourrait vous surprendre, en effet, le registre ne contient plus la position actuelle mais le nombre de pas codeur à parcourir pour finir le mouvement. Vous lire donc 0 tant que vous ne demandez pas de mouvement. Vous observerez un sut à la demande du mouvement qui réduit au fur et à mesure que le servomoteur se rapproche de sa position.
 
Voici un exemple avec une demande de déplacement de 2000 pas toutes les 2 secondes
Mode3_retourPosition.png
 
Contrairement au mode servo, en mode pas à pas, comme la position revient systématiquement à zéro, vous n'avez pas de phénomène de rebouclage (enfin pas ici).
 
La limite se situe au niveau de la consigne qui doit tenir sur 16 bits (bit de signe inclus). Donc la commande maximale que vous pouvez envoyer pour un mouvement est de 32767 pas (soit 8 tours). Évidement, si vous demandez plus, vous observerez le phénomène de rebouclage.

 

Le mode basse résolution vous permet de faire passer cette limite à 21 tours, mais les cas où ceci est utile ne doivent pas être nombreux...

La commande que vous envoyée sera ajoutée à celle en cours. Donc si vous envoyez de nouvelles consignes avant que le mouvement soit terminé, vous risquez un dépassement, mais c'est vraiment un effet de bord qui ne devrait pas arriver sur une utilisation correcte du servomoteur :
Mode3_CumulConsigne.png


Dans le sujet : Encore une présentation des servomoteurs Feetech

12 août 2025 - 08:31

Les différents modes

Moteur à courant continue (Mode 2)

Dans ce mode, vous définissez une tension à envoyer au moteur. Et le moteur tourne.
C'est une boucle ouverte simple. Le retour du codeur n'est pas utilisé par le servomoteur.

L'intérêt dans un projet me parait assez faible, vu les autres modes disponibles.

L'initialisation se fait ainsi :

sms_sts.writeByte(SERVO_ID, SMS_STS_MODE, 2); // SMS_STS_MODE vaut 0x21

La commande doit être comprise entre 1000 et -1000.

  • Les bit 0 à 9 contiennent la valeur de la vitesse
  • Le bit 10 son signe (0 anti-horaire, 1 horaire)

Voici le code pour l'utiliser :

// Construction de la commande
commande_moteur_tmp = commande_moteur;
neg = 0;
if(commande_moteur_tmp < 0){
  neg = 1;
  commande_moteur_tmp = -commande_moteur_tmp;
}

// Envoi de la commande
sms_sts.writeWord(SERVO_ID, 0x2C, commande_moteur_tmp | neg << 10);

Note: J'ai des soucis dès que la consigne dépasse les 500. Mais je ne vais pas creuser plus...

Moteur asservi en vitesse (Mode 1)

Dans ce mode, vous indiquez une consigne de vitesse (un nombre de pas par seconde) que le moteur doit atteindre. Le servomoteur dispose d'un correcteur PI que vous pouvez ajuster en fonction de votre application.

L'initialisation se fait ainsi :

sms_sts.writeByte(SERVO_ID, SMS_STS_MODE, 1); // SMS_STS_MODE vaut 0x21

ou

sms_sts.WheelMode(SERVO_ID);

L'envoi de la consigne se fait en écrivant les registres 0x2E et 0X2F.
Les 15 premiers bits contiennent la valeur absolue, le 16e le signe.

Soit vous utilisez votre fonction :

vitesse_tmp = vitesse;
neg = 0;
if(vitesse_tmp < 0){
  vitesse_tmp = -vitesse_tmp;
  neg = 1;
}
sms_sts.writeWord(SERVO_ID, 0x2E, vitesse_tmp | neg << 15);

 
Soit vous utilisez la fonction de la bibliothèque

sms_sts.WheelMode(SERVO_ID);

C'est, comme la fonction de la bibliothèque l'indique, le mode idéal pour piloter des roues. C'est aussi un mode intéressant pour travailler le réglage d'un asservissement.

Sur l'image ci-dessous, vous voyez la consigne et la vitesse réelle, ainsi que la commande moteur. Sur deux cycles, j'ai freiné - légèrement - le servomoteur. Vous observé que la commande monte en flèche et que la vitesse se stabilise tout près de la consigne malgré la perturbation.

ModeVitesse.png


Servo mode (0)

Nous nous rapprochons beaucoup du servomoteur classique avec une consigne de position.

Simple tour

Le principe est relativement simple, vous envoyer une position, et le servomoteur y va.

Avec la configuration par défaut, en faisant varier la consigne de position de -512 à 5120, nous observons des butées logicielles à 0 et à 4093. Notons aussi que la position renvoyée peut reboucler à 0 comme indiqué sur le graphique. Nous avons globalement le fonctionnement d'un servomoteur classique, sauf que nous avons le retour de position et que nous pouvons régler également la vitesse.

ModeServo_normal.png

Multi-tour

Ces servomoteurs n'ont pas de butées mécaniques, et nous avons vu qu'ils pouvaient réaliser plusieurs tours.
En mettant à 0 la butée minimale (2 octets ) et la butée maximale (2 octets), nous pouvons activons le mode multi-tours. Ce mode sera particulièrement utile à tous ceux qui veulent entraîner des courroies, des vis à billes ou des mécanismes avec démultiplication. Ce mode présente deux inconvénients :

  • Au bout d'un certain nombre de tour, le compteur reboucle. Sur le modèle que j'ai, je peux faire 8 tours dans chaque direction à partir du zéro. Si je dépasse cette limite, le servomoteur part en sens inverse et réalise les 16 tours.
  • Si le servomoteur est dé-alimenté, il perd le nombre de tour qu'il a effectué et se réinitialise dans la plage du premier tour.

Par défaut, le servomoteur renvoie une position qui est toujours comprise dans le premier tour, entre 0 et 4096. Il y a un bit du registre Phase à modifier pour obtenir la position entre -8 et +8 tours. Mais activer ce bit ne réglera pas les deux inconvénients précédents.

Basse résolution

Il y a un paramètre qui permet de ne compter qu'un pas sur 2 ou un pas sur 3. Ceci dégrade la précision du codeur mais permet de multiplier par 3 (au max) la plage sur laquelle le servomoteur peut être contrôlé en position. Ceci n'a d'intérêt qu'en multi-tour. J'ai noté un comportement bizarre des butées logicielles et un écart x2 ou x3 entre la consigne et la position réelle.

Pour activer le mode basse résolution :

sms_sts.writeByte(SERVO_ID, 0x1E, 3);

Passer à 1 le bit 4 du registre "Phase" règle les comportements bizarre (au moins l'écart entre la consigne et la position réelle).
Attention, la valeur par défaut pourrait changer en fonction des modèles et version des servomoteurs.
 

sms_sts.writeByte(SERVO_ID, 0x12, 0x7C);    // Registre de "Phase", valeur par défaut 108 (0x6C)

Un schéma pour comprendre comment tout ça s’emboîte !

 

Asservissement.png

 

Un mot sur la bibliothèque Feetech

Le fabriquant fournis une bibliothèque qui permet d'accéder facilement aux fonctions des bases. Robot-Maker fourni une évolution de la bibliothèque un peu plus claire. Voici en vrac les points qui ont pu m'interroger ou qui mérite une précision...

La fonction Feedback

La fonction Feedback récupère les données d'état (accélération, vitesse, valeur PWM, Tension, température, erreur, indicateur de mouvement et courant consommé)  d'un servomoteur en une seule transaction de communication. par la suite, appeler les fonctions de lecture d'état (ReadSpeed, ReadPos, etc...) iront consulter ce tampon si l'identifiant passé en paramètre vaut -1. C'est ce qui est fait dans le code d'exemple, mais sans explications.

Les fonctions readByte et writeByte

Les fonctions readByte et writeByte permettent de lire et modifier les registres et vous permettent d'accéder à l'ensemble des fonctionnalités des servomoteurs. Les fonctions readWord et writeWord permettent d'écrire des valeurs de 16 bits sur deux registres consécutifs, en ne donnant que l'adresse du premier.

Avec ces fonctions vous pouvez recréer toute la bibliothèque et créer les fonctions qui vous manquent.

Les adresses des registres

Le fichier .h fourni quelques adresses de registre mais pas tous, loin de là. c'est dommage.

Le multi-tour

Le moyen d'activer le multi-tour n'est pas indiqué dans la bibliothèque. Les limitations du multi-tour ne sont détaillées nulle part, c'est dommage.


Dans le sujet : Encore une présentation des servomoteurs Feetech

08 août 2025 - 01:57

Si vous êtes arrivé jusqu'ici, vous avez :
- installé l'IDE
- installé la bibliothèque
- réalisé le câblage

Nous allons pouvoir nous pencher sur le fonctionnement détaillé de ces servomoteurs Feetech.

Ce qui suit est valable pour un type de servomoteur - ceux à potentiomètre.

Le protocole

Penchons nous un peu sur le protocole de communication.
Le protocole de communication est défini par Feetech, la documentation n'est pas simple, ni à trouver, ni à lire...
Pour la trouver, le lien direct est ici : https://www.feetechr...

Quand à la lire, voici les grandes lignes. Il y a deux types de trame, les instructions et les réponses. Une instructions est structurée ainsi :

  • Entête : 2 octets (0xFF 0xFF)
  • L'identifiant du servomoteur : 1 octet (1 à 255)
  • La taille du message : 1 octect
  • L'instruction (voir plus bas) : 1 octet
  • Les paramètres de l'instruction : 1 ou plusieurs octets
  • La somme de contrôle : 1 octet

La réponse du servomoteur est structurée ainsi :

  • Entête : 2 octets (0xFF 0xFF)
  • L'identifiant du servomoteur : 1 octet (1 à 255)
  • La taille du message : 1 octet
  • Le status du servomoteur : 1 octet (0 si OK)
  • Les valeurs de la réponse : 1 ou plusieurs octets
  • La somme de contrôle : 1 octet

Les instructions sont peu nombreuses :

  • 0x01 : Ping
  • 0x02 : Lire registre
  • 0x03 : Écrire registre
  • 0x04 : Écriture tamporisé
  • 0x05 : Execute les instructions tamporisés
  • 0x06 : Écriture synchronisée (pour envoyer la même instruction à plusieurs servomoteurs - aux identifiants consécutifs)
  • 0x07 : Réinitialisation des paramètres d'usine

Voici la base du protocole. La bibliothèque est suffisamment bien faîte pour que nous n'ayons pas à rentrer dans les subtilités du protocole de communication. Pour comprendre la logique de fonctionnement des servomoteur Feetech, nous n'avons besoin de connaître que trois instructions : ping (que nous avons déjà utilisée sans le savoir), lire registre et écrire registre.

La tables des registres

C'est donc dans la fonction des registres que réside tous les secrets du servomoteur Feetech.

Feetech met encore une fois à disposition sur son site la documentation (https://www.feetechr...-agreement.html).
Mais encore une fois, c'est pas simple à trouver, et en chinois. Le document qui nous intéresse s'appelle "Servo Protocole Memory Table" (https://www.feetechr...)

La mémoire est découpée en 4 parties :

  • EPROM en lecture seule. Elle contient quelques informations liés à la fabrication du servomoteur (Version logicielle et matérielle)
  • EPROM en lecture-écriture. Elle contient des paramètres que ne devraient être modifiés que rarement (tel que l'identifiant du servomoteur ou la vitesse du protocole de communication). Cette mémoire est protégée, vous devrez modifier une valeur dans la partie suivante pour pouvoir la modifier.
  • SRAM en lecture-écriture. Elle contient les valeurs qui seront modifiée couramment pendant l'utilisation normale du servomoteur (Position cible, vitesse)
  • SRAM en lecture seule. Elle contient l'état actuel du servomoteur (position, vitesse, tension, température, erreur, courant)

EPROM en lecture seule

Adresse - Fonction

0x00 - Version logicielle (majeur)
0x01 - Version logicielle (mineur)
0x02 - Réserve
0x03 - Version matérielle (majeur)
0x04 - Version matérielle (mineur)

EPROM en lecture et écriture


Adresse - Fonction

0x05 - Identifiant, doit être unique sur le bus. L'identifiant 254 est réservé.
0x06 - Débit du protocole de communication, valeur de 0 à 7, respectivement 1000000, 500000, 250000, 128000, 115200, 76800, 57600 et 38400 bauds. Par défaut, 0 : 1 Mbauds.
0x07 - Délais de retour ou temps entre la réception de la commande et le début de la réponse, par pas de 2 µs. Par défaut : 250 (soit 500 µs).
0x08 - Réponse systématique. 0, ne répond qu'au demande de Ping et aux demandes de lectures. 1 répond à toutes les commandes.
0x09 - Butée minimale de l'angle. (2 octets - de 0 à 4094)
0x0B - Butée maximale de l'angle. (2 octets - de 0 à 4095)
0x0D - Limite de température maximale, 70° par défaut.
0x0E - Tension d'entrée maximale (en 0,1 V)
0x0F - Tension d'entrée minimale (en 0,1 V)
0x10 - Couple maximal, en pour-mille (0,1%), 2 octets de 0 à 1000
0x12 - Phase - la doc dit "fonction spéciale"
0x13 - Activation/désactivation des protections (surcharge, surchauffe, surintensité, plage de tension)
0x14 - Activation/désactivation des protections, visualisation par LED ??? - Comme si une LED pouvait s'allumer en cas d'erreur
0x15 - Coefficient P du correcteur de position
0x16 - Coefficient D du correcteur de position
0x17 - Coefficient I du correcteur de position
0x18 - Force de démarrage minimale (en 0,1% de la force maximale)
0x19 - Saturation du terme intégral du correcteur de position
0x1A - Zone "morte" dans le sens horaire (en nombre de pas codeur)
0x1B - Zone "morte" dans le sens anti-horaire (en nombre de pas codeur)
0x1C - Limite de courant (par pas de 6,5 mA - 2 octets). Valeur de 0 à 500, ce qui correspond à un courant maximal de 3,25 A
0x1E - Résolution angulaire (de 1 à 3) - un moyen d'obtenir du multitour au détriment de la précision angulaire. Attention, lire la doc !
0x1F - Offset de position - le bit 11 indique le signe de l'offset (2 octets)
0x21 - Mode de fonctionnement - 0 : Servomoteur, 1 : Vitesse constante, 2 : Vitesse régulée, 3 : mode pas à pas. Nous reviendrons plus tard sur ces différents modes.
0x22 - Couple de protection - couple fourni après que le servomoteur soit entré en protection à cause d'une surcharge du couple, en 1%.
0x23 - Temps pendant lequel la protection de couple reste active après s'être déclenchée - en 10 ms.
0x24 - Couple déclenchant la protection - en 1%
0x25 - Coefficient P du correcteur de vitesse
0x26 - Temps pendant lequel la protection contre les sur-intensités reste active en 10 ms.
0x27 - Coefficient I du correcteur de vitesse

SRAM en lecture et écriture

Adresse - Fonction

0x28 - Active ou désactive le couple (la commande) du servomoteur
0x29 - Consigne d'accélération, en 100 pas/s²
0x2A - Consigne de position, de -32766 à 32766, en pas
0x2C - Commande moteur (PWM de -1000 à 1000)
0x2E - Consigne de vitesse,  de -32766 à 32766, en pas/s
0x30 - Limite de couple. Valeur initialisée à celle indiquée au registre 0x10 au démarrage du servo. peut être ajustée ici.
0x31 à 0x36 - registres réservés (ne pas toucher)
0x37 - Protection de l'EPROM. à mettre à 0 pour modifier l'EPROM, à remettre à 1 juste après pour la re-protéger.

SRAM en lecture seule

Adresse - Fonction

0x38 - Position actuelle (2 octets)
0x3A - Vitesse actuelle (2 octets)
0x3C - Charge actuelle (2 octets)
0x3E - Tension actuelle
0x3F - Température actuelle
0x40 - État "écriture tamporisée"
0x41 - État du servo. 0 pas d'erreur, sinon voir la doc.
0x42 - Indicateur de mouvement. 1 : en mouvement, 0 : à l'arrêt
0x43 & 0x44 - Registres réservés (ne pas toucher)
0x45 - Courant consommé

 

Avec ceci vous une bonne idée des capacités des servomoteurs. Si une bonne bibliothèque doit vous donnez les fonctions adéquates, savoir comment marche le servomoteur est important pour bien l'utiliser. Et parfois, la bibliothèque est un peu "jeune" :no: ...

 

Avec les deux fonctions ci-dessous, vous devriez pouvoir lister les registres de votre servomoteur :

int lire_registre(int servo_id, int registre_adresse){
  return sms_sts.readByte(servo_id, registre_adresse);
}

void lire_tous_les_registres(int servo_id){
  char message[200]="";
  for (int i=0; i<0x46; i++){
    sprintf(message, "registre 0x%x: %d\n", i, lire_registre(servo_id, i));
    Serial.print(message);
  }
}

Le prochain épisode sera consacré aux différents modes du servomoteur.