Infoforall

5 - MAKEBLOCK / Télécommande IR

Télécommande et récepteur IR

Nous allons voir un aspect fondamental de la programmation : la possibilité d'insérer des mini-programmes dans les programmes de façon à créer de nouvelles actions. Vous avez déjà utilisé de nombreuses fois les fonctions. Lesquelles ? print est une fonction, input est une fonction. Pourquoi ne pas les avoir affichés en rouge ? Simplement parce qu'il s'agit de fonctions génériques, couramment utilisées. Bien entendu, les deux fonctions les plus visible sont la fonction setup et la fonction loop. Mais nous allons voir aujourd'hui comment créer vos propres fonctions si l'action que vous voulez effectuer n'est pas gérée par l'une des innombrables fonctions ou méthodes de C et d'Arduino.

Et pour les utiliser de façon pratique, nous allons utiliser la télécommande IR (infrarouge) de façon à gérer un robot qui réponds aux ordres complexes qu'on peut lui envoyer, sans trop de lignes de code !

1 - Branchements

Le système de télécommande IR comporte deux éléments :

Principe de la télécommande

Commençons par fournir un programme fonctionnel qui permet d'afficher quelque chose sur votre afficheur digital.

J'utilise donc un objet-afficheur nommé disp de classe Me7SegmentDisplay pour afficher des nombres et un objet capteurIR qui va me permettre de gérer les informations qui parviennent jusq'au capteur infrarouge du robot.

J'ai rajouté les déclarations des objets moteurs (nommés motor3 et motor4), de l'objet ultraSensor de l'émetteur-recepteur ultrasonore. Ils vous serviront plus tard.

Pensez à vérifier la concordance des numéros de ports sur votre robot et la correspondance des couleurs entre l'interface et le port.

#include "MeOrion.h"

#include <SoftwareSerial.h>


Me7SegmentDisplay disp(PORT_4);

MeInfraredReceiver capteurIR(PORT_6);

MeUltrasonicSensor ultraSensor(PORT_7); /* Ultrasonic module can ONLY be connected to port 3, 4, 6, 7, 8 of base shield. */

MeDCMotor motor3(M1);

MeDCMotor motor4(M2);


uint8_t motorSpeed = 100;


void setup()

{

    for (int i=0; i < 5 ; i++) {

        disp.display(i);

        delay(1000);

    }

}


void loop()

{

}

01° Tester le code et vérifier sa validité sur votre robot : avant de lancer la suite, autant savoir si tout fonctionne bien.

02° Compter jusqu'à dix au démarrage puis afficher la distance à l'obstacle perçu par le capteur dans la fonction loop().

...CORRECTION...

#include "MeOrion.h"

#include <SoftwareSerial.h>


Me7SegmentDisplay disp(PORT_4);

MeInfraredReceiver capteurIR(PORT_6);

MeUltrasonicSensor ultraSensor(PORT_7); /* Ultrasonic module can ONLY be connected to port 3, 4, 6, 7, 8 of base shield. */

MeDCMotor motor3(M1);

MeDCMotor motor4(M2);


uint8_t motorSpeed = 100;


void setup()

{

    for (int i=0; i < 11 ; i++) {

        disp.display(i);

        delay(1000);

    }

}


void loop()

{

        disp.display(ultraSensor.distanceCm());

}

03° Finaliser le test : on veut afficher uniquement les cm, pas les mm et on veut que le test ne se fasse qu'une fois par demi-seconde.

...CORRECTION...

#include "MeOrion.h"

#include <SoftwareSerial.h>


Me7SegmentDisplay disp(PORT_4);

MeInfraredReceiver capteurIR(PORT_6);

MeUltrasonicSensor ultraSensor(PORT_7); /* Ultrasonic module can ONLY be connected to port 3, 4, 6, 7, 8 of base shield. */

MeDCMotor motor3(M1);

MeDCMotor motor4(M2);


uint8_t motorSpeed = 100;


void setup()

{

    for (int i=0; i < 11 ; i++) {

        disp.display(i);

        delay(1000);

    }

}


