Communication entre RCX

, par  Richard OLIVERO

Les communications entre RCX ou RCX <-> PC.

1 - PRESENTATION

Le RCX possède un système de communication par Infra-Rouge(IR). Très à la mode il y a une decennie, pour faire communiquer entre eux des materiels aussi divers que des calculettes, des PC . Les PC sont même prévus d’origine avec ce type de port. Les limites inhérentes à la nature même du support physique de transmission ajouté à la position des fabricants a fait avorter ce type de communications.

Le RCX conçu dans cette période est doté de ce type de communication. Mais dans ce cas la simplicité de mise en œuvre, la fiabilité, ont prévalu. La faible capacité mémoire occulte la lenteur de ce type de communication.

La communication est le parent pauvre du RCX, les quelques livres en français, ainsi que les articles en ligne ne font qu’effleurer le sujet. Si bien que rare sont les réalisations comportant plus de 2 RCX. Le RIS étant le seul set incluant le RCX, est de par son prix un frein. Malheureusement LEGO ne commercialise plus le RCX en pièce détachée. Mais les passionnés de Mindstorms© possèdent souvent 2 ou plusieurs RCX.

Des MOC comportant plusieurs RCX existent mais la communication entre eux est souvent assez primaire se résumant à l’envoi par un des RCX d’un, voir 2, messages. Les possesseurs de télécommande utilisent les messages envoyés par celle ci pour commander le RCX, mais le plus souvent la télécommande est utilisée en direct.

Pourtant les RCX ont un bon système de communication, qui bien utilisé multiplie les possibilités.

2 - LE MATERIEL

Le port de communication du RCX est placé à l’avant, le cône de réception émission est assez large. Je n’ai pas trouvé ses caractéristiques, j’ai donc procède à quelques essais rapides.
On peut considérer que la demi-sphère supérieure centrée sur le port IR constitue l’enveloppe utile. Dans le cas ou aucun obstacle ne se trouve entre les 2 ports, 2 RCX placés dos a dos (fond gris contre fond gris) communiquent très bien.

Tout cela fait qu’il est relativement facile d’implanter des RCX sur un MOC. Philo au cours d’un de nos multiples échanges, m’a en outre signalé la possibilité d’utiliser les ondes réfléchies. Une plaque blanche renvois les IR comme un miroir. Cette possibilité est très utile.

La porté varie suivant le type de RCX. Le type 1 est plus puissant que les type 1.5 et 2. n’ayant que des types 2 je ne puis vérifier. Mais 2 niveaux e puissance sont disponible. On peut les sélectionner soit par programme, soit dans le logiciel LEGO.

J’ai constaté une portée supérieure a 5 m dans de bonnes conditions. Mais le type même de « Porteuse » qui ne fonctionne correctement qu’ »en vue » limite fortement la portée pratique..
En résumé faire communiquer 2 RCX fixe l’un par rapport à l’autre est assez facile.

Par contre faire communiquer de RCX mobile (place sur un robot mobile) est plus hasardeux.

Ces caractéristiques s’appliquent aussi à la communication entre la tour et les RCX. Ce qui limite l’intérêt d’une caméra embarquée. Il en existe maintenant des remarquables à moins de 100€, émetteur compris. Il est très amusant de piloter un robot à travers une caméra. Encore faut il que le robot puisse recevoir des ordres à travers une cloison.

Ces limites une fois connues, la communication entre RCX et RCX base est tout à fait possible.

3 - LE PROTOCOLE SPECIFIQUE

LEGO® met à notre disposition un protocole réduit. Trois commandes sont à notre disposition

  • Envois d’un message comportant un seul octet.
  • Réception du message
  • Mise à 0 du buffer de réception.

Le fait que le message émis soit limité à un seul octet ne permet que 255 messages différents. LeJOS et brickOS s’affranchissent de cette limite, NQC qui garde le firmware LEGO ne s’en affranchit pas.

Mais la facilité d’utilisation de NQC et les options fournis par bricxCC ouvre des perspectives fort intéressantes.

Je suis persuadé que beaucoup de Mindstormiens on eut une reaction du genre « pppffffff que ça » à la lecture des possibilités de communication. En tout cas moi j’ai eut cette réaction. Je me suis dis avec ça on va pas loin.

Mais mon expérience de marin s’est rappelé à moi. Le code international par pavillon. Il comporte moins de 40 pavillons différents. Avec 5 pavillons au maximum le livre « Code international » comporte 1500 pages de message différents. Malgré les moyens modernes, ce code est toujours en vigueur. Donc 255 messages différents sont largement suffisant pour nos besoins.

La manière la plus simple d’utiliser ces 255 messages est d’établir une table de correspondance entre le numéro du message et sa signification. Malgré mes faibles connaissances en linguistique, je sais qu’un homme utilise moins de 100 mots différents dans une conversation courante. En imaginant 2 RCX communicants ils ont 120 mots à leur disposition. Largement suffisants pour une grosse application tant que des ordres sont échangés. Et je parle là d’un vrais dialogue du genre :

  • RCX 1 lève le bras
  • RCX 2 bien reçu
  • RCX 2 bras levé
  • RCX 1 ouvre la pince
  • RCX 2 pinces déjà ouvertes.
  • RCX 1 avance
  • RCX 2 moteurs en avant
  • RCX 2 détecteur 3 actionné moteur stoppes
  • RCX 1 moteur 2 AR

