Capteurs LEGO : Test et programmation NXC

vendredi 11 décembre 2009
par  Benoit PARSY
popularité : 34%

Après la série d’articles sur les capteurs tierce partie, j’ai eu envie de faire le tour des capteurs de la gamme LEGO Mindstorms (l’ancienne RCX et la nouvelle NXT), et de proposer des bouts de code NXC pour les exploiter avec les briques NXT.

Bricxcc et NXC, installation

BricxCC (Bricx Command Center) est un environnement de développement sous Windows (et avec un peu de bricolage sous MAC OS X), qui permet de programmer les briques NXT dans un langage proche du C, le NXC (Not eXactly C).

Pour l’installer, il vous faut la dernière version en date de Bricxcc. Téléchargez aussi la dernière mise à jour de Bricxcc.

Cette dernière mise à jour contient une version du firmware optimisé pour tirer partie des avancées du langage NXC (tableau multidimensionnels, parallélisation de l’exécution du code, mathématiques avancées).

Pour communiquer avec la brique NXT, et si vous n’avez pas installé le programme fourni par LEGO, il vous faudra installer le driver NXT 1.02. De la documentation est disponible, les "developer kit" sont très instructifs, LEGO ayant fait le choix de l’open source, beaucoup d’informations utiles sont dispersées tout au long des documents.

Installation

  • exécutable bricxcc pour installer bricxcc
  • archive de mise à jour à décompresser, puis "copier/coller" sur le répertoire de l’installation de bricxcc.
  • driver NXT connectez le NXT directement via l’USB, s’il est n’est pas reconnu, installez le driver.

Pour vérifier que tout est en place, télécharger le firmware optimisé dans le NXT, si c’est bon, vous avez fini, sinon, lisez la documentation très bien faite de bricxcc (en anglais), et recommencez l’installation.

Cable de conversion RCX <-> NXT

Clavier

Le NXT a 4 boutons en face avant.

PNG - 17.2 ko
NXT - Clavier
BoutonConstantesValeurForme, couleur
BTN1 BTNEXIT 0 Rectangle, gris foncé
BTN2 BTNRIGHT 1 Triangle <, gris clair
BTN3 BTNLEFT 2 Triangle >, gris clair
BTN4 BTNCENTER 3 Carré, orange
NO_OF_BTNS 4
  • ButtonCount(btn, reset) renvoie le nombre de fois que le bouton btn a été appuyé et relâché, depuis que son compteur a été remis à zéro. Si reset est à true, remise à zéro du compteur après lecture.
  • ButtonPressed(btn, reset) renvoie un booléen si le bouton btn est appuyé. Si reset est à true, remise à zéro du compteur après lecture.
  • ReadButtonEx(btn, reset, out pressed, out count) combine les deux fonctions précédentes, et remplie pressed par l’état appuyé, et count par le compteur. Si reset est à true, remise à zéro du compteur après lecture.
  • ButtonPressCount(btn)* renvoie le nombre d’appuis sur le bouton btn.
    • ButtonLongPressCount(btn)* renvoie le nombre d’appuis "longs" sur le bouton btn.
  • ButtonReleaseCount(btn)* renvoie le nombre de relâchés sur le bouton btn.
    • ButtonShortReleaseCount(btn)* renvoie le nombre de relâchés "courts" sur le bouton btn.
    • ButtonLongReleaseCount(btn)* renvoie le nombre de relâchés "longs" sur le bouton btn.

* Pour chacune de ces 5 fonctions, on a la fonction Setxxx qui force le paramètre à une valeur donnée : ainsi SetButtonReleaseCount(btn, value) force le nombre de relachés du bouton btn à value.

  • ButtonState(btn) renvoie l’état du bouton btn, selon la grille suivante :
constantes d’état du boutonValeurÉtat du bouton
BTNSTATE_PRESSED_EV 0x01 appuyé puis relâché
BTNSTATE_SHORT_RELEASED_EV 0x02 relâché court
BTNSTATE_LONG_PRESSED_EV 0x04 appui long
BTNSTATE_LONG_RELEASED_EV 0x08 relâché long
BTNSTATE_PRESSED_STATE 0x80 appuyé
  • SetButtonState(btn, value) force l’état du bouton btn.