void loop()

{

    int distance = ultraSensor.distanceCm();

    disp.display(distance);

    delay(500);

}

Nous allons maintenant gérer cette télécommande.

2 - Détection : begin et buttonState

Commençons par voir comment détecter que le récepteur reçoit quelque chose.

Premièrement, il faut démarrer la méthode begin sur l'objet qui fait la liaison avec le récepteur IR.

Ensuite, il faut utiliser la méthode buttonState sur votre objet gérant ce même récepteur IR.

Cette méthode renvoie

  • 0 si aucun bouton de télécommande n'est détectée, ou
  • 1 si vous êtes en train d'appuyer sur la télécommande.

04° Utiliser le programme ci-dessous pour vérifier que l'afficheur digital passe bien à 1 lorsqu'on détecte que vous appuyez sur l'un des boutons de votre télécommande.

#include "MeOrion.h"

#include <SoftwareSerial.h>


Me7SegmentDisplay disp(PORT_4);

MeInfraredReceiver capteurIR(PORT_6);

MeUltrasonicSensor ultraSensor(PORT_7); /* Ultrasonic module can ONLY be connected to port 3, 4, 6, 7, 8 of base shield. */

MeDCMotor motor3(M1);

MeDCMotor motor4(M2);


uint8_t motorSpeed = 100;


void setup()

{

    capteurIR.begin();

}


void loop()

{

    disp.display(capteurIR.buttonState());

}

Bien. Nous détectons l'appui sur les touches. Reste à voir comment les différencier.

3 - Lecture : read et available

Pour cela, nous allons avoir besoin d'utiliser la méthode read sur l'objet lié au récepteur IR : cette méthode va vous renvoyer les informations reçues par le récepteur.

Le problème est que nous risquons de créer des erreurs s'il n'y a rien à lire. Nous pouvons alors utiliser la méthode available qui renvoie le nombre de codes-touches enregistrés en mémoire mais non lus. S'il est positif, c'est qu'il y a quelque chose à lire.

ASTUCE : on peut utiliser le résultat de cette méthode pour faire un test VRAI / FAUX sur le contenu mémoire du capteur :

  • Si la mémoire ne contient rien, la méthode available renvoie 0 ce qui sera compris comme FALSE par un test if ( capteurIR.available() ).
  • Si la mémoire contient quelque chose, la méthode available renvoie le nombre d'octet contenu dans la mémoire, ce qui sera compris comme TRUE par un test if ( capteurIR.available() ).

Retenez que dans la plupart des langages, FALSE est codé par 0 et tous le reste correspond à TRUE. En gros, si une réponse ne renvoie pas 0, l'ordinateur comprendra TRUE si vous lui demandez de faire un choix binaire OUI/NON.

05° Utiliser ce programme ci-dessous pour trouver les codes correspondant aux différentes touches de votre télécommande. On affiche les codes reçus sur la console de l'interface Arduino. Pensez à l'activer pour voir les codes (OUTILS puis MONITEUR SERIE). Attention, chaque touche est codée via trois nombres.

#include "MeOrion.h"

#include <SoftwareSerial.h>


Me7SegmentDisplay disp(PORT_4);

MeInfraredReceiver capteurIR(PORT_6);

MeUltrasonicSensor ultraSensor(PORT_7); /* Ultrasonic module can ONLY be connected to port 3, 4, 6, 7, 8 of base shield. */

MeDCMotor motor3(M1);

MeDCMotor motor4(M2);


uint8_t motorSpeed = 100;


void setup()

{

    capteurIR.begin();

    Serial.begin(9600);

}


void loop()

{

    disp.display(capteurIR.buttonState());

    if ( capteurIR.available() ) {

        int premierNombre = capteurIR.read();

        int deuxiemeNombre = capteurIR.read();

        int troisiemeNombre = capteurIR.read();

        Serial.print(premierNombre);

        Serial.print(" - ");

        Serial.print(deuxiemeNombre);

        Serial.print(" - ");

        Serial.println(troisiemeNombre);

    }

}

