LOCODUINO

Bouton poussoir

.
Par : Dominique, Guillaume, Jean-Luc

DIFFICULTÉ :

Nombreux sont les montages Arduino qui nécessitent des organes d’interaction entre l’utilisateur et le programme. Le Bouton Poussoir en est un parmi les plus importants : la preuve, toutes les cartes Arduino disposent d’un bouton de Reset !

Introduction

Les boutons poussoirs sont des interrupteurs temporaires : sitôt relâché, le BP (abréviation de Bouton Poussoir) revient à sa position de base, contrairement au commutateur qui peut avoir 2 positions stables ou plus.
Ils sont associés à des contacts électriques et l’appui sur le bouton modifie l’état du contact : il l’établit ou le rompt. En relâchant le bouton, c’est l’inverse qui se produit.

Ce sont des interrupteurs (au sens large, ce terme inclus les poussoirs !) qui vont nous fournir énormément de possibilités dans le modélisme. C’est un composant peu onéreux qui pourra donc servir dans de multiples cas.

Types de Bouton Poussoir

Il existe deux types :

  • le BP normalement ouvert NO : le courant à l’état de base du BP ne passe pas, le circuit est ouvert. En appuyant le circuit devient fermé.
  • BP normalement fermé NF : le courant à l’état de base du BP passe, le circuit est fermé. En appuyant, le circuit devient ouvert.

    A l’état appuyé, le circuit va donc changer d’état, qui sera opposé à l’état de base..

Exemples de BP

Ceci est un BP à souder très répandu. Nous voyons quatre pattes qui sont reliées deux à deux. Une des manières de savoir lesquelles font partie d’une même paire est d’utiliser un multimètre. Mais il suffit de connecter deux pattes en diagonale pour être certain de prendre une patte de chaque paire et ainsi nul besoin de multimètre.
Toutefois, c’est quand même mieux de vérifier !

Les BP peuvent revêtir de nombreuses formes :

Reconnaître le type NO ou NF d’un BP est facile. Connectons en série une résistance de 330 Ohms, une Led et le BP à tester (en prenant les pattes aux diagonales comme indiqué plus haut) et appliquons une tension de 5V environ (une pile de 4,5V fera bien l’affaire).

Si la LED s’allume, c’est un BP normalement fermé et si elle reste éteinte, c’est un BP normalement ouvert.

Des boutons poussoirs qui n’en sont pas mais fonctionnent de la même façon

Ce titre étrange ne sert qu’à attirer votre attention sur d’autres dispositifs qui seront gérés par votre logiciel comme des boutons poussoirs : cet article est bien plus général qu’il en a l’air !

On trouve ici des ILS (interrupteurs à lame souple), des contacts de relais, des détecteurs d’occupation (la sortie d’un opto-coupleur se comporte comme un BP). Nul doute que vous en trouverez d’autres.

Connecter un BP à une broche de l’Arduino

Le but de cette connexion est d’indiquer qu’on appuie ou non sur le BP en faisant changer d’état (haut ou bas) une broche de l’Arduino.

On relie donc une des pattes du BP à la broche choisie de l’Arduino.

Et à quoi relie-t-on l’autre broche ?

Il y a plusieurs possibilités :

1/ BP relié au 5V

Selon ce schéma, lorsque le contact du BP est fermé, on amène le 5V sur la broche 5. Et lorsque le contact est ouvert, il faut "tirer" la broche 5 au 0V à l’aide d’une résistance (10K c’est bien). On l’appelle alors « résistance de pull down ».

Le but est de ne jamais laisser la broche de l’Arduino « en l’air », c’est à dire non connectée pendant qu’elle est définie comme une entrée : elle se comporterait alors comme une antenne qui capterait tous les parasites environnantes, votre programme se sentirait mal et vous ne comprendriez pas pourquoi.

L’initialisation de la broche de l’Arduino est :

pinMode(bp, INPUT);

Ce n’est pas mon schéma préféré !

