Ceci est une version archivée de
LienRealModel à 2008-03-25 11:06:11.
Retour
IV/ MISE EN PLACE DE LA LIAISON SERIE
Afin de synchroniser le bras et son modèle 3D, il est nécessaire de relier le micro-contrôleur M32C83 commandant les moteurs du bras et le poste à partir duquel on modélise graphiquement ce même bras. Plus concrètement, cette liaison permet au micro-contrôleur d'envoyer une trame qui informera Raydium sur l'angle imposé à chacun des moteurs. Au niveau matériel, cette liaison est assurée par un port série RS232.
PLAN
IV.1/ Côté micro-contrôleur
Pour une utilisation simplifiée des ports série, certaines fonctions ont été définies au début du programme principal, notamment les fichiers periph.h, uart0.h et dma0.h. Le port série doit ensuite être initialisé par la fonction periph_init(). La communication sur le port série se faisant de manière unidirectionelle (du M32C83 vers le poste informatique), seule la fonction periph_write() sera utilisée (pour écrire sur le port série).
// Détail de la structure 'commande' utilisée dans periph_write()
typedef union {
struct {
unsigned char dest;
unsigned char mode;
unsigned int val;
}s;
void * msg;
}commande;
void periph_write(char addr,int valeur)
{
commande comm;
comm.s.dest=addr; comm.s.mode=':'; comm.s.val=valeur;
snd_dtq (ID_bus_tx_qdm, (VP_INT) comm.msg);
}
La fonction fonction d'écriture prendra donc en paramètre :
- addr : un caractère correspondant à l'identifiant du moteur
- valeur : un entier correspondant à l'angle à imposer au moteur
On crée alors un nouveau modèle de trame en déclarant une variable comm de type commande. Le contenu de cette trame est précisé à la ligne uivante, selon un modèle précis :
- Le premier caractère indique l'identifiant du moteur concerné par la trame (précisé en paramètres).
- Le deuxième caractère précise le type d'opération que la trame doit effectuer. Les ':' indiquent qu'il s'agit d'une opération d'écriture periph_write()).
- Les quatre caractères suivants représentent l'angle à imposer au moteur (précisé en paramètres). Il s'agit d'un entier signé, codé sous a forme d'un short (16bits) pour des valeurs allant de -32768 à +32767.
Enfin la dernière instruction (snd_dtq()) apporte une précision quant à la manière de gérer l'envoi de cette trame au poste informatique. Celle-ci st stockée dans une queue de messages d'identifiant ID_bus_tx_qdm (défini dans le fichier template.cfg), d'où elle ne sera transmise que lorsque le port série sera libre.
Supposons que le programme rencontre l'instruction suivante :
Littéralement, il s'agit d'envoyer une trame au poste informatique pour appliquer un angle de 34°5 au moteur correspondant à l'identifiant C. La trame prendra cette forme :
Précisons que les quatres derniers caractères sont en hexadécimal. On effectuant une convertion, on retrouve bien 0x0159 = 345, soit 34°5. À noter que l'angle à appliquer au moteur peut être négatif, le bit de signe modifiera donc la forme de la trame. Par exemple, pour appliquer un angle de -60° au moteur C, la trame prendra la forme suivante :
Cette fonction periph_write() est donc appelée chaque fois que l'on modifie l'un des angles des moteurs réels, pour permettre à Raydium d'actualiser ses propres angles.
IV.1/ Côté moteur 3D
Pour que l'on puisse commander le bras grâce au port série, il faut définir certaines choses. Tout d'abord, il faut l'initialiser. Pour cela, il y a une fonction periph_init() déclaré dans le fichier "periph.h".
Ensuite, il faut créer un tableau de tous les moteurs que l'on veut commander. Voici la déclaration de ce tableau :
Periph periphs[] = {{'A',"test_bras_mot_axe1",'A',pi/1800,0,0},
{'B',"test_bras_mot_axe2",'A',pi/1800,-pi/2,0},
{'C',"test_bras_mot_axe3",'A',-pi/1800,0,0},
{'D',"test_bras_mot_axe4",'A',pi/1800,2*pi/18,0},
{'E',"test_bras_mot_axe5",'A',-pi/1800,0,0},
{'F',"test_bras_mot_axe6_1",'A',pi/1800,pi/4,0},
{'G',"test_bras_mot_axe6_2",'A',-pi/1800,-pi/4,0},
{'H',"test_bras_mot_axe6_4",'A',pi/1800,pi/4,0},
{'I',"test_bras_mot_axe6_6",'A',pi/1800,pi/4,0},
{'J',"test_bras_mot_axe6_8",'A',pi/1800,pi/4,0},
{'K',"test_bras_mot_axe6_10",'A',pi/1800,pi/4,0},
{'M',"test_bras_mot_axe6_3",'A',-pi/1800,-pi/4,0},
{'N',"test_bras_mot_axe6_5",'A',-pi/1800,-pi/4,0},
{'O',"test_bras_mot_axe6_7",'A',-pi/1800,-pi/4,0},
{'P',"test_bras_mot_axe6_9",'A',-pi/1800,-pi/4,0},
{0,"fin",0,0.0,0.0,0}};
Voici la signification des éléments. Prenons exemple avec l'axe2.
{'B',"test_bras_mot_axe2",'A',pi/1800,-pi/2,0}
- 'B' = caractère reçu en premier par le port série. Il sert à commander le moteur n°2.
- "test_bras_mot_axe2" = moteur à commander.
- 'A' = pour un moteur angulaire.
- pi/1800 = on multiplie la commande reçu par cette valeur => Il faut envoyer un angle en dixième de degré.
- -pi/2 = on additionne la commande par cette valeur => pour corriger les erreurs d'angle entre le vrai bras et le modèle.
Le dernier élément sert à couper la communication si il ne reçoit plus rien par le port série.
On a aussi déclaré une variable énuméré pour informer au moteur physique si la communication est établie ou non. Pour cela :
//variable énumérée pour la liaison série
enum {remote_on,remote_off}remote_mode=remote_off;
Enfin, on créé une fonction step() qui sera appelé indéfiniment dans le programme (comme la fonction display()).
/**
Cette fonction est appelé continuellement pour la connexion série
*/
void step(void){
if(remote_mode == remote_on);
{
remote_serveur_loop();
}
}
Retour