Infoforall

2 - MAKEBLOCK / Utilisation des boucles

robot makeblock

Nous allons voir comment utiliser un outil bien pratique en progammation : la boucle FOR.

1 - La boucle FOR

On peut utiliser un FOR pour faire une boucle revenant à réaliser les mêmes instructions X fois.

Comment fonctionne une boucle for ? Le cas le plus simple est facile à comprendre : on prend une variable i qui commence à la valeur zéro. On l'augmente de 1 à chaque tour tant qu'elle ne dépasse pas strictement une valeur de seuil iMAX telle que i < iMAX.

Si vous n'étes pas familier avec le concept, utilisez le script ci-dessous :

Valeur initiale (initialisation) :

On continue tant que i < Valeur de test:

Je vais commencer par vous présenter l’utilisation basique de l'instruction for ( initialisation de la variable ; condition pour continuer ; incrémentation ). Comme ça, ça semble compliqué mais en fait, non.

01° Utiliser les entrées de la boucle présentée ci-dessus pour répondre aux questions suivantes : Quelles sont les différentes valeurs prises par i si on utilise 0 initialement et i<5 pour le test de continuité ? Va-t-on réellement jusqu’à 5 ou s’arrête-t-on juste avant ?

Et oui. On ne compte que jusqu'à 4, on s'arrête avant 5.

Pourquoi ?

Nous verrons plus loin la raison exacte mais si on regarde ce qui est affiché ...

0

1

2

3

4

... on voit qu'on compte jusqu'à 4 mais qu'on a bien 5 nombres : 0 - 1 - 2 - 3 - 4.

En terme de codage, l'initialisation se fait avec int i=0. Cela veut dire qu'on demande de créer une variable nommée i et de lui donner le type int, integer en anglais correspondant en gros à un nombre entier en français.

On notera qu'on place un point-virgule pour séparer l'intialisation de la condition de poursuite.

Comment note-t-on cette condition ? Par i<5. On s'arrête donc lorsque i vaut 5. On place encore un point-virgule.

L'incrémentation peut se noter i=i+1 mais on utilise plutôt i++ qui veut dire presque la même chose.

Bref, le code de la boucle for précédente est for (int i =0; i < 5 ; i++).

Regardons comme utiliser ceci dans un cas plutôt simple : on veut faire bouger le point en suivant le trajet. Vous pouvez utiliser les curseurs pour définir :

Une boucle

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

    va_a_gauche();

}

Une boucle

for (int j=0 ; j< JMAX; j++) {

    va_en_bas();

}

A droite : IMAX = 0
En bas : JMAX = 0

...CORRECTION...

Il faut régler IMAX sur 4 pour avoir 4 étapes : 0-1-2-3.

Il faut régler JMAX sur 7 pour avoir 7 étapes : 0-1-2-3-4-5-6.

Il faut donc se souvenir qu'on commence ici avec le compteur à 0 car on note var i = 0.

Nous expliquerons la différence entre les codes i=i+1, i++ et ++i un peu plus tard. Souvenez-vous pour l'instant que dans les trois cas, nous allons augmenter i de 1. La différence se fait au niveau du moment où on incrémente réellement i. Avec i++, on incrémente i après avoir fait l'instruction, avec ++i, on incrémente i avant de faire l'instruction.

Nous allons commencer par vous montrer comment réaliser une boucle en utilisant la liaison série de l'Arduino.

Commençons par ce petit programme (J'ai rajouté les déclarations des moteurs qui ne servent à rien pour l'instant mais vous allez devoir les utiliser en fin d'activité) :

#include "MeOrion.h"

MeDCMotor motor1(M1);

MeDCMotor motor2(M2);

uint8_t motorSpeed = 100;


void setup()

{

    // Ouverture du port série

    Serial.begin(9600);

    Serial.println("Debut du programme");

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

        Serial.println(i);

    }

}


void loop()

{

}

Regardons l'ordre d'exécution théorique :

CLIQUEZ ICI POUR VOIR L'ANIMATION :

motorSpeed :

i :

02° Le code présent dans la fonction setup va-t-il s'exécuter une fois ou plusieurs fois en boucle ?

...CORRECTION...

Le code de setup ne va s'exécuter qu'une fois.

Par contre, il y a une boucle FOR dans ce code qui lui va tourner plusieurs fois.

03° Téléverser le code dans votre robot, ouvrir le moniteur série. Pour ouvrir le moniteur série, aller dans le menu OUTILS.

Vous devriez obtenir ceci :

Debut du programme

0

1

2

3

4

Si vous ne comprenez pas à quoi sert Serial, autant repartir sur la leçon d'introduction à Arduino.

Vous y découvrirez comment fonctionne cet objet qui permet de créer une communication série entre la carte Arduino et l'ordinateur.

Cela vous permettra aussi de faire la différence entre print et println qui seront utilisés quelques questions plus loin.

04° Modifier le code précédent pour afficher les chiffres de 0 à 20 avec une boucle.

05° Regarder le code ci-dessous et prévoir s'il va réussir à afficher correctement le résultat d'une multiplication par deux ou si une erreur se trouve dans le code. Vérifier en lançant le code. Le code présenté contient une erreur de conception ! Modifier le code pour qu'il fonctionne correctement : on veut afficher la multiplication par 2, pas le carré.