...CORRECTION...

Touche A : 0-255-69

Touche B : 0-255-70

Touche C : 0-255-71

Touche D : 0-255-68

Touche E : 0-255-67

Touche HAUT : 0-255-64

Touche BAS : 0-255-25

Touche GAUCHE : 0-255-7

Touche DROITE : 0-255-9

Touche MAKEBLOCK : 0-255-21

Touche 0 : 0-255-22

Touche F : 0-255-13

Touche 1 : 0-255-12

Touche 2 : 0-255-24

Touche 3 : 0-255-94

Touche 4 : 0-255-8

Touche 5 : 0-255-28

Touche 6 : 0-255-90

Touche 7 : 0-255-66

Touche 8 : 0-255-82

Touche 9 : 0-255-74

Bon. Comme vous pouvez le constater, seul le dernier octet transmis est important. Les deux premiers sont toujours un 0 (état BAS de l'octet, tous les bits à 0) et un 255 (état HAUT de l'octet, tous les bits à 1). Les deux premiers octets ne servent donc qu'à signaler qu'on débute un transfert d'informations.

Par contre, c'est assez pénible en terme de programmation. Il va falloir lire les octets un par un et tenter de trouver le nombre qui correspond à la touche voulue. Heureusement, ces valeurs sont déjà stockées dans certains des fichiers sous forme de constantes : par exemple, le code de la touche A (l'integer 69) est déjà en mémoire dans la variable constante qui se nomme IR_BUTTON_A.

Ainsi, si on veut que le robot avance pendant 1 seconde lorsqu'on appuie sur A, on peut utiliser le code suivant :

#include "MeOrion.h"

#include <SoftwareSerial.h>


Me7SegmentDisplay disp(PORT_4);

MeInfraredReceiver capteurIR(PORT_6);

MeUltrasonicSensor ultraSensor(PORT_7); /* Ultrasonic module can ONLY be connected to port 3, 4, 6, 7, 8 of base shield. */

MeDCMotor motor3(M1);

MeDCMotor motor4(M2);


uint8_t motorSpeed = 100;


void setup()

{

    capteurIR.begin();

    Serial.begin(9600);

}


void loop()

{

    disp.display(capteurIR.buttonState());

    if ( capteurIR.available() ) {

        int octetLu = capteurIR.read();

        if ( octetLu == IR_BUTTON_A ) {

            motor3.run(motorSpeed);

            motor4.run(motorSpeed);

            delay(1000);

            motor3.stop();

            motor4.stop();

        }

    }

}

06° Utiliser ce programme ci-dessus avec différents cas : appui court sur A, appui très long sur A, multiples appuis sur A.

Attention 1 : le robot va avancer mais le cable USB est branché pour assurer la liaison série.

Attention 2 : il est probable que vous ne pensiez pas à utiliser le bouton marche/arrêt dans la mesure où le robot est relié en filaire à un port USB. Cela marche depuis le début car on consomme peu de courant : c'est l'ordinateur qui fournit l'énergie. Cela ne fonctionnera pas pour les moteurs. Il faut que vous mettiez le robot en route pour les moteurs soient alimentés via les batteries du robot.

Vous devriez voir que le robot n'agit pas forcément comme on le veut :

Nous allons rentrer dans le détail de fonctionnement dans l'avant dernière partie. Ainsi, vous verrez comment créer un fonctionnement

Mais d'abord, nous allons voir un moyen plus efficace qu'une grande succession de else if pour connaitre la touche sur laquelle on vient d'appuyer.

4 - La sélection d'un choix avec Switch

L'instruction switch va nous permettre de nous passer de l'écrire fastidieuse des choix SI multiples.

Imaginons qu'on veuille initier des actions sur les touches A, B et C.

Avec des if et des else if, cela donne :

        if ( octetLu == IR_BUTTON_A ) {

            ***

        } else if ( octetLu == IR_BUTTON_B ) {

            ***

        } else if ( octetLu == IR_BUTTON_C ) {

            ***

        }

