Mis à jour le mercredi 30 novembre 2016
  • 15 heures
  • Moyenne

Ce cours est visible gratuitement en ligne.

Vous pouvez obtenir un certificat de réussite à l'issue de ce cours.

J'ai tout compris !

Le bouton poussoir

Connectez-vous ou inscrivez-vous gratuitement pour bénéficier de toutes les fonctionnalités de ce cours !

Vous savez maintenant brancher des LED et programmer leur allumage. Vous avez utilisé des variables de plusieurs types, des tableaux, le moniteur. Vous allez vous apercevoir que la suite finalement n'apporte pas de réelle difficulté.

Maintenant que vous avez compris comment allumer une LED en mettant un pin en position haute, ce serait intéressant d’ajouter de l’interactivité entre l’Arduino et son environnement.  Et c’est en utilisant un bouton poussoir que vous allez découvrir dans ce chapitre comment donner un premier sens à l’Arduino : le sens du toucher.

L'utilisation d'un bouton poussoir, et plus généralement d'un contacteur, va vous amener à gérer non plus les sorties, mais les entrées de la carte Arduino. Nous allons donc voir comment elles fonctionnent, comment on les programme, comment on en récupère les informations (il s'agit pour le moment de récupérer les informations des entrées numériques).

Vous allez voir comment connecter un bouton poussoir à la carte Arduino et comprendre l’intérêt des résistances pull-up et pull-down ; puis vous mettrez toutes ces connaissances à l’épreuve avec deux projets de pratique.

La routine quoi...

Les entrées numériques

Nous avons utilisé jusqu'à présent les sorties numériques : soit l'Arduino est en position haute (HIGH) et il envoie du +5V, soit il est en position basse, et il est à 0V, donc au ground.

Et bien les entrées numériques fonctionnent sur le même principe : soit elle reçoivent  du +5V ou du 0V.

Pour les sorties nous utilisions la commande digitalWrite(pin, état), qui est donc une commande d'écriture : write=écrire (Lukas, write is not white, right?)

Pour les entrées, nous utiliserons la commande digitalRead(pin), qui vous l'aurez peut-être deviné est une commande de lecture : read=lire.

Mais avant toute chose il faut comprendre une notion importante de l'Arduino : un pin est soit en entrée, soit en sortie, mais pas les deux. Il est donc important de bien définir si le pin va se comporter en entrée ou en sortie ! C'est ce que nous pouvons faire grâce à la commande que nous avons utilisée :

pinMode(pin, mode);

Où "pin" correspond au numéro de pin concerné, et mode correspond à la façon dont l’Arduino va gérer ce pin, c’est-à-dire :

  • mode OUTPUT :

    pinMode(pin,OUTPUT);

    pour indiquer à la carte que le pin doit être en mode écriture, c’est-à-dire qu’il peut envoyer ou non du courant. C’est donc une sortie.

  • mode INPUT :

    pinMode(pin,INPUT);

    pour indiquer que le pin est en mode lecture. Il ne va donc pas piloter du courant, mais être à l'écoute du courant qui va lui arriver.

Comment l'Arduino va nous dire ce qu'il "entend" en terme de courant ?

Et bien grâce à la commande digitalRead(pin), voici un morceau de code :

void setup()
{
    Serial.begin(9600); //Initialisation de la communication avec le moniteur série
    pinMode(10,INPUT); //On indique à l’Arduino le mode du pin (entrée)
}
void loop()
{
    boolean a=digitalRead(10);// et on l’affecte à la variable "a"
    Serial.println(a); // on l'affiche sur le moniteur
}

Ce code permet de lire la valeur reçue par le pin 10.

Saisissez-le et testez-le en ne connectant rien sur votre Arduino.

Dans le meilleur des cas, vous obtiendrez une série de 0. Dans le pire, vous obtiendrez des séries de 1 et de 0 qui changent sans raison valable.

