LOCODUINO

Forum de discussion
Dépôt GIT Locoduino
Flux RSS

vendredi 24 mars 2017

24 visiteurs en ce moment

Instructions conditionnelles : le if ... else

. Par : Jean-Luc

Dans « La programmation, qu’est ce que c’est », nous avons vu un premier programme très simple permettant de faire clignoter une DEL  . Comparé à de l’électronique classique, ce n’est pas vraiment un grand pas en avant. Si la force des micro-contrôleurs est justement de permettre de faire des choses beaucoup plus complexes que ce qui est faisable en électronique classique, cette complexité se traduit forcément par un programme plus élaboré. Une des briques de base est la capacité d’exécuter les instructions selon une condition.

Un premier exemple simple d’utilisation du if

Pour prendre un exemple concret, supposons que vous vouliez que l’Arduino signale sur une DEL   la présence d’un train dans une gare cachée. Les constituants de ce système sont :

  • bien évidemment un Arduino ;
  • un capteur qui va donner une information de nature tout ou rien : le train est présent ou il ne l’est pas ;
  • la DEL qui permet de signaler la présence du train.

Le capteur fournit la condition : le train est présent. La série d’instructions à exécuter correspond à on allume la DEL.

L’instruction permettant d’allumer la DEL si le train est présent est le if ... else, « si ... sinon » en français. La syntaxe générale est la suivante :

  1. if (condition) {
  2. // instruction(s) exécutée(s) si la condition est vraie
  3. }
  4. else {
  5. // instruction(s) exécutée(s) si la condition est fausse
  6. }

Si il n’est pas nécessaire d’exécuter une série d’instruction si la condition est fausse, il suffit d’omettre la partie else comme ceci :

  1. if (condition) {
  2. // instruction(s) exécutée(s) si la condition est vraie
  3. }
Notez bien les paires d’accolades ouvrantes et fermantes qui délimitent les séries d’instructions. Notez également les parenthèses autour de la condition.
 

Pour revenir à notre système, supposons que le capteur soit connecté à la broche 2 de l’Arduino et qu’il fournisse HIGH, c’est à dire 5V, si le train est présent et LOW, c’est à dire 0V, si il n’est pas présent. La condition pour allumer la DEL est donc que le capteur fournisse HIGH.

Pour commencer en respectant les bonnes pratiques, définissons la constante pinCapteur et donnons lui la valeur 2.

  1. const byte pinCapteur = 2;

Evidemment pour que tout cela puisse fonctionner il faut que la broche 2 soit programmée en entrée et que le programme lise la valeur fournie par le capteur. Nous avons déjà vu dans « La programmation, qu’est ce que c’est » comment programmer une broche en sortie pour allumer une DEL et comment écrire une valeur sur cette broche. Ici nous devons faire l’inverse. Pour programmer la broche 2 en entrée, la fonction pinMode(...) est également employée mais son second argument doit être INPUT, « entrée » au lieu de OUTPUT. Ceci vient se loger dans setup() :

  1. void setup() {
  2. pinMode(pinCapteur, INPUT);
  3. }

Pour lire la valeur fournie par le capteur, nous allons utiliser la fonction digitalRead(...). L’unique argument de digitalRead(...) est le numéro de broche. Jusqu’ici nous n’avons vu que des fonctions qui ne retournent aucune valeur, c’est à dire dont le type est void. digitalRead(...) retourne une valeur, un int, qui est l’état de la broche, HIGH ou LOW [1].

Dans notre cas, la condition du if est une simple comparaison, on veut comparer la valeur renvoyer par digitalRead(pinCapteur) avec HIGH. La condition est vraie si les deux sont identiques. Cette comparaison est effectuée avec l’opérateur == [2]. Ainsi :

  1. digitalRead(pinCapteur) == HIGH

sera vrai si digitalRead(pinCapteur) retourne HIGH et faux si il retourne LOW.

Sous le capot. On a parlé de vrai ou faux. Sur l’Arduino, deux constantes sont définies et disponible : true (vrai) et false (faux). Un type boolean [3] existe également. Toutefois, il s’agit en fait de nombres. false vaut 0 et true vaut 1. Une comparaison retourne donc un nombre, 0 ou 1