Bref, si vous avez 20 touches, ça devient rapidement un peu long à taper...

C'est pour cela qu'il existe une autre structure de controle : le SWITCH.

Regardons à quoi ressemblerait la gestion des différentes touches avec cette structure :

#include "MeOrion.h"

#include <SoftwareSerial.h>


Me7SegmentDisplay disp(PORT_4);

MeInfraredReceiver capteurIR(PORT_6);

MeUltrasonicSensor ultraSensor(PORT_7); /* Ultrasonic module can ONLY be connected to port 3, 4, 6, 7, 8 of base shield. */

MeDCMotor motor3(M1);

MeDCMotor motor4(M2);


uint8_t motorSpeed = 100;


void setup()

{

    capteurIR.begin();

    Serial.begin(9600);

}


void loop()

{

    disp.display(capteurIR.buttonState());

    if ( capteurIR.available() ) {

        int octetLu = capteurIR.read();


        switch ( octetLu ) {

            case IR_BUTTON_A: Serial.println("Press A."); break;

            case IR_BUTTON_B: Serial.println("Press B."); break;

            case IR_BUTTON_C: Serial.println("Press C."); break;

            case IR_BUTTON_D: Serial.println("Press D."); break;

            case IR_BUTTON_E: Serial.println("Press E."); break;

            case IR_BUTTON_F: Serial.println("Press F."); break;

            case IR_BUTTON_0: Serial.println("Press 0."); break;

            case IR_BUTTON_1: Serial.println("Press 1."); break;

            case IR_BUTTON_2: Serial.println("Press 2."); break;

            case IR_BUTTON_3: Serial.println("Press 3."); break;

            case IR_BUTTON_4: Serial.println("Press 4."); break;

            case IR_BUTTON_5: Serial.println("Press 5."); break;

            case IR_BUTTON_6: Serial.println("Press 6."); break;

            case IR_BUTTON_7: Serial.println("Press 7."); break;

            case IR_BUTTON_8: Serial.println("Press 8."); break;

            case IR_BUTTON_9: Serial.println("Press 9."); break;

            case IR_BUTTON_SETTING: Serial.println("Press Setting."); break;

            case IR_BUTTON_UP: Serial.println("Press Up."); break;

            case IR_BUTTON_DOWN: Serial.println("Press Down."); break;

            case IR_BUTTON_LEFT: Serial.println("Press Left."); break;

            case IR_BUTTON_RIGHT: Serial.println("Press Right."); break;

            default: Serial.println("*"); break;

        }

    }

}

07° Utiliser ce programme pour tester que la liaison série permet bien d'afficher la touche sur laquelle on vient d'appuyer.

Un peu d'explication sur la structure :

08° A quoi sert le mot-clé default ?

...CORRECTION...

Si aucun des choix n'est le bon, on arrive à la fin de la liste. En plaçant default, on signale alors ce qu'il faut faire si la variable ne contient pas les choix précédents. En gros, c'est l'action à faire par défaut. Vous n'êtes pas obligé de placer cette ligne. Dans ce cas, le programme ne fera rien si la variable ne contient pas un des choix clairement définis.

09° A quoi sert l'instruction break ?

...CORRECTION...

Si vous avez réussi à répondre à cette question, ce que vous avez déjà fait un peu de progammation. Sinon, chapeau !

L'instruction break sert à sortir immédiatement d'une structure de controle. Imaginons, qu'on ne place pas les différents break et que vous tapiez sur B.

            case IR_BUTTON_A: Serial.println("Press A.");

            case IR_BUTTON_B: Serial.println("Press B.");

            case IR_BUTTON_C: Serial.println("Press C.");

            case IR_BUTTON_D: Serial.println("Press D.");

On vérifie avec case IR_BUTTON_A si la touche est A : non, on passe au case suivant.

On vérifie avec case IR_BUTTON_B si la touche est B : oui, on passe à l'action puis passe au case suivant ! Et ainsi de suite jusqu'à la fin : alors qu'on sait fort bien que c'était un B, on va devoir tester une à une les autres possibilités.