Voici un exemple de gestion de menu avancée, avec menu déroulant plein écran, rubriques dynamiques, navigation au clavier et double clic. Ce projet est très impressionnant, il s’agit d’un scanner piloté par NXT, avec sauvegarde dans un fichier de l’image résultante.

Capteurs

Constantes et variables "capteurs" en NXC

Il y a 4 entrées, numérotées en interne 0, 1, 2, et 3. Or elles sont marquées 1, 2, 3, et 4 sur le boitier du NXT. Pour vous aider, des constantes S1, S2, S3, et S4 ont été définies, et désignent les ports tels que labellisés. Les variables SENSOR_1, SENSOR_2, SENSOR_3, et SENSOR_4 ont aussi été définies, et appellent la mesure du capteur.

Comme pour les boutons du clavier, chaque capteur a ses constantes d’état, qui sont constamment remis à jour.

Constantes d’étatétat du capteur
Type Type de capteur
InputMode Mode de traitement de la mesure
RawValue valeur brute de la mesure
NormalizedValue valeur normée
ScaledValue valeur traitée
InvalidData Invalide la donnée traité

Sensor(port) renvoie la valeur traitée du capteur connecté en port (doit être S1..S4). Sensor(S1) est identique à SENSOR_1, les deux lancent la mesure.

SensorType(port) renvoie la valeur du type configuré pour le capteur connecté en port (doit être S1..S4). cf. ci-dessous pour l’explication sur les types.

SensorMode(port) renvoie la valeur du mode configuré pour le capteur connecté en port (doit être S1..S4). cf. ci-dessous pour l’explication sur les modes.

SensorRaw(port) renvoie la valeur brute du capteur connecté en port (doit être S1..S4). Elle évolue dans l’intervalle [0..1023], et est issue de la numérisation sur 10 Bits, à 333 Hz.

SensorNormalized(port) renvoie la valeur normée du capteur connecté en port (doit être S1..S4).

SensorScaled(port) renvoie la valeur traitée du capteur connecté en port (doit être S1..S4). SensorScaled(S1) est identique à Sensor(S1).

SensorInvalid(port) renvoie le booléen de bonne exécution de la mesure du capteur connecté en port (doit être S1..S4).

SensorBoolean(port) renvoie le résultat (0/1) de la conversion booléenne. Une pente peut être définie en utilisant SetSensorMode().

ClearSensor(port) remet à zéro le compteur associés au capteur, configuré pour mesurer des données quantitatives, comme les pas de capteurs de rotation, ou les compteurs d’impulsions.

ResetSensor(port) remet à zéro les données capteur, après un changement de type ou de mode à la volée dans le corps du programme.

Types et Modes "capteurs" en NXC

Les ports d’entrée du NXT sont capables de s’interfacer avec quantité de capteurs, mais c’est le programme qui précise au NXT le Type de capteur connecté. En NXC, il y a 17 types de capteurs reconnus, plus le type "capteur non configuré". SetSensorType() configure le type de capteur, qui peut changer au cours de l’exécution du programme. Mal configurer un type de capteur expose à une mesure erratique, et donc à un comportement erratique du robot.