C'est ce qu'on appelle un comportement erratique. C'est-à-dire que la valeur obtenue n'est pas fiable. Et ne vous y trompez pas, même si pour ce test, vous obtenez des 0, vous verrez que si vous ne cherchez pas à pallier ce comportement erratique, lors de vos projets, vous risquez d'avoir des comportements de la carte inattendus. Ce sera peut-être plus visible dans ce qui vient.

Le bouton poussoir

Un bouton poussoir peut se trouver sous plusieurs formes dans le commerce. Ceux qui nous intéressent pour le moment, et que j'espère vous avez en votre possession, est un bouton avec 4 pattes, une forme carrée, et un rond au centre qui est le bouton lui-même.

Un exemple de bouton poussoir
Un exemple de bouton poussoir

Le principe de ce bouton est que lorsque l'on appuie, le courant passe, et lorsque l'on relâche et bien... le courant ne passe plus !

Contrairement à un interrupteur, il ne garde pas la position (il faut garder le doigt dessus pour qu'il fasse contact). Voici un schéma de circuit :

Circuit avec diode et bouton poussoir
Circuit avec diode et bouton poussoir

Le bouton poussoir sert de pont. S'il est levé, le courant ne passe pas, on dit que le circuit est ouvert. S'il est baissé et donc relie les deux contacts, le courant passe, on dit que le circuit est fermé.

Vous pouvez tester le montage suivant avec votre Arduino. Il ne nécessite pas de programme :

Connection directe de la carte Arduino avec un bouton poussoir et une LED
Connection directe de la carte Arduino avec un bouton poussoir et une LED

Comme à chaque fois, observez le passage du courant. Le poussoir coupe ou non le circuit. 

Bon ce montage est en fait l'équivalent de ce que vous avez chez vous pour allumer la lumière : le courant passe si le contact est fait. Il n'y a aucune programmation. 

Comment utiliser un bouton par programmation ?

Tout simplement en le reliant à un pin qui est en mode lecture. Si le montage est correctement réalisé, en appuyant sur le bouton, l'Arduino va recevoir l'information et pourra agir en conséquence.

Pour comprendre, l'Arduino va pouvoir lire une valeur de +5V ou de 0V. Donc en théorie, si on envoie le +5V sur un poussoir, quand il est baissé, il laisse passer le courant et l'Arduino reçoit +5V, il indique donc HIGH (ou 1). Si le poussoir est ouvert, l'Arduino devrait ne rien recevoir, donc être à 0V et indiquer LOW (ou 0).

Voici le montage correspondant en connexion sur le pin 10 :

Montage pour lier un bouton poussoir au pin 10 par +5V
Montage pour lier un bouton poussoir au pin 10 par +5V

Nous pouvons maintenant écrire le programme qui affiche le résultat sur le moniteur. Essayez de le faire avant de regarder le code qui suit.

int pinBouton;
void setup()
{
    Serial.begin(9600);
    pinBouton=10;
    pinMode(pinBouton,INPUT);
}
void loop()
{
    boolean etatBouton=digitalRead(pinBouton);
    Serial.println(etatBouton);
}

Testez le programme... il y a un bug !

En effet, on voit bien s'afficher des 0, puis lorsqu'on appuie sur le bouton, on voit des 1 et en relâchant, et bien ça reste à 1 !

Ce qui ce passe c'est justement le côté erratique de notre montage. Si on observe bien, le pin 10, quand le bouton est levé, n'est finalement connecté à rien. Le résultat lu par l'Arduino est donc peu interprétable. Il existe un moyen de forcer l'Arduino à lire quelque chose, tout simplement avec l'ajout d'une résistance...

Résistance pull-down

Il faut savoir que l'électricité est paresseuse. Elle va toujours choisir le chemin qui lui résiste le moins. Mais si elle n'a pas le choix, elle passe tout de même là où ça résiste.

Nous allons donc ajouter une résistance à notre circuit. Une assez forte pour que le courant ne passe que s'il y est obligé (souvent de l'ordre de 10kΩ).