L'instruction break permet donc de sortir de la structure dès qu'un des choix a été validé.

Le dernier break sur default n'est donc pas obligatoire en réalité. C'était le dernier choix.

10° Modifier le programme pour que le robot avance 1 seconde lorsqu'on appuie sur la touche UP.

...CORRECTION...

#include "MeOrion.h"

#include <SoftwareSerial.h>


Me7SegmentDisplay disp(PORT_4);

MeInfraredReceiver capteurIR(PORT_6);

MeUltrasonicSensor ultraSensor(PORT_7); /* Ultrasonic module can ONLY be connected to port 3, 4, 6, 7, 8 of base shield. */

MeDCMotor motor3(M1);

MeDCMotor motor4(M2);


uint8_t motorSpeed = 100;


void setup()

{

    capteurIR.begin();

    Serial.begin(9600);

}


void loop()

{

    disp.display(capteurIR.buttonState());

    if ( capteurIR.available() ) {

        int octetLu = capteurIR.read();


        switch ( octetLu ) {

            case IR_BUTTON_A: Serial.println("Press A."); break;

            case IR_BUTTON_B: Serial.println("Press B."); break;

            case IR_BUTTON_C: Serial.println("Press C."); break;

            case IR_BUTTON_D: Serial.println("Press D."); break;

            case IR_BUTTON_E: Serial.println("Press E."); break;

            case IR_BUTTON_F: Serial.println("Press F."); break;

            case IR_BUTTON_0: Serial.println("Press 0."); break;

            case IR_BUTTON_1: Serial.println("Press 1."); break;

            case IR_BUTTON_2: Serial.println("Press 2."); break;

            case IR_BUTTON_3: Serial.println("Press 3."); break;

            case IR_BUTTON_4: Serial.println("Press 4."); break;

            case IR_BUTTON_5: Serial.println("Press 5."); break;

            case IR_BUTTON_6: Serial.println("Press 6."); break;

            case IR_BUTTON_7: Serial.println("Press 7."); break;

            case IR_BUTTON_8: Serial.println("Press 8."); break;

            case IR_BUTTON_9: Serial.println("Press 9."); break;

            case IR_BUTTON_SETTING: Serial.println("Press Setting."); break;

            case IR_BUTTON_UP:

                motor3.run(motorSpeed);

                motor4.run(motorSpeed);

                delay(1000);

                motor3.stop();

                motor4.stop();

                break;

            case IR_BUTTON_DOWN: Serial.println("Press Down."); break;

            case IR_BUTTON_LEFT: Serial.println("Press Left."); break;

            case IR_BUTTON_RIGHT: Serial.println("Press Right."); break;

            default: Serial.println("*"); break;

        }

    }

}

Une petite remarque pour la route :

J'ai noté ceci pour que cela soit plus clair :

            case IR_BUTTON_UP:

                motor3.run(motorSpeed);

                motor4.run(motorSpeed);

                delay(1000);

                motor3.stop();

                motor4.stop();

                break;

La tabulation des instructions n'est ici que cosmétique : nous aurions pu taper ceci :

            case IR_BUTTON_UP: motor3.run(motorSpeed); motor4.run(motorSpeed); delay(1000); motor3.stop(); motor4.stop(); break;

Mais bon, c'est bien moins clair pour lire l'ensemble.

11° Rajouter quelques fonctionnalités, comme le fait de faire marche arrière, de tourner ...

Pensez à sauvegarder votre programme quelque part. Nous allons en avoir besoin pour la suite.

5 - Mini-projet : Robot à mémorisation d'actions

Nous allons rentrer dans le détail du fonctionnement du stockage des octets reçus pour voir comment créer une série d'action puis lancer l'action.

Comme nous n'avons pas encore vu les tableaux permettant de stocker plusieurs données, nous allons réaliser un programme primitif mais simple : le robot attend 5 ordres puis va les executer dans l'ordre.

Commençons par voir comment évolue la réponse de la méthode available.