Type de CapteurCapteur
SENSOR_TYPE_NONE capteur non configuré
SENSOR_TYPE_TOUCH capteur de contact NXT ou RCX
SENSOR_TYPE_TEMPERATURE capteur de température RCX
SENSOR_TYPE_LIGHT capteur de luminosité RCX
SENSOR_TYPE_ROTATION capteur de rotation RCX
SENSOR_TYPE_LIGHT_ACTIVE capteur de luminosité NXT avec source allumée
SENSOR_TYPE_LIGHT_INACTIVE capteur de luminosité NXT avec source éteinte
SENSOR_TYPE_SOUND_DB capteur de niveau sonore NXT en dB
SENSOR_TYPE_SOUND_DBA capteur de niveau sonore NXT en dBA
SENSOR_TYPE_CUSTOM capteur particulier (pas utilisé)
SENSOR_TYPE_LOWSPEED capteur I2C sans source 9V(pin 1 inactive)
SENSOR_TYPE_LOWSPEED_9V capteur I2C avec source 9V(pin 1 active)
SENSOR_TYPE_HIGHSPEED capteur rapide, RS485 (pas utilisé)
SENSOR_TYPE_COLORFULL capteur de couleur-Led blanche
SENSOR_TYPE_COLORRED capteur de couleur-Led rouge
SENSOR_TYPE_COLORGREEN capteur de couleur-Led verte
SENSOR_TYPE_COLORBLUE capteur de couleur-Led bleue
SENSOR_TYPE_COLORNONE capteur de couleur-Led éteinte

SetSensorType(port, const type) configure le type de capteur, port doit être S1..S4, type, l’un de ceux du tableau.

Le Mode précise comment les données brutes (raw value) venant du capteur (dont on a préalablement défini le type...) vont être traitées (processed value). Certains modes n’ont de sens qu’avec certains types de capteurs, ainsi SENSOR_MODE_ROTATION n’est utile qu’avec un capteur de rotation...

Mode de TraitementTraitement
SENSOR_MODE_RAW donnée brute (sur 10 bits) 0 à 1023
SENSOR_MODE_BOOL valeur booléenne (0 ou 1)
SENSOR_MODE_EDGE compte le nombres de transitions booléennes(0 à 1, 1 à 0)
SENSOR_MODE_PULSE compte le nombres de périodes booléennes, pulsations
SENSOR_MODE_PERCENT valeur de 0 à 100
SENSOR_MODE_FAHRENHEIT degrés F
SENSOR_MODE_CELSIUS degrés C
SENSOR_MODE_ROTATION rotation (16 impulsions par rotation)

SetSensorMode(port, const mode) configure le mode de traitement des données provenant du capteur, port doit être S1..S4, mode, l’un de ceux du tableau ci dessus.

Le NXT fournit une conversion booléenne pour tous les capteurs, quelque soit le mode choisi (ex. SENSOR_MODE_PERCENT ). Cette conversion est basée sur une hystérésis. Toute valeur "raw" inférieure à 460 sera vue comme un 1, toute valeur "raw" supérieure à 562 sera traduite par un 0. Une pente [0..31] peut être rajoutée au mode choisi, si la valeur "raw" change plus que ce seuil en 3 ms (333 fois/s), la conversion booléenne change de valeur selon le sens, 0 pour une augmentation, 1 pour une diminution. Cela permet de suivre des phénomènes très rapides.

Le langage NXC permet de définir le type et le mode en même temps, pour les combinaisons standards d’utilisation d’un capteur donné.

CombinaisonType Mode
SENSOR_TOUCH SENSOR_TYPE_TOUCH SENSOR_MODE_BOOL
SENSOR_LIGHT SENSOR_TYPE_LIGHT SENSOR_MODE_PERCENT
SENSOR_ROTATION SENSOR_TYPE_ROTATION SENSOR_MODE_ROTATION
SENSOR_CELSIUS SENSOR_TYPE_TEMPERATURE SENSOR_MODE_CELSIUS
SENSOR_FAHRENHEIT SENSOR_TYPE_TEMPERATURE SENSOR_MODE_FAHRENHEIT
SENSOR_PULSE SENSOR_TYPE_TOUCH SENSOR_MODE_PULSE
SENSOR_EDGE SENSOR_TYPE_TOUCH SENSOR_MODE_EDGE

SetSensor(port, configuration) permet de définir la configuration (type/mode) d’un capteur. port doit être S1..S4, configuration l’une des combinaison du tableau ci dessus.

Cable de conversion RCX<->NXT

PNG - 4.4 ko
NXT schéma d’un port d’entrée

Le NXT à une interface d’entrée à six câbles