Résistance 10 KΩ montée en pull-down
Résistance 10 KΩ montée en pull-down

Que se passe-t-il dans ce circuit ?

Si le poussoir est baissé, le courant va du +5V au pin de l'Arduino. Il ne prendra pas le chemin du ground car la résistance lui demande un effort. Le pin de l'Arduino recevra du +5V et indiquera HIGH (ou 1).

Si le poussoir est levé, donc le circuit ouvert, le très faible courant résiduel qui sortira du pin de l'Arduino sera absorbé par le Gnd, le pin sera donc bien en LOW (ou 0).

Ce montage est à connaître, car quel que soit le type de contacteur que vous placerez en lecture sur un pin, il vous faudra prévoir ce comportement erratique.

Voici le montage sur l'Arduino :

Montage d'une résistance de 10KΩ en pullDown
Montage d'une résistance de 10 KΩ en pull-down

J'en ai profité pour vous montrer une autre façon de connecter le bouton poussoir : à cheval sur le centre de la breadBoard. C'est parfois utile pour un gain de place. Ça ne change rien au montage, je vous laisse observer le parcours du courant.

Si vous testez ce montage avec le programme, vous aurez maintenant un résultat qui correspond à nos attentes, c’est-à-dire que le moniteur affichera 1 lorsqu’on pousse le bouton, et 0 lorsqu’il est levé.

Résistance Pull-Up

Il est possible dans d'autres cas de monter la résistance, non pas vers le ground, mais vers le +5V. Il faut penser à connecter le poussoir au ground (et non plus au +5V)  pour que tout fonctionne.

Voici  donc le schéma, et le montage :

Résistance de 10 KΩ montée en pull-up
Résistance de 10 KΩ montée en pull-up

Et le montage sur l'Arduino :

Montage d'une résistance de 10KΩ en pull-Up
Montage d'une résistance de 10KΩ en pull-up
  • Quand le poussoir est ouvert, le +5V nourrit le pin de l'Arduino, qui donnera HIGH comme résultat.

  • Lorsqu'il est fermé, le +5V et le pin sont absorbés par le ground, le pin donnera LOW comme résultat.

Faites le test avec le programme précédent, vous verrez s'afficher 1 quand le bouton est levé et 0 quand il est baissé. Vous verrez que ça changera nos tests plus tard.

Le mode INPUT_PULLUP

Vous allez maintenant comprendre l'intérêt des explications précédentes ! (enfin j'espère...)

La carte Arduino propose par défaut un mode qui permet d'activer une résistance de 20 KΩ qui est dans la carte pour en faire une résistance pull-up. L'avantage est clair : pas besoin de se prendre la tête avec une résistance en plus. Il suffit de connecter correctement le bouton poussoir en mode pull-up.

Bouton poussoir connecté au pin 7 en mode INPUT_PULLUP
Bouton poussoir connecté au pin 7 en mode INPUT_PULLUP

Il faut aussi et surtout indiquer à l'Arduino d'activer cette résistance, on utilise la commande suivante :

pinMode(pin,INPUT_PULLUP);

Ce qui pour le montage de l'image précédente deviendrait  :

pinMode(7,INPUT_PULLUP);

 Vous voyez donc que la commandepinMode sert finalement à préparer un pin dans trois modes différents :

  • Mode OUTPUT : l'Arduino fournira par programmation du +5V ou du 0V.

  • Mode INPUT : l'Arduino lira l'état sur le pin concerné : HIGH (ou 1) pour +5 V reçus et LOW (ou 0) pour 0 V. Il faut prévoir le montage qui correspond.

  • Mode INPUT_PULLUP : l'Arduino lira les informations reçues, mais le pin sera connecté en interne (dans la carte elle-même) avec une résistance de 20KΩ en mode pull-up.

Et bien nous pouvons attaquer nos nos projets pratiques maintenant...

Programme "Jour/Nuit"