void setup()

{

    // Ouverture du port série

    Serial.begin(9600);

    Serial.println("Debut du programme");

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

        Serial.print("i*2 = ");

        Serial.print(i);

        Serial.print(" *2 = ");

        Serial.println(i*i);

    }

}


void loop()

{

}

06° Réaliser un programme ne comprenant qu’une seule boucle FOR qui affiche (pour chaque valeur de x variant de 0 à 6) le carré de x et la puissance trois de x.

...CORRECTION...

void setup()

{

    // Ouverture du port série

    Serial.begin(9600);

    Serial.println("Debut du programme");

    for (int x=0 ; x < 7 ; x++) {

        Serial.println(x);

        Serial.println(x*x);

        Serial.println(x*x*x);

    }

}

Si on veut que le compteur ne commence pas à 0, il suffit de le préciser lors de l'initialisation for (int i = 2 ; i < 6 ; i++) va donc prendre les valeurs 2, 3, 4 et 5.

07° Réaliser un programme qui affiche un à un les nombres compris entre 32 et 127.

...CORRECTION...

void setup()

{

    // Ouverture du port série

    Serial.begin(9600);

    Serial.println("Debut du programme");

    for (int x=32 ; x < 128 ; x++) {

        Serial.println(x);

    }

}

Les systèmes informatiques ne stockent que des bits (0 ou 1), associés le plus souvent par 8. Un ensemble de 8 bits se nomme un octet et code un nombre de 0 à 255.

Toutes les informations sont ainsi stockées sous forme d'octets, les nombres mais aussi les images ou les textes.

Ainsi, l'ordinateur ne stocke pas A ou a, mais un nombre qui codera A ou a.

Pour savoir à quel caractère correspond un nombre x pour votre Arduino, il faut utiliser Serial.write(x).

08° Réaliser un programme qui affiche (dans le moniteur série) un à un les caractères associés aux nombres compris entre 32 et 127 sous la forme :

        Le caractère X correspond au code XXX

...CORRECTION...

void setup()

{

    // Ouverture du port série

    Serial.begin(9600);

    Serial.println("Debut du programme");

    for (int x=32 ; x < 128 ; x++) {

        Serial.print("Le caractère ");

        Serial.write(x);

        Serial.print(" correspond au code ");

        Serial.println(x);

    }

}

Tous les caractères sont-ils "imprimables" ?

Debut du programme

Le caractère   correspond au code 32

Le caractère ! correspond au code 33

Le caractère " correspond au code 34

Le caractère # correspond au code 35

Le caractère $ correspond au code 36

Le caractère % correspond au code 37

Le caractère & correspond au code 38

Le caractère ' correspond au code 39

Le caractère ( correspond au code 40

Le caractère ) correspond au code 41

Le caractère * correspond au code 42

Le caractère + correspond au code 43

Le caractère , correspond au code 44

Le caractère - correspond au code 45

Le caractère . correspond au code 46

Le caractère / correspond au code 47

Le caractère 0 correspond au code 48

Le caractère 1 correspond au code 49

Le caractère 2 correspond au code 50

Le caractère 3 correspond au code 51

Le caractère 4 correspond au code 52

Le caractère 5 correspond au code 53

Le caractère 6 correspond au code 54

Le caractère 7 correspond au code 55

Le caractère 8 correspond au code 56

Le caractère 9 correspond au code 57

Le caractère : correspond au code 58

Le caractère ; correspond au code 59

Le caractère < correspond au code 60

Le caractère = correspond au code 61

Le caractère > correspond au code 62

Le caractère ? correspond au code 63

Le caractère @ correspond au code 64

Le caractère A correspond au code 65

Le caractère B correspond au code 66

Le caractère C correspond au code 67

Le caractère D correspond au code 68

Le caractère E correspond au code 69

Le caractère F correspond au code 70

Le caractère G correspond au code 71

Le caractère H correspond au code 72

Le caractère I correspond au code 73

Le caractère J correspond au code 74

Le caractère K correspond au code 75

Le caractère L correspond au code 76

Le caractère M correspond au code 77

Le caractère N correspond au code 78

Le caractère O correspond au code 79

Le caractère P correspond au code 80

Le caractère Q correspond au code 81

Le caractère R correspond au code 82

Le caractère S correspond au code 83

Le caractère T correspond au code 84

Le caractère U correspond au code 85

Le caractère V correspond au code 86

Le caractère W correspond au code 87

Le caractère X correspond au code 88

Le caractère Y correspond au code 89

Le caractère Z correspond au code 90

Le caractère [ correspond au code 91

Le caractère \ correspond au code 92

Le caractère ] correspond au code 93

Le caractère ^ correspond au code 94

Le caractère _ correspond au code 95

