Mon premier programme en NXC
Table des matières
Préambule
Ce tutoriel s’adresse à tous les mordus de LEGO qui voudraient bien rendre leurs constructions « intelligentes ». Nous allons ainsi apprendre ensemble les bases de la programmation. Nous allons nous servir de ces bases pour créer un petit programme basique qui vous permettra de télécommander votre robot. Il y aura deux capteurs qui pourront activer deux moteurs. D’ailleurs, n’hésitez pas à vous construire une télécommande. A vous après de découvrir plus en détails les possibilités qui vous sont offertes, sachez en tout cas qu’elles sont sans limite !
Le langage que nous utiliserons est le NXC : Not eXactly C. Il s’agit d’un langage dont la syntaxe ressemble à celle du langage C. Les amateurs du C n’auront donc pas de mal à s’adapter. Le langage NXC fut développé exprès pour la programmation sur NXT.
Matériel nécessaire
- Un NXT avec deux moteurs et deux capteurs de contact
- Un ordinateur avec les droits administrateur
- Un câble de transfert entre l’ordinateur et le NXT
- Le logiciel Bricx Commander Center
Et bien sûr, n’oubliez pas votre tête et vos deux mains
Le logiciel Bricx Commander Center
Ce logiciel vous servira pour éditer vos programmes, les charger dans le NXT ainsi que d’autres fonctionnalités telles qu’obtenir des informations sur le NXT, effectuer des actions à distance, … Rendez vous sur le site officiel, téléchargez le logiciel, installez-le et lancer-le, vous atterrissez ainsi sur une fenêtre de connexion à votre NXT.
Connectez votre NXT à votre ordinateur, sélectionnez le port de connexion et le type de votre brique intelligente puis cliquez sur OK. Si vous ne pouvez pas brancher votre NXT, cliquez sur Cancel si vous désirez accéder au logiciel sans connecter votre NXT.
Les principales fonctionnalités :
- Compiler et charger le programme : Compile et Download disponible dans le menu Compile
- Lancer le programme et l’arrêter : Run et Stop disponible dans le menu Compile
- Contrôler la brique à distance : Remote disponible dans le menu Tools
- Chercher et connecter la brique : Find brick disponible dans le menu Tools
- Charger le micro programme de la brique : Download firmware disponible dans le menu Tools
Preparer votre ordinateur et votre NXT
Votre ordinateur
Pour que votre ordinateur puisse communiquer avec votre brique intelligente, il faut que vous installiez le driver disponible sur la page du support du site officiel LEGO. Sachez que si vous avez déjà installé le logiciel disponible sur le CD fourni avec votre NXT, le driver est déjà installé et vous pouvez donc sauter cette partie. Sinon, rendez-vous sur la page de téléchargement des drivers.
Votre NXT
Avant de commencer à réaliser votre premier programme, il vous faut d’abord charger sur votre NXT un nouveau micro-programme qui saura faire fonctionner vos futurs programmes en NXC.
Commencez par le télécharger puis charger le sur votre NXT. Il vous suffit pour cela de le connecter à votre ordinateur, de vous rendre sur Bricx Commander Center, d’accéder à l’option Download firmware dans le menu Tools puis de spécifier le firmware à charger.
Si jamais vous désirez remettre le micro-programme LEGO, télécharger-le depuis la page de téléchargement sur le site LEGO puis chargez-le sur votre NXT.
Le programme
Ouvrez le logiciel Brixc Commander Center et créez un nouveau programme, menu File et option New.
Quelques notions
Les instructions
Une grande partie d’un programme est composé d’instructions, par exemple : « attendre 200ms », « allumer le moteur 1 », « attendre que le capteur 2 soit appuyé », … Chaque instruction doit finir par un point virgule. Exemple :
instruction;
Le NXT qui aura lancer votre programme exécutera l’une après l’autre toutes ses instructions. Les principales instructions que vous utiliserez seront l’appel de fonction et l’affectation de variables, ce que nous verrons par la suite.
Les commentaires
Sachez qu’il y a un moyen très simple de ne pas vous perdre dans un programme : les commentaires. C’est du texte que vous pouvez mettre n’importe où et qui n’auront pas d’incidence sur le fonctionnement du programme. Ils servent par exemple à décrire le fonctionnement d’une partie de votre programme pour que quelqu’un d’autre (ou bien vous même dans plusieurs mois/années) passe moins de temps à comprendre votre programme. Exemple de commentaire :
instruction; // Commentaire jusqu'à la fin de la ligne instruction; /* Commentaire qui commence ici et fini la */ instruction;
Les variables
Les variables sont un des éléments essentiels dans un programme, c’est grâce à elles que vous pourrez manipuler des données. Une variable est composé de trois éléments :
- Son type (un nombre ? un caractère ? …)
- Son nom (qui permet d’accéder à son contenu)
- Son contenu (qui contient la donnée)
Le nom d’une variable doit être court et clair. Il est uniquement composé de lettres et de chiffres et doit forcement commencé par une lettre. Préférence de programmation : commencez toutes vos variables par une lettre minuscule et si le nom de la variable est composé, chaque mot commence par une majuscule (excepté le premier bien sûr), exemple : maVariable
Liste des types d’une variable :
- bool : booléen (true ou false)
- int : nombre entier (23, 45, …)
- float : nombre à virgule (12.6, 98.5, …)
- char : caractère (g, r, …)
Pour déclarer une variable, il suffit d’écrire :
typeDeLaVariable nomDeLaVariable;
Exemple de déclaration :
// Déclaration de la variable nombreA, c'est un entier int nombreA; // Déclaration de la variable nombreB, c'est un entier int nombreB; // Déclaration de la variable resultat, c'est un entier int resultat;
Pour manipuler ces variables, nous avons à notre disposition une instruction : l’affectation. Elle se met en place à l’aide du symbole égale, à sa gauche la variable affectée et à sa droite la valeur. Si une variable est placée à droite du égale alors c’est sa valeur qui sera pris en compte. Exemple en continuité avec l’exemple précédant :
// La valeur 12 est affecté à la variable nombreA nombreA = 12; // La valeur 8 est affecté à la variable nombreB nombreB = 8; // La variable resultat prendre pour valeur la somme de la valeur de nombreA et de nombreB resultat = nombreA + nombreB;
Les fonctions
En C, et donc en NXC, un programme marche notamment grâce aux fonctions. Une fonction est un traitement qui peut être paramétré et qui peut renvoyer une donnée. Déclaration d’une fonction :
typeDeLaDonneeRetournee fonction(type parametreA, type parametreB) { // Liste d'instructions }
Si une fonction ne retourne rien, on utilise le mot clé void, exemple :
void fonction(type parametreA, type parametreB) { // Liste d'instructions }
Un exemple ? Si vous demandez à votre robot d’effectué une trajectoire, les paramètres de la fonction qui exécute ce traitement pourraient être le point à rejoindre ainsi que la vitesse et la donnée retournée par la fonction pourrait être le nombre de cm parcourus. Exemple de fonction :
/* Cette fonction prend en paramètre deux paramètres : - a : c'est un entier - b : c'est un entier La fonction va faire la somme de ces entier et retourner le résultat */ int somme(int a, int b) { // Déclaration de la variable resultat, c'est un entier int resultat; // Affecter le résultat de la somme des variables a et b dans la variable resultat resultat = a + b; // Retourner le résultat à l'instruction qui à appelé la fonction return resultat; }
Une fonction c’est bien jolie mais si on ne s’en sert pas, ca ne sert à rien. Nous en arrivons donc à l’appel de fonction, exemple :
// Déclaration de la variable résultat, c'est un entier int resultat; // Affectation de la valeur retournée par la fonction dans la variable resultat resultat = somme(2,4);
Sachez qu’une fonction doit être déclarée avant son appel. Une fonction a la particularité de bloquer le NXT pendant le temps d’exécution des instructions de la fonction appelée. Exemple :
// Le NXT va faire un appel de fonction et va exécuter ses instructions x = equation2ndDegre(5,6,1); // Le NXT ne passera pas à la suite tant qu'il n'aura pas fini d'exécuter les instructions de la fonction
Heureusement pour nous, des fonctions déjà déclarée existent. En voici une liste qui devrait nous servir :
// Mise en marche d'un moteur dans un sens OnRev(nomDuMoteur,vitesse); // mise en marche d'un moteur dans l'autre sens OnFwd(nomDuMoteur,vitesse); // Arrêt brutal d'un moteur Off(nomDuMoteur,vitesse); // Arrêt en douceur d'un moteur Float(nomDuMoteur,vitesse); // Attendre pendant un certain défini en ms Wait(ms);
Les tâches
A la différence des fonctions, une tâche ne retourne aucune donnée et s’exécute en parallèle de la tâche ou fonction appelante. Grâce à ces tâches, on peut facilement exécuter des instructions qui concernent différente parties de votre robot. Déclaration d’une tâche :
task tache(type parametreA, type parametreB) { // Liste d'instructions }
De même que pour une fonction, il faut pouvoir appeler une tâche si on veut qu’elle serve à quelque chose. A vrai dire, une tâche ne s’appelle pas comme une fonction, elle se démarre :
// Lancement de la tache start tache; // Le NXT lance la tâche et n'attend pas d'avoir fini ses instructions pour continuer
Les conditions
Un programme doit pouvoir réagir différemment en fonction de certaines données, c’est pourquoi les conditions existent. Elles permettent au programme d’exécuter certaines instructions plutôt que d’autres en fonction de valeurs. Le résultat d’une condition est booléen, c’est à dire une condition est soit vrai soit fausse. Par exemple, on peut mettre en place le raisonement suivant : si la condition « il pleut » est vrai, on pourrait exécuter l’instruction « courir s’abriter » ou bien « sortir son parapluie ». La première structure que vous devez connaître pour manipuler les conditions est le if (si en anglais), qui peut être couplé à else (sinon en anglais).
If :
if(condition) { // Si la condition est vrai alors ... instruction; // ... on exécute l'instruction }
If et Else :
if(condition) { // Si la condition est vrai alors ... instructionA; // ... on exécute l'instruction A } else { // Sinon ... instructionB; // ... on exécute l'instruction B }
Exemple :
if(variableA == variableB) { // Si la valeur de variableA égale la valeur de variableB alors ... instructionA; // ... on exécute l'instruction A } else { // Sinon ... instructionB; // ... on exécute l'instruction B }
Opérateurs de comparaison :
- == : égale à ?
- != : différent de ?
- > : supérieur à ?
- < : inférieur à ?
- >= : supérieur ou égale à ?
- <= : inférieur ou égale à ?
Afin de pouvoir faire des conditions un peu plus complexes, nous avons notre disposition des opérateurs booléens qui permettent d’associer plusieurs conditions. Exemple :
// Si variableA est égale à variableB ou si variableC est inférieur à variableD ... if(variableA == variableB || variableC < variableD) { instruction; // ... on exécute l'instruction }
Opérateur booléens :
- && : et
- || : ou
Les boucles
Les boucles sont un autre moyen d’utiliser les conditions. On les appelle boucle car on peur faire « boucler » le NXT sur plusieurs instructions. La seule boucle que nous verrons sera la boucle while (tant que en anglais), à vous de voir toutes les autres boucles qui existent. La boucle while :
while(condition) { // Tant que la condition est vrai ... instruction // ... on exécute l'instruction }
Déclaration des moteurs
Pour utiliser un moteur il vous faut d’abord le déclarer et ceci se fera simplement en écrivant en haut de votre programme. Déclaration d’un moteur :
#define description OUT_N
Où N est le numéro de la sortie correspondante au moteur désiré. Exemple de déclaration de moteurs :
#define moteurGauche OUT_A #define moteurDroite OUT_B
Déclaration des capteurs
De la même manière que pour les moteurs, il faut déclarer les capteurs pour pouvoir les utiliser avec facilité :
#define description SENSOR_N
Où N est le numéro de l’entrée correspondante au capteur. Exemple de déclaration de capteurs :
#define capteurContact1 SENSOR_1 #define capteurContact2 SENSOR_2
Les capteurs ne sont pas encore utilisables, il faut les définir comme capteur de contact. Pour cela, il faut utiliser la fonction déjà définie SetSensor() dans la tâche main que nous verrons après, exemple :
// On déclare les capteurs sur les entrées 1 et 2 comme capteur de contact SetSensor(IN_1, SENSOR_TOUCH); SetSensor(IN_2, SENSOR_TOUCH);
La tâche main()
La tâche la plus importante est la tâche main (en anglais principal), il s’agit de la tâche appelée lors du lancement du programme. Exemple de main :
task main() { // Liste d'instructions }
On réutilise tout se qu’on a vu
Et voilà, vous devriez en savoir assez pour faire le programme dont nous avions parlé au début du tutoriel permettant télécommander un robot à deux roues. Aller, je ne vous laisse pas dans la nature comme ca, voici le fameux programme à charger sur votre NXT :
// Définition des moteurs #define moteurGauche OUT_A #define moteurDroite OUT_B // Définition des capteurs #define capteurGauche SENSOR_1 #define capteurDroite SENSOR_2 task main() { // On déclare les capteurs sur les entrées 1 et 2 comme capteur de contact SetSensor(IN_1, SENSOR_TOUCH); SetSensor(IN_2, SENSOR_TOUCH); // Déclaration de variables qui définissent si un moteur est bien activé bool etatMoteurG; bool etatMoteurD; // Par défaut les moteurs ne sont pas activé etatMoteurG = false; etatMoteurD = false; // On boucle toujours while(true) { // Si on appuie sur le capteur et que le moteur n'est pas allume if(!capteurGauche && etatMoteurG) { OnFwd(moteurGauche); // On allume le moteur etatMoteurG = true; // On retient dans la variable que le moteur est allume } // Si on appuie pas sur le capteur et que le moteur est allume if(capteurGauche && !etatMoteurG) { Float(moteurGauche); // On éteint le moteur etatMoteurG = false; // On retient dans la variable que le moteur est éteint } // Si on appuie sur le capteur et que le moteur n'est pas allume if(!capteurDroite && etatMoteurD) { OnFwd(moteurDroite); // On allume le moteur etatMoteurD = true; // On retient dans la variable que le moteur est allume } // Si on appuie pas sur le capteur et que le moteur est allume if(capteurDroite && !etatMoteurD) { Float(moteurDroite); // On éteint le moteur etatMoteurD = false; // On retient dans la variable que le moteur est éteint } } }
Le mot de la fin
J’espère que vous avez apprécié ce tutoriel. Surtout, n’hésitez pas à me poser des questions dans les commentaires de cet article, je suis à votre écoute.
Pour en savoir plus sur la programmation NXC, rendez vous sur le tutoriel de Daniele Benedettelli.