Chaque message correspond à une séquence bien définie. Le plus difficile s’est la définition des séquences correspondant au message. Cela s’appelle un protocole.

Donc tant que vous avez besoin de ce genre de communication et 2 RCX la communication est possible. Une vraie communication et non pas juste des messages envoyés en « l’air » en espérant que l’autre RCX les reçoivent.

Au dela de 2 RCX ou si vous voulez échanger des données autre que booléennes, ça devient plus difficile.

Mais déjà faire communiquer 2 RCX est amusant. Vous trouverez à la fin un programme où 2 RCX communiquent comme R2D2 et C3PO. Le résultat n’est pas à la hauteur de mes espérances par le seul fait de mon manque de connaissance musicale.

En résumé la communication entre RCX est facile les seuls inconscients sont liés au type même du port :

  1. faible portée
  2. liaison en vue directe
  3. Lenteur. Les documentations donnent 5/10 de secondes entre le début de l’émission et l’exécution de l’ordre.

J’ai adopté un minimum de normalisation pour mes applications.

Le reste est fonction de l’application. Mais déjà vous avez un minimum de commandes,

NUMERO DU MESSAGE INTERPRETATION
0 Jamais l’utiliser
1,2,3 Réservé à la télécommande
4 Moteur A AV
5 Moteur A AR
6 Moteur B stop
7 Moteur B AV
8 Moteur B AR
9 Moteur B stop
10 Moteur C AV
11 Moteur C AR
12 Moteur C stop
250 Stop arret d’urgence
251 Message reçu
252 Ordre exécuté (si attente de fin d’exécution)
253 Fin de message
254 Fin de transmission

4 - LES COMMUNICATIONS AVANCEES

Le problème se corse si vous avez plus d’un RCX. 2 personnes qui dialoguent, le message n’a qu’un récepteur.
A 10 c’est de la cacophonie. L’architecture devient une architecture maître esclave. Je préfère l’image chef d’orchestre et musiciens. En tout il y a un RCX qui gère les communications. En NQC au-delà de 10 esclaves je pense que s’est ingérable cela fait 11 programmes à écrire. Lourd, sauf configuration particulière. On peut imaginer que les RCX esclaves sont juste là comme récepteur, le maître agissant comme une télécommande.

Dans tous les autres cas le programme est différent pour chaque RCX, même si seules quelques valeurs change.

Prenons pour exemple grogneugneu enjambeur :

6 RCX musicien et le chef d’orchestre. Encore 4 RCX ont la même fonction et les 2 autres aussi.

J’ai donc 4 pieds moteurs et 2 pieds porteurs uniquement. 3 programmes sont nécessaires, seules 3 constantes différencient les programmes similaires.

Dans ce type, l’application est une application simple on peut diviser les messages an 3 catégories :

  1. les messages publics (s’adresse à tous les récepteurs )
  2. les messages particuliers (n’intéresse qu’un RCX ou groupe de RCX doivent être ignorés des autres)
  3. Le transfert de données. (type de message particulier)

La tache de gestion des messages devient un imbroglio de ’if’, directement proportionel au nombre de RCX. Voyons comment s’organise la gestion des messages.

  1. les messages publics ont la même forme que dans le cas précédent a ceci près qu’un nombre de message équivalent au nombre de RCX deviennent des adresses et indique à quel RCX il s’adresse.
  2. Les messages privés commencent toujours par un message public. A la réception de ce message public les RCX non concernés mettent la fonction de traduction des messages en sommeil, jusqu’à la réception du message « fin de transmission. Le RCX concerné par ce message utilise une nouvelle table de traduction. Et le dialogue devient un dialogue entre deux RCX. Ce type de message peut servir à :
    • forcer le sous ensemble ’commande’ par le RCX à exécuter une séquence particulière
    • transmettre des informations (position d’un capteur, valeur d’une variable.).

c’est pour ce type de message que la distinction entre ’fin de message’ et ’fin de transmission’ a été introduite dans le protocole précédent. c’est l’équivalent de ’fin de ligne’ et de ’retour chariot’ des imprimantes.
Tant que le message ’fin de transmission’ n’est pas émis les autres RCX restent sourds. En fait, ils reçoivent les messages mais ne les interprètent pas. Une transmission particulière pouvant durer plusieurs secondes, pendant lesquelles aucun message ne peut être émis, il est conseillé de suspendre toutes les taches en particulier les taches de mouvement.

5 - UN PROTOCOLE ETENDU

Pour le protocole public il reprend les valeurs du protocole du chapitre 3

PROTOCOLE PUBLIC
20 à 29 Adresse de message particulier (0 pour le maître)
PROTOCOLE PRIVE
DE 48 à 57 Chiffres de 0 à 9
DE 65 à 90 Lettres de A à Z
251 Message reçu
252 Ordre exécuté (si attente de fin d’exécution)
253 Fin de message
254 Fin de transmission