PinCouleurNomFonction
1 Blanc ANA Entrée analogique, avec résistance de tirage (10K) ou Source de tension (I2C) 9V
2 Noir GND Masse analogique
3 Rouge GND Masse numérique
4 Vert IPOWERA/Vcc Source de tension (I2C) 4,3V
5 Jaune DIGI0/CLK Ligne Horloge I2C
6 Bleu DIGI1/DATA Ligne Données I2C

Schéma du câble de conversion Pour pouvoir utiliser des capteurs initialement développer pour le RCX (pour rappel, interface 2 fils, protégée des inversions par pont de diode, mesure et alimentation véhiculées par les mêmes fils), l’astuce consiste à connecter les pins 1 et 2 du NXT, avec les deux conducteurs du câble RCX. Pour lire la valeur du capteur, il faut faire appel à des fonctions déclenchant la numérisation du port (sur 10 bits, 333 fois par seconde) , par le microprocesseur du NXT.

Voici une description du mode opératoire de la soudure des câbles, des photos, etc... N’hésitez pas à vous balader sur ce site, c’est une véritable mine d’or, et à questionner Philo, qui, comme son site (en anglais) ne le laisse pas deviner, est français.

LEGO vend ces câbles sous forme de kit de trois , sous la référence 8528

Capteurs NXT

Des fonctions particulières sont définies en NXC pour accéder aux capteurs NXT standards :

PNG - 6.2 ko
NXT - Capteur de contact

Capteur de contact (analogique)

SetSensorTouch(port) configure le port S1..S4 pour recevoir un capteur de contact (RCX ou NXT).

PNG - 5.9 ko
NXT - Capteur de luminosité

Capteur de luminosité (analogique)

SetSensorLight(port) configure le port S1..S4 pour recevoir un capteur de luminosité (source de lumière active).

PNG - 8.6 ko
NXT - Capteur de niveau sonore

Capteur de niveau sonore (analogique)

Ce capteur est un capteur d’amplitude sonore, il délivre le niveau de bruit ambiant. Vous trouverez des informations intéressantes sur ce capteur], des projets de têtes chercheuses de sons, et auto directrices notamment. Ce capteur pourrait faire bien plus, car son connecteur arrière ressort le flux capturé par le micro, amplifié en pin 6. Or les pins 6 (DIGIAI1) des ports d’entrées pourraient être configurées pour faire de la capture de signaux analogique à 8000 Hz, et donc être capable de fournir après traitement du signal, les fréquences et les puissances, et donc ouvrir la voie à la reconnaissance vocale sur NXT... mais il faudrait un firmware spécialement écrit pour ouvrir cette possibilité, et je n’en ai pas les compétences. Plus d’informations

SetSensorSound(port) configure le port S1..S4 pour recevoir un capteur de niveau sonore (dB).

PNG - 6.5 ko
NXT - Capteur colorimétrique

Capteur de couleur (analogique)

Le capteur de couleur est assez particulier, il enferme une led RGB qui peut être commandée, et un capteur de couleur. Pour reproduire le comportement du capteur sous l’environnement de programmation LEGO, le capteur peut distinguer 6 couleurs, dont la valeur est normée selon la table suivante :

ConstanteValeurCouleur détectée
INPUT_BLACKCOLOR 1 Noir
INPUT_BLUECOLOR 2 Bleu
INPUT_GREENCOLOR 3 Vert
INPUT_YELLOWCOLOR 4 Jaune
INPUT_REDCOLOR 5 Rouge
INPUT_WHITECOLOR 6 Blanc

SetSensor(port, SENSORCOLORxxx) permet d’initialiser le capteur, et de commander la LED RGB.

Pour aller plus loin, NXC fournit la procédure ReadSensorColorEx(port, colorval, raw, norm, scaled), fournit la couleur détectée, ainsi que les composantes RGB "raw" (brutes) et "norm" (normées) de la couleur réellement détectée. Cela permet une plus grande plage d’utilisation du capteur. Cependant, pour utiliser la procédure ReadSensorColorEx(), il faut utiliser des tableaux de variables, selon la structure suivante

