DigitalSpirit / Wiki / Gestionde24servos

Présentation

Forum associé

Cette carte à été réalisé à la base pour le projet Bleuette qui est un robot hexapode, qui possède 2 Servo-Moteurs par patte, soit un total de 12 Servo-Moteurs à gérer le plus précisément possible et bien sûr de manière totalement synchrone.

Pour ceux qui se demande de quoi je parle, cliquez sur le lien suivant pour en savoir plus sur les Servo-Moteurs.

En premier lieu, j'ai utilisé l'excellent programme de commande de 8 servos des Fribottes (je me suis d'ailleurs amusé à rajouté un système pour gérer la vitesse des servos, j'essaierai d'ici peu de faire une page dessus) qui permet en fait de piloter 64 servos avec l'aide de 8 pics 16F84. Je me suis rapidement trouvé avec un problème de taille, en effet, comment synchronisé toutes ces pattes en même temps, autrement dit, comment faire pour que par exemple, tous les servos se mettent au neutre exactement en même temps car l'envoie des ordres série au micro controleur est décomposé ainsi :

Lors d'envoie d'ordre de mise au neutre de toutes les pattes, il y avait un décalage entre la première patte recevant l'ordre de mise au neutre et la dernière patte. Il n'était donc pas possible de synchroniser précisément 12 pattes avec 2 pic 16F84, j'ai alors décidé de développer ma propre carte.

Caractéristiques :

Détail technique :

Todo :

Software

Plusieurs méthodes existent pour commander plusieurs servos avec un seul micro controleur, ainsi, le programme des Fribottes à divisé les 20ms en 8, soit 2,5ms pour le traitement de la durée de l'impulsion, le chronogramme d'une telle méthode se trouve ci dessous :

On constate bien grâce au chronogramme que le servo dispose de 2.5ms (rectangle rouge) à chaque nouveau cycle de 20ms, ce qui est amplement suffisant pour effectuer divers traitements : lecture consigne courante, configuration du timer...etc...

Cette méthode est particulièrement bien adapté au traitement de 8 servos, on peut même passer à 10 servos avec cette méthode en perdant du débattement.

Malheureusement, il est simple de constater que cette méthode ne peut gérer 12 servos, voici donc un chronogramme d'une méthode radicalement différente qui nous permettra de commander autant de servos qu'on le souhaite, théoriquement bien sûr !

Comme le montre le chronogramme, toutes les impulsions partent au même moment, un atout indéniable pour avoir une parfaite synchronisation des servos.

Etant donné que les impulsions démarre en même temps et duront au minimum 400us (la plage s'étant de 400us à 2.4ms), il faudrait, une fois arrivé à 400us déterminé l'impulsion qui doit être arrêté en concordance avec sa consigne donc il faudrait lire toutes les consignes et chercher qui à la plus courte, en théorie, c'est possible, mais en pratique, c'est un vrai casse tête car notre micro controleur à beau tourner à 40Mhz, on n'aura jamais le temps de trié sans que ce soit préceptible sur les mouvements du servos ! La méthode logique est donc de trier les servos pendant la période d'inactivité des impulsions, c'est à dire quand elles sont toute à l'état bas !

Le traitement est divisé en 5 grandes phases :

Exemple avec 4 servos : Consigne servo 0: 128, servo 1: 128, servo 2: 80, servo 3: 254

Voici les tableaux générés après le tri :

Tableau des consignes triées (FSR0)

Numéro de servo Consigne
2 80
0 128
1 128
3 254

Tableau de l'état des ports (FSR1)

Num Sequences Port3 Port2 Port1 Port0
1 0 1 0 0
2 0 0 1 1
3 1 0 0 0

A chaque changement de consignes et une fois le temps de la consigne passé, le tableau correpondant à la séquence en cours est envoyé au port du PIC.

Tableau des nombre de ports actifs (FSR2)

Num Sequences Nombre de servos
1 1
2 2
3 1

Ce tableau permet de compter le nombre de servos passés à chaque séquence

Déroulement du programme de temporisation, mise à jour des servos :

Cette manière de faire à de gros avantages, en effet, elle permet de se passer des choses prenant beaucoup de temps CPU entre 2 consignes, elle a tout de même un inconvénient, elle consomme tout de même beaucoup en temps CPU mais comme elle se fait avant la mise à 1 des ports des servos, elle n'est pas ressenti sur la présision du système. Pour ceux qui souhaitent en savoir plus, je leur conseil de lire les sources que j'ai essayé de commenté le plus possible.

Hardware

Cette carte possède un PIC18F452 au format DIP et est donc imposant, je mettrai d'ici peu une carte possédant un PIC au format PLCC voir dans un format plus petit pour faciliter l'intégration dans de petits montages.

Le schéma de principe :

Le schéma d'implantation :

Les fichiers originaux au format Eagle

Liste des composants :

Dénomination Valeurs
C1, C2, C3, C4 100nf
C10, C11 22pf
R1,R2 1Kohm
IC1 PIC18F452P
IC2 MAX232
Q1 10mhz
X1 SubD9 Femelle
SERVO0 à SERVO23 Barette secable

Mapping des ports :

bit7 bit6 bit5 bit4 bit3 bit2 bit1 bit0
Servo 0 à 7 RC2 RC1 RC0 RA4 RA3 RA2 RA1 RA0
Servo 8 à 15 RE1 RE0 RB5 RB4 RB3 RB2 RB1 RB0
Servo 16 à 23 RD7 RD6 RD5 RD4 RD3 RD2 RD1 RD0

Les sorties RB6 et RB7 ne sont pas utilisés pour pouvoir garder une connectivité avec un éventuel module ICD.

Envoi de commande

Vous pouvez envoyer les commandes directement avec un autre PIC ou encore sous Window$ avec Hyper Terminal.

Pour cela, la connection RS232 doit être configuré en 9600b (oui, c'est beaucoup mais indispensable car le pic tourne à 40Mhz), 1bit de start, 1bit de stop. En mode SERVO_MODE_CMD_UNIT, il suffit d'envoyer 3 octets pour piloter UN seul servo :

Ainsi, pour mettre le servo 1 au neutre, il faut envoyer : 255 1 128

En mode SERVO_MODE_CMD_MASK, il faut envoyer un masque de bit :

Pour mettre le servo 1 au neutre, il faut envoyer : 255 1 0 0 128 (en binaire : 11111111 00000001 00000000 00000000 10000000) Pour mettre tous les servos au neutre, il faut envoyer : 255 255 255 255 128 (en binaire : 11111111 11111111 11111111 11111111 10000000)

En mode SERVO_MODE_CMD_MASK_3BLOCK, il faut envoyer un masque de bit :

Pour mettre le servo 1 au neutre, il faut envoyer : 255 0 0 1 0 0 128 (en binaire : 11111111 00000000 00000000 00000001 00000000 00000000 10000000) Pour mettre tous les servos au neutre, il faut envoyer : 255 255 255 255 128 128 128 (en binaire : 11111111 11111111 11111111 11111111 10000000 10000000 10000000)

Capture d'écran d'oscillo !

Voici 2 captures illustrant le principe de fonctionnement du programme, la première capture montre différentes consignes, à savoir : 0 pour le canal 1 (en jaune), 2 pour la canal 2 (en bleu), 128 pour le canal 3 (en violet) et enfin 255 pour le canal 4 en vert :

Enfin, dans cette seconde capture, toutes les consignes avaient été positionnées à 1 de manière à générer 400us, le canal 1 était connecté à SERVO0, le canal 2 à SERVO1, le canal 3 à SERVO22 et le canal 4 à SERVO23, on constate ainsi que l'erreur est inférieur à ~0.1us entre le premier servo et le dernier qui reçoit la consigne, ce qui était le but de ce montage.

Téléchargements

Ce programme est fourni sous les termes de la licence GNU General Public License