Le caractère ` correspond au code 96

Le caractère a correspond au code 97

Le caractère b correspond au code 98

Le caractère c correspond au code 99

Le caractère d correspond au code 100

Le caractère e correspond au code 101

Le caractère f correspond au code 102

Le caractère g correspond au code 103

Le caractère h correspond au code 104

Le caractère i correspond au code 105

Le caractère j correspond au code 106

Le caractère k correspond au code 107

Le caractère l correspond au code 108

Le caractère m correspond au code 109

Le caractère n correspond au code 110

Le caractère o correspond au code 111

Le caractère p correspond au code 112

Le caractère q correspond au code 113

Le caractère r correspond au code 114

Le caractère s correspond au code 115

Le caractère t correspond au code 116

Le caractère u correspond au code 117

Le caractère v correspond au code 118

Le caractère w correspond au code 119

Le caractère x correspond au code 120

Le caractère y correspond au code 121

Le caractère z correspond au code 122

Le caractère { correspond au code 123

Le caractère | correspond au code 124

Le caractère } correspond au code 125

Le caractère ~ correspond au code 126

Le caractère  correspond au code 127

Les code 32 et 127 semblent particuliers : le code 32 correspond au caractère ESPACE et le code 127 à la touche DEL.

09° Essayer les caractères de 0 à 31. S'agit-il de caractères imprimables ? Que se passe-t-il pour le 10 ?

Cette association particulière d'un code et d'un caractère ou d'une action (comme le 10 qui correspond au passage à la ligne) est le code ASCII. Il est un standard : tous les encodages de caractères sont similaires ou presque à l'ASCII sur les codes 0 à 127. C'est pour les codes 128 et plus que cela diverge.

On peut également changer l'incrémentation. i-- diminue i de 1 plutôt que l'augmenter, i+=2 va augmenter i de 2 plutôt que d'augmenter de un en un. On aurait pu noter également i=i+2.

Si le pas est négatif, on compte en sens inverse : for (int i=9;i>1;i--) donne : 9 8 7 6 5 4 3 2, mais pas 1 puisque la condition n'est alors plus vérifiée.

10° Créer un programme qui affiche automatiquement une lettre sur 2 de A (code 65) à Z (code 90) puis qui affiche les lettres de Z à A. Utiliser les boucles FOR associées au code ASCII.

2 - Le programme de test de déplacement

Nous allons maintenant pouvoir reprendre notre robot pour lui faire faire des tours.

11° Créer un programme qui permet au robot d'avancer d'un dizaine de centimètres et de reculer au point de départ.

Voici le programme de base que nous avions utilisé dans la première activité.

#include "MeOrion.h"

MeDCMotor motor1(M1);

MeDCMotor motor2(M2);

uint8_t motorSpeed = 100;


void setup()

{

}


void loop()

{

    motor1.run(motorSpeed);

    motor2.run(motorSpeed);

    delay(2000);

    motor1.stop();

    motor2.stop();

    delay(100);

    motor1.run(-motorSpeed);

    motor2.run(-motorSpeed);

    delay(2000);

    motor1.stop();

    motor2.stop();

    delay(2000);

}

12° Idem mais le robot doit faire cela 3 fois. Boucle FOR impérative.

13° Idem mais la vitesse augmente à chaque fois aller/retour. Il faudra impérativement utiliser la valeur du compteur pour gérer la vitese.

Si vous avez bloqué sur une question, demandez de l'aide sinon, ça va être délicat pour le projet...

...CORRECTION...

#include "MeOrion.h"

MeDCMotor motor1(M1);

MeDCMotor motor2(M2);

uint8_t motorSpeed = 80;


void setup()

{

    for (int etape =0; etape < 4 ; etape++) {

        motor1.run(motorSpeed+40*etape); /* value: between -255 and 255. */

        motor2.run(motorSpeed+40*etape); /* value: between -255 and 255. */

        delay(2000);

        motor1.stop();

        motor2.stop();

        delay(100);

        motor1.run(-motorSpeed-40*etape);

        motor2.run(-motorSpeed-40*etape);

        delay(2000);

        motor1.stop();

        motor2.stop();

        delay(2000);

    }

}


void loop()

{

}

3 - Quelques petits défis

14° Faire tourner votre robot autour de 4 pieds de chaise à l'aide d'une suite d'instructions basiques que vous allez executer 4 fois avec une boucle FOR.

15° Créer un mouvement linéaire où la vitesse augmente au fil du déplacement.

Et là, vous devriez constater la limite de la conduite en roue libre : on ne contrôle ABSOLUMENT pas où le robot veut aller. Il reste de finir dans le mur. Il faudra veiller à l'intégrité physique de votre robot, votre note en dépend !

La prochaine activité traitera des conditions logiques et de l'emetteur/récepteur à ultrasons. On pourra ainsi dire de robot de s'arrêter SI un obstacle est trop proche.

Qu'est-ce qu'une variable ? (3)

Souvenez-vous bien qu'on a deux types de variables différentes. On a donc :

Des types de variables pour les variables "simples" ou de structures : si uint8_t x = 45 alors

  • x est une variable
  • renvoyant une valeur.
  • de type int (integer) (uint8_t)

Des classes pour les variables-objet ou variables de référence: si MeDCMotor motor3(M1) alors

  • motor3 est une variable
  • renvoyant une référence vers un objet
  • de classe MeDCMotor.