Les attentes de fonctionnement de ce programme sont simples...

  • Le montage contient un bouton poussoir connecté au pin 2 avec une résistance montée en pull-down ;

  • Une LED (LED1) connectée au pin 4 (pensez à la résistance) ;

  • Une LED (LED2) connectée au pin 6 (pensez à acheter du pain...) ;

  • Lorsque le bouton est levé, la LED1 est allumée, la LED2 est éteinte ;

  • Lorsque le bouton est appuyé, la LED1 est éteinte, la LED2 est allumée.

Vous avez tout ce qu'il faut pour réussir à programmer seul(e) cet exercice. Je vous laisse donc le plaisir de le faire...

Voici la solution pour le montage :

Montage des deux LED, du bouton et de la résistance en pull-down
Montage des deux LED, du bouton poussoir et de la résistance en pull-down

  et voici le code :

/*
le bouton poussoir est connecté au pin 2 avec une résistance pull-down de 10KΩ
les LED sont connectées au pins 4 et 6 avec des résistances de 220Ω
*/

//déclaration des variables
int pinBouton;
int pinLed1, pinLed2;
void setup()
{
  //initialisation des variables
  pinBouton = 2;
  pinLed1 = 4;
  pinLed2 = 6;
  //définition des modes
  pinMode(pinBouton, INPUT); //mode lecture pour le bouton
  pinMode(pinLed1, OUTPUT); //mode écriture pour led1
  pinMode(pinLed2, OUTPUT); //mode écriture pour led2

}
void loop()
{
  //lecture de l'état du bouton et stockage dans etatBouton
  boolean etatBouton = digitalRead(pinBouton);
  //test des conditions
  if (etatBouton==HIGH)//test si bouton appuyé
  {
    digitalWrite(pinLed1,LOW); //led1 éteinte
    digitalWrite(pinLed2,HIGH); //led2 allumée
  }
  if (etatBouton==LOW)//test si bouton levé
  {
    digitalWrite(pinLed1,HIGH); //Led1 allumée
    digitalWrite(pinLed2,LOW); //led2 éteinte
  }
  delay(100); //petite attente
}

Quelques informations complémentaires sur ce code...

  •  int pinLed1,pinLed2; : on peut très bien déclarer plusieurs variables à la suite séparées d'une virgule ; 

  •  boolean etatBouton = digitalRead(pinBouton); : le type boolean est tout à fait approprié pour la variable état bouton qui ne prend que les valeurs 1 ou 0 (HIGH ou LOW) ;

  • if (etatBouton==HIGH)  etif (etatBouton==LOW) : lorsque l'on teste l'état du bouton, il est tout à fait possible de remplacer HIGH par 1 et LOW par 0. Il est même possible comme vu dans les chapitres précédents d'écrire :

if (etatBouton)
{
   //code à effectuer 
}
  • delay(100); : il est conseillé de toujours laisser un peu de temps à l'Arduino avant de refaire une boucle, surtout lorsque des données sont lues.

Il est enfin possible, pour éviter la succession des deux conditions "if" d'utiliser une méthode de tests combinés, voici un code qui le montre :

if (test)
{
    //code à exécuter
}
else if (autreTest)
{
    //autre code
}
else 
{
    //code exécuté si aucun test n'est vérifié
}

"else" signifie "sinon". Nous aurons l'occasion de revenir sur ce point plus tard. Mais je vous livre le code du programme "Jour/nuit" modifié avec les points que nous venons de voir. Observez les lignes 7, 25 et 30 :

/*
le bouton poussoir est connecté au pin 2 avec un résistance pull-down
les leds sont connectées au pins 4 et 6 avec des resistances de 220Ω
*/