Vous savez déjà allumer une DEL, le programme complet est :

  1. const byte pinCapteur = 2; // le capteur est connecté sur la broche 2
  2. const byte pinDEL = 13; // on utilise la DEL de la carte sur la broche 13
  3.  
  4. void setup() {
  5. pinMode(pinCapteur, INPUT); // on veut lire le capteur
  6. pinMode(pinDEL, OUTPUT); // on veut piloter la DEL
  7. }
  8.  
  9. void loop() {
  10. if (digitalRead(pinCapteur) == HIGH) { // si un train est détecté
  11. digitalWrite(pinDEL, HIGH); // allume la DEL
  12. }
  13. else { // sinon
  14. digitalWrite(pinDEL, LOW); // éteint la DEL
  15. }
  16. }

Télécharger

Les if imbriqués

le if étant une instruction, il peut tout à fait être utilisé à l’intérieur d’un autre if. Supposons que notre capteur ait des sautes d’humeur, de temps en temps il déraille et envoie de courtes impulsions de moins de 10ms comme si un train était présent alors que ce n’est pas le cas. Ce genre de problème arrive plus souvent qu’on ne croit.

Pour corriger ce problème, il suffit de lire une seconde fois le capteur après un délai de 10ms et si il renvoie à nouveau HIGH alors il y a bien un train. sinon ce n’est pas le cas [4]. loop() deviendrait donc :

  1. void loop() {
  2. if (digitalRead(pinCapteur) == HIGH) {
  3. // si un train est détecté
  4. // on attend 10 ms avant de vérifier que
  5. // ce n'est pas une détection erronée
  6. delay(10);
  7. if (digitalRead(pinCapteur) == HIGH) {
  8. // le train est toujours là, allume la DEL
  9. digitalWrite(pinDEL, HIGH);
  10. }
  11. else {
  12. // sinon, éteint la DEL
  13. digitalWrite(pinDEL, LOW);
  14. }
  15. }
  16. else {
  17. // sinon, éteint la DEL
  18. digitalWrite(pinDEL, LOW);
  19. }
  20. }

Les opérateurs de comparaison

Nous venons de voir l’égalité, l’opérateur ==, il existe d’autres opérateurs de comparaison.

!= est l’opérateur différent de. La comparaison est vraie si les deux opérandes sont différents. On peut par exemple écrire digitalRead(pinCapteur) != LOW comme ceci :

  1. if (digitalRead(pinCapteur) != LOW) { // le train est toujours là
  2. digitalWrite(pinDEL, HIGH); // allume la DEL
  3. }
  4. else { // sinon
  5. digitalWrite(pinDEL, LOW); // éteint la DEL
  6. }

> est l’opérateur supérieur à. La comparaison est vraie si le le premier opérande est plus grand que le second opérande.

>= est l’opérateur supérieur ou égal à. La comparaison est vraie si le le premier opérande est plus grand que ou égal au second opérande.

< est l’opérateur inférieur à. La comparaison est vraie si le le premier opérande est plus petit que le second opérande.

<= est l’opérateur inférieur ou égal à. La comparaison est vraie si le le premier opérande est plus petit que ou égal au second opérande.

Les opérateurs logiques

On peut composer les comparaisons avec des opérateurs logiques. Par exemple, si nous avons maintenant deux capteurs, l’un branché sur pinCapteur1 et l’autre sur pinCapteur2 et que nous voulons allumer la DEL si les deux capteurs renvoient HIGH tous les deux en même temps, nous écrirons :

  1. if (digitalRead(pinCapteur1) == HIGH && digitalRead(pinCapteur2) == HIGH) {
  2. digitalWrite(pinDEL, HIGH); // allume la DEL
  3. }
  4. else { // sinon
  5. digitalWrite(pinDEL, LOW); // éteint la DEL
  6. }

&& est donc le et logique. La condition est vraie si les deux opérandes sont vrais. Dans tous les autres cas, la condition est fausse.

|| est le ou logique. La condition est vraie si l’un des deux ou les deux opérandes sont vrais. Lorsque les deux opérandes sont faux, la condition est fausse.