12° Utiliser le programme ci-dessous pour voir comment évolue la réponse de available. L'affichage se fait directement sur l'afficheur numérique. Pensez à vérifier que la DEL bleue s'allume pour signifier que le signal est reçu.

#include "MeOrion.h"

#include <SoftwareSerial.h>


Me7SegmentDisplay disp(PORT_4);

MeInfraredReceiver capteurIR(PORT_6);

MeUltrasonicSensor ultraSensor(PORT_7); /* Ultrasonic module can ONLY be connected to port 3, 4, 6, 7, 8 of base shield. */

MeDCMotor motor3(M1);

MeDCMotor motor4(M2);


uint8_t motorSpeed = 100;


void setup()

{

    capteurIR.begin();

    Serial.begin(9600);

}


void loop()

{

    disp.display(capteurIR.available());

}

...CORRECTION...

On constate normalement qu'on enregistre 3 octets supplémentaires à chaque fois (255-0-code de la touche). D'ailleurs, on en enregistre parfois 6 d'un coup : il arrive qu'un simple appui provoque l'enregistrement de deux ordres...

Par contre, on ne peut pas dépasser 63 octets stockés. On ne peut donc aller que jusqu'à 11 ordres d'affilé.

Nous allons maintenant lire un par un les ordres stockés, à raison d'un ordre par seconde.

#include "MeOrion.h"

#include <SoftwareSerial.h>


Me7SegmentDisplay disp(PORT_4);

MeInfraredReceiver capteurIR(PORT_6);

MeUltrasonicSensor ultraSensor(PORT_7); /* Ultrasonic module can ONLY be connected to port 3, 4, 6, 7, 8 of base shield. */

MeDCMotor motor3(M1);

MeDCMotor motor4(M2);


uint8_t motorSpeed = 100;


void setup()

{

    capteurIR.begin();

    Serial.begin(9600);

}


void loop()

{

    disp.display(capteurIR.available());

    if ( capteurIR.available() >= 30) {

        while ( capteurIR.available() > 0) {

            int numeroOctet = capteurIR.available();

            int octetLu = capteurIR.read();

            disp.display(numeroOctet);

            delay(1000);

        }

    }

}

13° Utiliser le programme pour vérifier qu'une fois qu'on atteint 30 octets mémorisés, il commence à les lire à la vitesse de un par seconde et qu'il les fait disparaitre un à un de sa mémoire puisque le nombre d'octets mémorisés diminue.

...CORRECTION...

On constate normalement qu'on enregistre 3 octets supplémentaires à chaque fois. D'ailleurs, on en enregistre parfois 6 d'un coup : il arrive qu'un simple appui provoque l'enregistrement de deux ordres...

Par contre, on ne peut pas dépasser 63 octets stockés. On ne peut donc aller que jusqu'à 11 ordres d'affilé.

Je vais maintenant modifier le code pour qu'il affiche la touche numérique utilisé s'il s'agit d'une des touches de 1 à 9 : j'affiche la touche numérotée*100 + le nombre d'octets stockés.

Ainsi s'il lit la touche "9" et qu'on a 6 octets stockés, l'afficheur affichera 9*100+6, soit 906.

#include "MeOrion.h"

#include <SoftwareSerial.h>


Me7SegmentDisplay disp(PORT_4);

MeInfraredReceiver capteurIR(PORT_6);

MeUltrasonicSensor ultraSensor(PORT_7); /* Ultrasonic module can ONLY be connected to port 3, 4, 6, 7, 8 of base shield. */

MeDCMotor motor3(M1);

MeDCMotor motor4(M2);


uint8_t motorSpeed = 100;


void setup()

{

    capteurIR.begin();

    Serial.begin(9600);

}


void loop()