Constanteindex du tableau
INPUT_RED 0
INPUT_GREEN 1
INPUT_BLUE 2
INPUT_BLANK 3

Voici un exemple de code pour utiliser le capteur :

Ce capteur a été comparé à celui developpé par HiTechnic, dans un très bon article de Philo.

PNG - 7 ko
NXT - Télémètre à ultrasons

Télémètre à ultrason (I2C)

Comme le télémètre à ultrason est un capteur I2C, sa valeur ne peut être lue par l’intermédiaire de la procédure standard Sensor(port). Pour initialiser le port en mode I2C, il faut préalablement à la mesure, utiliser SetSensorLowspeed(port). Utiliser ensuite SensorUS(port) adresse le port S1..S4 pour recevoir la donnée provenant le télémètre, i.e. la distance à l’obstacle en cm.

JPEG - 19.1 ko Les capteurs ultrasoniques sont vraiment très pratiques, quand on en connait les inconvénients. La distance effectivement mesurable est limitée, en éloignement car la déperdition de puissance de l’onde dans l’air est importante, ce qui limite pratiquement la portée du capteur. Elle est limitée aussi en proximité, car il faut "protéger" le récepteur de l’émission de l’onde, et donc la mesure ne peut se faire qu’après un certain temps, or le temps dans le cas présent, c’est une distance... De plus, les ondes émises sont sensibles à la géométrie, la densité et l’état de surface de l’obstacle. Elles ricochent, ou se perdent, ou reviennent plusieurs fois (multi-trajets).

Une des limitations du capteur LEGO vient que par défaut, il émet en continu, et ne peut pas directement être commander en "ping" (choix du moment de la mesure), l’autre est que l’accés aux 7 autres mesures (car le capteur fait jusqu’à 8 mesures de l’écho) ne sont pas elles aussi disponibles. il y a là du code pour accéder aux registres I2C à faire pour exploiter à son maximum le capteur. Le fait que l’on ne puisse pas déterminer le moment de la mesure peut être génant si l’on utilise plusieurs capteurs Ultrasoniques (phénomène de cross-talk). Des expérimentations et du codage donc... On en parle là, la documentation du protocole I2C du capteur est disponible en appendice 7 du Hardware dev kit.

PNG - 7.2 ko
NXT - Capteur de température

Capteur de température (I2C)

Le nouveau capteur de température corrige les défauts de l’ancienne version, à savoir :

    • Interface I2C, sans artefact de mesure,
    • un câble long de 50cm, scellé au capteur, pour éviter les problèmes du à la proximité de liquides,
    • Sonde de température en métal, étanche et blindée, autorisant l’immersion de la sonde (pas du capteur...)
    • Meilleure résolution (12 bits), donnant une résolution maxi de 0,0625°C,
    • Meilleure plage de mesure (-40 à 125 °C, mais LEGO recommande -20 à 110 °C), permettant de mesurer la température de l’eau bouillante.

Il n’existe pas d’API spécifique (encore) sous NXC pour ce capteur, il faut donc écrire le code qui permet d’accéder aux registres I2C du capteur. En voici un exemple, par John Hansen, qui donne la température *10, pour simuler la décimale. Discussions et codes autour de ce capteur sur le forum nxtasy.org

Capteurs RCX

Les capteurs RCX doivent être connectés via le câble de conversion à la brique NXT. Ils sont donc vus par le NXT comme des capteurs analogiques, et ne bénéficient pas tous de procédures spécifiques, mais ont des modes et des types associés, facilitant leur exploitation.

PNG - 8 ko
RCX - Capteur de contact

Capteur de contact (analogique)

SetSensorTouch(port) configure le port S1..S4 pour recevoir un capteur de contact (RCX ou NXT).

PNG - 14.3 ko
RCX - Capteur de température

Capteur de température (analogique)

SetSensor(port, SENSOR_CELSIUS)

Configure le port S1..S4 pour recevoir un capteur de température RCX, avec mesure convertie en degré Celsius.

PNG - 7.2 ko
RCX - Capteur de luminosité