! est l’opérateur de négation. Si son unique opérande est vrai, la condition est fausse et inversement. Par exemple, disposant de 3 capteurs branchés sur pinCapteur1, pinCapteur2 et pinCapteur2, on peut allumer si le premier et le deuxième sont HIGH ou si le troisième est LOW, on écrirait :

  1. if ((digitalRead(pinCapteur1) == HIGH && digitalRead(pinCapteur2) == HIGH)
  2. || digitalRead(pinCapteur3) == LOW)
  3. {
  4. digitalWrite(pinDEL, HIGH); // allume la DEL
  5. }
  6. else { // sinon
  7. digitalWrite(pinDEL, LOW); // éteint la DEL
  8. }

Bien que dans les exemples nous nous soyons limités à la comparaison du résultat renvoyé par digitalRead(...) à une constante, HIGH ou LOW, cela ne signifie pas que les opérateurs de comparaison et les opérateurs logiques se limitent à ça. Tout résultat de fonction, toute constante, toute variable, peuvent être employés à gauche ou à droite des opérateurs présentés.

Une comparaison retournant un nombre, 0 ou 1, les opérateurs logiques opèrent donc sur des nombres. En réalité, tout nombre différent de 0 est compris comme vrai et tout nombre égal à 0 est compris comme faux. Toutefois une bonne pratique consiste à ne pas trop mélanger les booléens avec les entiers et éviter de faire de l’arithmétique avec les opérateurs logiques.

Dans le prochain article, nous verrons une autre instruction conditionnelle : le switch.

La suite de la série d’articles avec « Calculer avec l’Arduino (1) ». Si ce n’est pas déjà fait lisez également « La programmation, qu’est ce que c’est » et « Types, constantes et variables ».

[1Sous le capot, LOW vaut 0 et HIGH vaut 1.

[2et non = tout seul qui est l’affectation, attention c’est une erreur fréquente.

[3Nommé ainsi d’après George Boole, mathématicien anglais du 19e siècle, créateur de la logique moderne.

[4Effectivement dans notre petit exemple, ça ne serait pas très grave de faire une fausse détection, on ne fait qu’allumer une DEL mais supposons maintenant que l’on manœuvre un aiguillage.

6 Messages

Réagissez à « Instructions conditionnelles : le if ... else »

Qui êtes-vous ?
Votre message

Pour créer des paragraphes, laissez simplement des lignes vides.

Lien hypertexte

(Si votre message se réfère à un article publié sur le Web, ou à une page fournissant plus d’informations, vous pouvez indiquer ci-après le titre de la page et son adresse.)

Rubrique « Programmation »

Comment gérer le temps dans un programme ?

La programmation, qu’est ce que c’est

Types, constantes et variables

Installation de l’IDE arduino

Répéter des instructions : les boucles

Les interruptions (1)

Instructions conditionnelles : le if ... else

Instructions conditionnelles : le switch ... case

Comment gérer l’aléatoire ?

Calculer avec l’Arduino (1)

Calculer avec l’Arduino (2)

Les structures

Systèmes de numération

Les fonctions

Trois façons de déclarer des constantes

Transcription d’un programme simple en programmation objet

Les chaînes de caractères

Trucs, astuces et choses à ne pas faire !

Le monde des objets (1)

Le monde des objets (2)

Le monde des objets (3)

Le monde des objets (4)

Les pointeurs (1)

Les pointeurs (2)

Les Timers (I)

Les Timers (II)

Les Timers (III)

Les Timers (IV)

Les Timers (V)

Les derniers articles

Les Timers (V)


Christian Bézanger

Trucs, astuces et choses à ne pas faire !


Dominique

Le monde des objets (4)


Thierry

Les pointeurs (2)


Thierry

Les chaînes de caractères


Thierry

Transcription d’un programme simple en programmation objet


Dominique, Guillaume, Jean-Luc

Les pointeurs (1)


Thierry

Comment gérer l’aléatoire ?


Dominique, Guillaume, Jean-Luc

Les Timers (IV)


Christian Bézanger

Les fonctions


Jean-Luc

Les articles les plus lus

Les interruptions (1)

Les Timers (I)

Comment gérer le temps dans un programme ?

Calculer avec l’Arduino (1)

Répéter des instructions : les boucles

Les Timers (II)

Les chaînes de caractères

Les Timers (IV)

Instructions conditionnelles : le if ... else

Les pointeurs (1)