{

    disp.display(capteurIR.available());

    if ( capteurIR.available() >= 30) {

        while ( capteurIR.available() > 0) {

            int numeroOctet = capteurIR.available();

            int octetLu = capteurIR.read();

            switch ( octetLu ) {

                case IR_BUTTON_1: disp.display(100+numeroOctet); break;

                case IR_BUTTON_2: disp.display(200+numeroOctet); break;

                case IR_BUTTON_3: disp.display(300+numeroOctet); break;

                case IR_BUTTON_4: disp.display(400+numeroOctet); break;

                case IR_BUTTON_5: disp.display(500+numeroOctet); break;

                case IR_BUTTON_6: disp.display(600+numeroOctet); break;

                case IR_BUTTON_7: disp.display(700+numeroOctet); break;

                case IR_BUTTON_8: disp.display(800+numeroOctet); break;

                case IR_BUTTON_9: disp.display(900+numeroOctet); break;

                default: disp.display(numeroOctet); break;

            }

            delay(1000);

        }

    }

}

14° Utiliser le code et appuyer sur les touches 1,2,3,4,5,6,7,8,9,9 pour obtenir dix touches enregistrées. Lorsqu'on lit, obtient-on d'abord les premières touches ou les dernières touches ?

...CORRECTION...

On constate qu'on lit les touches dans l'ordre d'enregistrement. En tapant sur 1-2-3-4-5-6-7-8-9-9, on obtient :

30-29-128

27-26-225

24-23-322

...

Pile ou file ?

Il existe deux façons de stocker puis de lire les informations qu'on a stocké :

  • La PILE : comme avec des livres qu'on vous donne au fur et à mesure et que vous empilez progressivement. Le premier que vous pourrez prendre sera nécéssairement le dernier qu'on vous a donné.
  • La FILE : comme dans une file d'attente. Le premier arrivé sera le premier à pouvoir sortir.
  • La gestion des informations dans la mémoire du capteur IR est visiblement en file d'attente : la première touche activée est la première touche a être lu.

15° Modifier le programme pour n'attendre que lorsqu'on veut afficher un numéros de touche et de n'afficher d'ailleurs que les numéros de touche qui ont été mémorisés.

...CORRECTION...

#include "MeOrion.h"

#include <SoftwareSerial.h>


Me7SegmentDisplay disp(PORT_4);

MeInfraredReceiver capteurIR(PORT_6);

MeUltrasonicSensor ultraSensor(PORT_7); /* Ultrasonic module can ONLY be connected to port 3, 4, 6, 7, 8 of base shield. */

MeDCMotor motor3(M1);

MeDCMotor motor4(M2);


uint8_t motorSpeed = 100;


void setup()

{

    capteurIR.begin();

    Serial.begin(9600);

}


void loop()

{

    disp.display(capteurIR.available());

    if ( capteurIR.available() >= 30) {

        while ( capteurIR.available() > 0) {

            int numeroOctet = capteurIR.available();

            int octetLu = capteurIR.read();

            switch ( octetLu ) {

                case IR_BUTTON_1: disp.display(1); delay(1000); break;

                case IR_BUTTON_2: disp.display(2); delay(1000); break;

                case IR_BUTTON_3: disp.display(3); delay(1000); break;

                case IR_BUTTON_4: disp.display(4); delay(1000); break;

                case IR_BUTTON_5: disp.display(5); delay(1000); break;

                case IR_BUTTON_6: disp.display(6); delay(1000); break;

                case IR_BUTTON_7: disp.display(7); delay(1000); break;

                case IR_BUTTON_8: disp.display(8); delay(1000); break;

                case IR_BUTTON_9: disp.display(9); delay(1000); break;

            }

        }

    }

}

16° Dernière étape : réaliser un robot qui attend sagement 10 ordres et qui les execute ensuite. Vous devrez gérer la marche avant, la marche arrière et les deux rotations au moins.

Voilà, c'est tout pour aujourd'hui. Attention, il reste encore pas mal de choses à faire avec la télécommande :

A vous de chercher et de mettre au point des stratégies. Et vous risquez d'en avoir besoin pour vos projets.

Mais avant de pouvoir faire des choses vraiment complexes, il nous reste à voir une dernière entité importante en informatique : la fonction. Et c'est la leçon suivante.