2/ BP relié au 0V avec résistance de pull-up au +5V

Une résistance de pull-up est une résistance comme les autres. Elle permet de fixer l’entrée numérique à l’état haut lorsque rien n’est connecté pour ne pas rester « en l’air », comme indiqué ci-dessus.

L’initialisation de la broche de l’Arduino se fait de la même manière que précédemment.

Ce n’est pas non plus mon schéma préféré, parce que les Arduino actuels comportent une résistance de pull-up interne, donc déjà intégrée dans le processeur.

Nous pouvons donc faire l’économie de la résistance (il n’y a pas de petites économies !!).

Dans ce cas, pour utiliser cette résistance de pull-up, il faut déclarer l’entrée de cette façon :

pinMode(bp, INPUT_PULLUP);

Un BP, ça rebondit énormément !

Quand le BP est appuyé, l’état change sur la broche de l’Arduino, il passe de 0 à 5V ou inversement selon le type de BP ou le type de branchement. Mais entre les deux états, la transition n’est pas instantanée et il y a une phase de rebonds qui dure quelques millisecondes et qui est due au choc entre les contacts métalliques un peu élastiques.

D’où des changements d’états très rapides qui sont captés par l’Arduino, et qui peuvent entraîner des erreurs. Dans le cadre d’un compteur, pour le réglage de l’heure par exemple, un seul appui pourra être compté comme plusieurs à cause de ce phénomène.

Pour l’éviter, un condensateur de 100 nF en parallèle sur le BP, pourra être employé. Mais la valeur du condensateur doit être déterminée expérimentalement, les BP étant tous différents sur ce plan.

Il existe heureusement une autre méthode purement logicielle. Elle consiste à lire l’état de la broche et la stocker dans une variable, d’attendre quelques millisecondes et de lire une nouvelle fois la broche en la comparant à la valeur stockée. Si la valeur est la même, l’appui est confirmé.

Code

Venons-en à la partie intéressante, l’Arduino est relié aux composants selon le schéma précédent (même broche 5). La lecture de l’état de la broche impose donc de mettre la broche en entrée avec pull-up lors du setup. La lecture se fera lors de chaque boucle de loop et sera comparée à une valeur pour entraîner une action en fonction de l’appui ou non du BP.

Nous allons donc transférer dans l’Arduino, un code qui allumera une Led à savoir la diode de la broche 13 quand le BP sera appuyé (si BP normalement ouvert)

// Déclaration des broches
const byte del = 13;
const byte bp = 5;

void setup()
{
  // programmation des broches
  pinMode(del, OUTPUT);
  pinMode(bp, INPUT_PULLUP);
  // extinction de la LED
  digitalWrite(del, LOW);
}

void loop()
{
  if (digitalRead(bp) == LOW) // poussoir enfoncé
  {
    digitalWrite(del, HIGH);
  }
  else
  {
    digitalWrite(del, LOW);
  }
}

L’appui sur le bouton allume la LED si le BP est normalement ouvert et vice-versa.
Si certaines portions de code vous semblent obscures, reportez aux articles de la rubrique programmation : ici et , cela devrait vous aider.

Ce programme ne traite pas les rebonds dans ce cas simple de commande d’une Led.

L’anti-rebond avec la bibliothèque Bounce2

La bibliothèque à jour pour traiter cette question est Bounce2 que l’on peut télécharger ici : Bounce2

Une fois installée ( voir l’article "Installer une bibliothèque"), voici comment s’en servir :

// Intégration de la bibliothèque dans le code :
#include <Bounce2.h>

const byte del = 13;
const byte bp = 5;

// Création d'un objet Bounce que j'appelle bouton
Bounce bouton; 

void setup() {

  pinMode(del,OUTPUT);
  pinMode(bp,INPUT_PULLUP);

  // definition des paramètres de l'objet Bounce
  bouton.attach(bp);   // la broche du bouton poussoir
  bouton.interval(10); // l'intervalle de temps en ms

}