//déclaration des variables
int pinBouton, pinLed1, pinLed2;
void setup()
{
  //initialisation des variables
  pinBouton = 2;
  pinLed1 = 4;
  pinLed2 = 6;
  //définition des modes
  pinMode(pinBouton, INPUT);
  pinMode(pinLed1, OUTPUT);
  pinMode(pinLed2, OUTPUT);

}
void loop()
{
  //lecture de l'état du bouton et stockage dans etatBouton
  boolean etatBouton = digitalRead(pinBouton);
  //test des conditions
  if (etatBouton)//si bouton appuyé (donc 1)
  {
    digitalWrite(pinLed1,LOW);
    digitalWrite(pinLed2,HIGH);
  }
  else //sinon
  {
    digitalWrite(pinLed1,HIGH);
    digitalWrite(pinLed2,LOW);
  }
  delay(100);
}

Bien, ce programme commence à bien plus interagir avec notre Arduino. Nous verrons plus tard, qu'à la place d'un poussoir, il peut y avoir un système de détection par lumière, ou un contacteur type moustache de chat pour un robot...

Allez, un dernier programme pour bien asseoir nos connaissances !

Programme "Interrupteur"

L'objectif de ce programme est à nouveau facile à décrire :

  • Le bouton poussoir est connecté au pin 2 en mode INPUT_PULLUP ;

  • Une LED est connectée au pin 4 ;

  • Quand on appuie une fois sur le bouton, la LED s'allume (et reste allumée) ;

  • Lorsqu'on appuie à nouveau, la LED s'éteint (et reste éteinte).

Allez ! Go ! Go ! Go !

Solution

Voici le montage :

Montage d'un bouton en pull-up sur pin 2 et d'une diode sur pin 4
Montage d'un bouton en pull-up sur pin 2 et d'une diode sur pin 4

Et voici le code. ;)

/*
le bouton poussoir est connecté au pin 2 pour un mode INPUT_PULLUP
la Led est connectée au pins 4 avec une résistance de 220Ω
*/

//déclaration des variables
int pinBouton, pinLed;
boolean etatAllumage;
void setup()
{
  //initialisation des variables
  Serial.begin(9600);
  pinBouton = 2;
  pinLed = 4;
  etatAllumage=0;
  //définition des modes
  pinMode(pinBouton, INPUT_PULLUP);
  pinMode(pinLed, OUTPUT);
}
void loop()
{
  Serial.print(etatAllumage);
  
  if (etatAllumage) //on teste si etatAllumage est à 1
  {
    digitalWrite(pinLed, HIGH);//on allume la LED
  }
  else //sinon
  {
    digitalWrite(pinLed, LOW); //on éteint la LED
  }
  //lecture de l'état du bouton et stockage dans etatBouton
  boolean etatPinBouton = digitalRead(pinBouton);
  Serial.println(etatPinBouton);
  //test des conditions
  if (!etatPinBouton)//si bouton appuyé (donc le pin indique 0 car il est en mode INPUT_PULLUP)
  {
    if (etatAllumage) //si etatAllumage à 1
    {
      etatAllumage=0; //on le passe à 0
    }
    else //sinon
    {
      etatAllumage=1; //on le passe à 1
    }
  }
  delay(200);
}

On remarque que le programme n'est pas si simple. Nous verrons plus tard comment le rendre plus concis.

J'attire votre attention sur la ligne 36 : on utilise le point d'exclamation "!" devant la variable. Ça veut dire "non" en informatique donc !etatBouton, veut dire "non etatBouton=1" traduit pour l'humain : si etatBouton n'est pas égal à 1. Donc écrire  if(!etatPinBouton)  revient à écrire  if(etatPinBouton!=1) , c’est juste plus rapide !

Le test de ce programme n'est pas très agréable. En effet, l'appui prolongé sur le bouton, ou des appuis plus ou moins longs modifient l'allumage de la diode.

C'est toujours une question de rapidité de la machine par rapport à l'humain : si l'on maintient appuyé, la boucle se répète et passe la variable  etatAllumage de  0 à 1 sans arrêt.

Pour résoudre ce problème, il faudrait ajouter une variable qui teste si le bouton a été relâché entre-temps. C'est d'ailleurs un très bon exercice de programmation. :soleil:

Exemple de certificat de réussite
Exemple de certificat de réussite