Capteur de luminosité (analogique)

Ce capteur est utile pour détecter la présence d’obstacles, la résolution de labyrinthes par suivi de murs, mesurer la garde au sol de robots équilibristes, ou "lire" le sol, pour le suivi de lignes ou du ring pour les robots SUMO, ou déterminer la "couleur" de plates pour la commande par bandes (RFID préhistorique ???).

SetSensorType(port, SENSOR_TYPE_LIGHT) configure le port S1..S4 pour recevoir un capteur de luminosité RCX (source de lumière active). Ne pas oublier d’utiliser SetSensorMode(port, SENSOR_MODE_PERCENT) pour configurer le mode (ici %).

PNG - 8 ko
RCX - Capteur de rotation

>Capteur de rotation (analogique)

Ce capteur est très utile, pour l’odométrie, comme pour le suivi de consignes moteurs. Il est basé sur un disque rompant un faisceau, et donc est très facile à mouvoir, contrairement au servomoteur NXT qui embarquent lui aussi un encodeur, mais dont le déplacement est contrarié par le moteur. Les précisons sont aussi différentes, le capteur de rotation RCX compte 16 pas par tour, (soit une précision de 22,6°), alors que le servomoteur renvoi une information précise au degré près. Cependant, plus de pas par rotation peuvent être obtenus en jouant sur les rapports d’engrenage, au détriment de la facilité de mise en rotation (par frottement).

SetSensor(port, SENSOR_ROTATION) Configure le port S1..S4 pour recevoir un capteur de rotation, selon la configuration ad-hoc (16 pas par rotation). Il faut veiller à remettre à zéro le compteur au début de séquences de déplacement, grace à ClearSensor(port). Un exemple de code bien connu est le rattrapage de commandes moteur pour faire "aller droit" un robot (très basique, mais ça fonctionne et c’est facile à comprendre !).

On peut aussi faire des choses plus exotiques, comme permettre à une télécommande Power-Functions de donner des ordres à un NXT...


Voilà, encore un article sur les capteurs diront les chagrins, bientôt son jumeaux chez les actionneurs diront les optimistes. Espérant avoir été utile, je reste à votre disposition pour toute remarque ou question.


Commentaires  (fermé)

Logo de ericnc
vendredi 3 mai 2013 à 12h57 - par  ericnc

Super...sauf que je ne connais pas le c..mais je suis sur enchanting, plus facile pour les élèves de college. Bravo pour ce boulot... je cherchais des infos sur le capteur de couleur nxt que je n’arrive pas a utiliser avec enchanting... si tu as des infos...
Perso je vais surement passer au c, grâce à ton article :)
Merci

Logo de EL ouardi
mercredi 30 mai 2012 à 00h46 - par  EL ouardi

C’est un trés bon travail, merci beaucoup

Logo de Gmi_Gilles
mardi 15 décembre 2009 à 17h11 - par  Gmi_Gilles

Merci pour ce bel article que je n’ai pas lu dans le détail.

Mais quand j’en aurais besoin je saurais ou chercher ;-)

bye

Brèves

29 juillet 2011 - Mise à jour des pièces LDraw 2011-01

La première mise à jour des pièces LDraw pour 2011 est désormais disponible ! Au sommaire, 486 (...)

28 mars 2011 - Reportage sur la chaine de fabrication LEGO

Un reportage de National Geographic sur la compagnie LEGO, et plus particulièrement sur la (...)

23 février 2011 - Pierre Normandin présente le nouveau train LEGO Maersk 10219 en vidéo

Notre ami Pierre Normandin, designer LEGO CITY, présente dans cette vidéo le nouveau train LEGO (...)

31 décembre 2010 - Mise à jour des pièces LDraw 2010-03

Une nouvelle mise à jour des pièces officielles LDraw est disponible ! Au sommaire, 456 nouveaux (...)

21 juillet 2010 - Nouveau magazine LEGO dans les kiosques

Nouveauté dans les kiosques, le magazine LEGO n°01 vient de sortir. Au sommaire, pas grand (...)