void loop() {
  // l'objet Bounce doit exécuter son code interne à chaque loop :
  bouton.update();

  // Lire la valeur du bp filtré :
  int value = bouton.read();

  // commande de la led en conséquence :
  if ( value == LOW ) {
    digitalWrite(del, HIGH );
  } 
  else {
    digitalWrite(del, LOW );
  }
}

Cette bibliothèque Bounce2 offre bien plus de possibilités que ce qui est décrit ci-dessus. Nous vous invitons à étudier les exemples qui sont fournis.

21 Messages

  • Bouton poussoir 1er janvier 2016 21:26, par tanguy

    Bonjour et bonne année,

    dans l’extrait de code
    Bounce bouton = Bounce() ;
    à quoi sert la deuxième partie " = Bounce()" ?

    Répondre

    • Bouton poussoir 2 janvier 2016 10:26, par Jean-Luc

      Bonjour et meilleurs vœux pour 2016.

      Ça ne sert pas à grand chose. D’ailleurs je l’ai supprimé. Dans les deux cas, le constructeur sans argument de Bounce est appelé.

      Répondre

    • Bouton poussoir 2 janvier 2016 10:38, par Thierry

      Bonjour
      Lors de la déclaration d’une instance (un exemplaire) de la classe Bounce nommée ’bounce’, il est possible de faire appel au constructeur que l’on veut plutôt que de faire automatiquement appel à celui par défaut. La notation employée ici est inutile puisque l’on appelle quand même le constructeur par défaut sans arguments ! Il s’agit là du code officiel de l’exemple ’Bounce’ livré avec la bibliothèque Bounce2...

      Répondre

  • Bouton poussoir 2 janvier 2016 10:38, par Thierry

    haaaa . Grilled ! :)

    Répondre

  • problèmes de rebond , Bouton poussoir 30 mars 2017 09:20, par Almamy

    Bonjour, actuellement je cherche à mettre en pause l’affichage sur mon joulemètre qui reçoit les valeurs d’un emetteur NRF24L01 . Ce pendant quand j’appuie sur le bouton, il fonctionne correctement mais au fur et à mesure ce problème de rebond est de plus en plus fréquent. J’utilise la bibliothèque Bounce2 et un trigger de schmitt, mais rien à faire. Lorsque je relie la pin qui reçoit l’information du bouton au trigger, le basculement se fait automatiquement, pouvez-vous m’aider ?

    Voici mon programme :

    #include <Bounce2.h>
    #include <PinChangeInt.h>
    #include <LiquidCrystal.h>
    //////////////////////////////////////////////
    #include <SPI.h>
    #include <Mirf.h>
    #include <MirfHardwareSpiDriver.h>
    #include <MirfSpiDriver.h>
    #include <nRF24L01.h>
    //////////////////////////////////////////////////////
    float energy;
    float times;
    float paramValues[2]={0};
    int timesS;
    int timesM;
    ////////////////////////////////////////////////////////////
    //int pinBouton;
    boolean etatRecu;
    const byte pinBouton =6;
    Bounce bouton = Bounce();
    ////////////////////////////////////////////////////////////
    LiquidCrystal lcd(8,7,5,4,3,2);
    void setup() {
      // put your setup code here, to run once:
    Serial.begin(9600);
    etatRecu=0;
    bouton.attach(pinBouton);
    bouton.interval(5);
    pinMode(pinBouton, INPUT);
    PCintPort: attachInterrupt(pinBouton,tour,CHANGE);
    ////////////////////////////
    Mirf.cePin=9;
    Mirf.csnPin=10;
    Mirf.spi=&MirfHardwareSpi;
    Mirf.init();
    Mirf.channel=1;
    Mirf.payload=sizeof(paramValues) ;
    Mirf.config();
    Mirf.configRegister(RF_SETUP,00100110);
    //Mirf.configRegister(CONFIG,01111011);
    Mirf.setTADDR((byte*)"nrf01");
    Mirf.setRADDR((byte*)"nrf02");
    //////////////////////////////
    lcd.begin(16,2);
    //////////////////////////////
    
    }
    
    void loop() {
      bouton.update();
      tour();
      //Serial.println(etatRecu);
      if (etatRecu){
     if(Mirf.dataReady()){
      Mirf.getData((byte*)&paramValues);
      energy = paramValues[0];
      times = paramValues[1];
      timesM=times/60;
      timesS= times-60*timesM;
     }
      
      //Serial.print("Energy:");
       Serial.println(energy);
     // Serial.print("Time:");
      Serial.print(timesM);
      Serial.print(":");
      Serial.println(timesS);
      Serial.println("pause");
     }
    
      
    else  {
       if(Mirf.dataReady()){
      Mirf.getData((byte*)&paramValues);
      energy = paramValues[0];
      times = paramValues[1];
      timesM=times/60;
      timesS= times-60*timesM;
      
       }
      //Serial.print("Energy:");
      Serial.println(energy);
     // Serial.print("Time:");
      Serial.print(timesM);
      Serial.print(":");
      Serial.println(timesS);
     //}
     lcd.print("Energy:");
    lcd.setCursor(8,0);
    lcd.print(energy,3);
    lcd.setCursor(15,0);
    lcd.print("J");
    lcd.setCursor(0,1);
    lcd.print("Time");
    lcd.setCursor(5,1);
    lcd.print(timesM);
    lcd.setCursor(8,1);
    lcd.print(":");
    lcd.setCursor(9,1);
    lcd.print(timesS);
    
     lcd.home();
    Serial.println("marche");
    }
    
    }
    
    void tour(){
     int etatPinBouton= bouton.read();
     //digitalRead(pinBouton); 
     //=bouton.read();
    int memoire= HIGH;
    
    //Serial.println(etatPinBouton);
    
     //(etatPinBouton!=memoire)&&(!etatPinBouton)à remettre dans la boucle
    
    if(etatPinBouton==LOW){//bouton appuyé en pull up
      
      if(etatRecu){
        etatRecu=0;
      }
      else{
        etatRecu=1;
      }
    } 
    }

    Cordialement

    Répondre

  • Bouton poussoir 13 juillet 2017 21:17, par Jacques

    Bonjour Dominique, Guillaume et Jean-Luc,
    Cet article est génial car il explique clairement comment utiliser la bibliothèque Bounce2.
    Merci à tous,
    Jacques

    Répondre

  • Bouton poussoir lumineux 25 septembre 2018 17:34, par Pascal

    Bonjour,
    Pour aller plus loin avec cet article très intéressant sur les boutons poussoir, existe-t-il des boutons poussoirs avec une led RVB intégrée qui permettrait par exemple de passer d’une couleur verte pour dire bouton activable à rouge pour bouton inutilisable ?
    D’avance merci pour votre réponse
    Cordialement
    Pascal

    Répondre

    • Bouton poussoir lumineux 27 septembre 2018 08:35, par dominique

      Un tel bouton n’existe pas tel que vous le décrivez. Mais il existe des boutons avec leds intégrées, en cherchant sur le net.

      Ensuite c’est à vous de piloter les leds avec un Arduino.

      Répondre

    • Bouton poussoir lumineux 30 septembre 2018 12:11, par Laurent

      Bonjour,

      J’ai eu besoin d’utiliser ce type de boutons pour un montage en cours.

      J’ai commandé des boutons de borne d’arcade sur Arcade World.

      J’ai ensuite remplacé la led par une rvb (il faut modifier le support de led pour pouvoir faire passer tous les fils).

      Attention, les boutons peuvent être commandés complets (avec led, support de led et contacteur), ou bouton seul (pour dépannage).

      Voir en ligne : Arcade World

      Répondre

      • Bouton poussoir lumineux 1er octobre 2018 08:27, par Pascal

        Merci beaucoup pour ces informations (et pour l’adresse web, ou finalement pas besoin de faire trop de bricolage car ça existe déjà..... cf : lien ci dessous)

        Voir en ligne : bouton lumineux RGB

        Répondre

  • Bouton poussoir 1er octobre 2018 07:02, par Pascal

    Merci pour ces informations
    Maintenant yapluk....

    Répondre

  • Bouton poussoir 8 janvier 2019 17:06, par Roland Codaccioni

    bonjour,
    Je suis sur un projet de plaque tournante HO avec les données suivantes :
    une carte Arduino uno, un moteur step 5V DC ref 28BYJ -48 avec son module de branchement, un bouton pressoir pour faire tourner le moteur dans un sens et un autre BP pour aller dans l’autre sens de manière à aligner les rails par petites impulsions avant arrière.
    Je parviens bien à faire tourner le moteur en suivant les instructions de câblage mais impossible d’arriver à inclure les 2 BP dans ce processus.
    Avez vous un schéma qui permettrait de résoudre ce problème SVP ?
    Merci d’avance
    Cordialement RC

    Répondre

    • Bouton poussoir 14 février 2020 12:58, par Fina

      Il me semble que pour le plateau tournant
      Un potentiomètre serait plus utile :
      On tourne de chaque côté le potar pour un nombre de pas du moteur
      ...

      Répondre

  • Bouton poussoir 21 novembre 2021 19:11, par Claude49

    Bonjour
    Sur mon réseau, je refais mon TCO. J’utilise donc des boutons poussoirs. Quand ils sont activés ils déclenchent une interruption....d’où la gestion des rebonds. Je viens de "tomber" sur la bibliothèque Bounce 2...ça me plait bien. Ma question dois je déclarer une instance Bounce pour chacun des boutons du genre
    ( si B1, B2, B....sont des boutons) :
    Bounce B1 = Bounce() ;
    Bounce B2 = Bounce() ;
    Bounce B3 = Bounce() ;

    void setup()

    B1.attach(pinBouton) ;
    B1.interval(5) ;
    pinMode(pinB1, INPUT) ;

    B2.attach(pinBouton) ;
    B2.interval(5) ;
    pinMode(pinB2, INPUT) ;

    B3.attach(pinBouton) ;
    B3.interval(5) ;
    pinMode(pinB3, INPUT) ;

    Mis à part les instructions attach et pinMode, doit on tout répéter

    Merci

    Répondre

  • Bouton poussoir 21 novembre 2021 20:04, par Dominique

    Oui. Regardez les exemples de la bibliothèque !

    Répondre

    • Bouton poussoir 22 novembre 2021 17:05, par Claude49

      Merci
      Il fallait aller dans /examples/more.....on ne va jamais au fond des choses

      Répondre

  • Bouton poussoir 10 octobre 2022 14:34, par Olivier

    Bonjour,
    Je gère un moteur PAP avec des pulses de l’ordre de 60 ms, tout en veillant les appuis potentiels sur des bp de contrôle et d’autres actions. Je n’ai donc pas droit à des interruptions de programme pour débouncer mes bp. Est-ce que Bounce2 induit des interruptions dans le PG ou conserve-t-il dans une mémoire les valeurs lues pour comparaison avant validation d’appui ? Merci pour la réponse.

    Répondre

    • Bouton poussoir 10 octobre 2022 14:58, par msport

      Bonjour,

      un petit tour dans la bibliothèque Bounce2 permet de lire (Bounce2,h) :

      Because Bounce does not use interrupts, you have to "update" the object before reading its value and it has to be done as often as possible (that means to include it in your loop()). Only call update() once per loop().

      Cordialement

      Répondre

      • Bouton poussoir 10 octobre 2022 16:06, par Olivier

        Vitesse de réponse impressionnante !! Si je comprends bien il garde en mémoire le premier état et le compare jusqu’à la tempo désirée sans stand-by.je peux donc l’insérer dans ma routine, c’est bien ça ? (Merci encore)

        Répondre

Réagissez à « Bouton poussoir »

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 « Matériel »

Les derniers articles

Les articles les plus lus