J’ai conservé les références du protocole public pour les ordres généraux. Mais chacun est libre en fonction de ses besoins. Pour une question de facilité j’ai utilisé le code ASCII pour les chiffres et les lettres.

6 - EXEMPLE D’UTILISATION

dialogue R2D2 <-> C3PO

int messager ;
task main()          
{
while (true)
{
  messager = Random (254);
 SendMessage(messager);
 ClearMessage();
   until (Message() != 0);
 PlayTone(Message(),10);
 PlayTone(Message()-10,10);
 }
}

Entrez ce programme dans les 2 RCX et lancez l’execution.

ESSAIS DE TRANSMISSION

task main()          // ESCLAVE{
while (true)
{
   ClearMessage();
   until (Message() != 0);
   PlaySound (SOUND_UP);
 }
}

task main()          // MASTER
{
while (true)
{
 SendMessage(11);
   Wait (100) ;
 }
}

Chargez les programmes dans les 2 RCX et baladez vous. Vous aurez rapidemet la forme du volume de réception.

Exemple de message pour RCX exclave avec gestion de messages privés.

// programme pour le RCX 1

int TextMessage;
int Particulier;
int NomduRCX = 21 //    definition de la constante nom du RCX permet  d'ecrire le meme programme dans certain cas
task main()          // MASTER
{
    start VeilleMessage ;
  // corps du programme


}
task VeilleMessage ()
{
 ClearMessage();
   until (Message() != 0);
   TextMessage = Message();
   ClearMessage();
   if (Particulier == 0){interpretation()}; // message public
   if (Particulier ==1) {SommeilTraduction(); // Message Prive ne concernant pas le RCX
   if (Particulier ==2) {interpertationPrivée}; // message privé
}
void SommeilTraduction()
{
    if (TextMessage == 254 ){Particulier = 0); // attend la fin du message privé
}
void InterpretationPrivée ()
{
 // serie d'if pour l'interpretaton du message suivant protocole
 if (TextMessage == 254) { Particulier = 0 }; //Fin du message privé
}


void interpretation ()

{
    if (TextMessage == 1)       // message telecommnade
   {
      ²"code"
   }
   if (TextMessage == 2)
   {
     "code"
   }
   if (TextMessage == 3)
   {
     "Code"
   }
    if (TextMessage == 4)  // commande directe moteur A
   {
     OnFwd (OUT_A);
   }
   if (TextMessage == 5)
   {
     OnFwd (OUT_A);
   }
   if (TextMessage == 6)
   {
     Off (OUT_A);

   }
   if (TextMessage == 7)    // commande directe a moteur B
   {
     OnFwd (OUT_B);

   }
 if (TextMessage == 8)
   {
     OnRev (OUT_B);
   }
   if (TextMessage == 9)
   {
     Off (OUT_B);

   }
   if (TextMessage == 10)
   {
     "statements"
   }
   if (TextMessage == 11)
   {
     "statements"
   }
   if (TextMessage == 12)
   {
     "statements"
   }
   if (TextMessage == 13)
   {
     "statements"
   }
     if (TextMessage == NomduRCX)            // message particulier pour le rcx 1
   {
     Particulier = 1
   }
     if (TextMessage == 22)            // message particulier pour le rcx 2
   {
     Particulier = 2
   }
 }
 
}

Cet exemple est juste por vous donnez une idée de la maniere dont on peut gerer les messages dans le cas où 3 ou 4 rcx doivent communiquer.

La variable Particulier est un drapeau à 3 positions :
- 0 = valeur par defaut le rcx est dans la position d’interpretation des message public. appel de la fonction Interpretation
- 2 = le RCX est dans la position message privé en cours ne le concernant pas. il attend le message ’FIN de MESSAGE’
- 1 = Le RCX traite un message privé le concernant. il dialogue avec l’autre RCX.

Notez que n’importe quel RCX peut dialoguer en privé avec lui.
Le message ’Fin de transmission’ peut :
- Etre de son initiative
- A l’initiative du l’autre RCX. Dans ce cas, il met la variable Particulier à 0 apres la commande SEND

7 - CONCLUSIONS

Faire dialoguer réellement plus de 2 RCX est faisable en NQC. Lourd à gérer si l’application est tant soit peut évoluée.

En C et C++, ainsi qu ‘en LeJOS, les bibliothèques et paquetages offrent plus de possibilité, en particulier dans les communications RCX <-> BASE. Ce langage offre aussi d’autres possibilités, en particulier la possibilité de sauvegarder des valeurs dans une zone mémoire non volatile ; ce qui permet d’arrêter les programmes et même le RCX, et de recuperer les valeurs au redémarrage. Intéressant pour sauvegarder la position ou la configuration du robot. En outre LeJOS grâce à son paquetage vector permet de mémoriser un cheminement sous forme de vecteurs.

Navigation

AgendaTous les événements

avril 2024 :

Rien pour ce mois

mars 2024 | mai 2024

Brèves Toutes les brèves