Le bouton poussoir

Un Boutonbouton poussoir est un interrupteur (ou contacteur) monostable : il retourne seul dans la position repos (« relâché »).

Il peut être :

  • à fermeture = ouvert au repos :
  • à ouverture = fermé au repos : 

Sur un schéma, on représente toujours les boutons au repos !

 

Câblage

 

Sur la platine

Certains boutons peuvent être fichés sur une breadboard. Attention à bien enfoncer les pattes, sans les tordre !

Schéma électrique interne :

 

 

Sur l’Arduino

Un bouton poussoir fournit une information logique (Appuyé / Relâché). Il doit donc être raccordé à un port numérique configuré en mode INPUT.

Remarque : quand le bouton est relâché, pour ne pas laisser flottante l’entrée du port (cas d’un interrupteur mécanique par exemple), il est nécessaire d’utiliser une résistance de rappel (pull down) ou de tirage (pull up) .

Les montages ci-dessous permettent de fournir au port numérique D :

Résistance de rappel

  • 0V quand le bouton est relâché : état bas = LOW
  • 5V quand le bouton est appuyé : état haut = HIGH

Résistance de tirage

  • 5V quand le bouton est relâché : état haut = HIGH
  • 0V quand le bouton est appuyé : état bas = LOW

Remarque : un léger courant \(I=\frac{5}{10 000}\;\text{A}\) circule dans la résistance, lorsque le bouton est appuyé.

 

 

Résistances de tirage intégrées à l’Arduino

Certains microcontrôleurs, comme l’Arduino UNO par exemple, sont équipés de résistances de tirage, incluses dans le circuit intégré.

Cela permet de simplifier les câblages :

Pour les activer, il faut le préciser lors du réglage du mode du port numérique :

pinMode (D, INPUT_PULLUP);

 

 

Programmation

Un bouton n’est pas un objet parfait : lorsqu’on agit dessus (appuyer ou relâcher), le signal ne commute pas parfaitement de 5V à 0V (ou le contraire). Il peut se passer quelques millisecondes pendant lesquelles le signal va « rebondir » avant de se stabiliser. Ce rebond peut provoquer un comportement inattendu du programme (comptage d’appuis en trop, arrêt ou démarrage prématuré de procédures, …).

 

Il existe diverses solutions pour éviter cela…

 

En filtrant le signal

Une des solutions est d’utiliser un condensateur (en parallèle avec l’interrupteur) et une résistance (en série avec l’interrupteur). Le condensateur permet d’absorber les rebonds en se déchargeant progressivement. La commutation du port numérique n’a lieu qu’une fois le condensateur suffisamment déchargé, soit un peu après la commutation du bouton (temps qui dépend de la valeur de la résistance en série et de la capacité du condensateur).

Avec ce montage on peut programmer l’utilisation d’un bouton de la manière suivante :

int pin_LED = 13;   // port numérique associé à la LED intégrée
int pin_button = 2; // port numérique lié au bouton poussoir
int state = LOW; // variable d'état de la LED

void setup() {
   pinMode(pin_LED, OUTPUT);   // réglage du port de la LED en mode SORTIE
   pinMode(pin_button, INPUT); // réglage du port du bouton en mode ENTREE
}

void loop() {
   if (digitalRead(pin_button) == HIGH) { // si le bouton est pressé ...
      state = !state; // ... inversion de la variable d'état de la LED (allumée<->éteinte)
   }
   digitalWrite(pin, state); // action sur la LED (allumage ou extinction)
   
   // Suite du programme ... simulé par une instruction d'attente
   delay(100);
}

 

Il reste néanmoins un inconvénient à cette solution : si la durée d’exécution de la boucle loop()est trop long, il peut arriver qu’un utilisateur appuie pendant un temps si court que l’instruction qui teste de l’état du bouton (if (digitalRead(pin_button) == HIGH)) n’a pas le temps de « voir » cet appui.

Activité
Tester le programme ci-dessus avec une attente de 1s … et constater le problème …

 

En utilisant une interruption

Les microcontrôleurs Arduino possèdent des ports supportant les interruptions matérielles : une commutation d’un de ses ports (parmi ceux dédiés à cette fonctionnalité), provoque l’arrêt de l’exécution du programme pour faire une tâche particulière (en exécutant une fonction), puis retourner à l’exécution normale du programme.

Pour mettre en place une interruption, on utilise la fonction attachInterrupt qui attend 3 arguments :

  • le numéro de l’interruption. Pour un Arduino UNO :
    • 0 : port numérique 2
    • 1 : port numérique 3
  • la fonction à exécuter
  • le mode de l’interruption, c’est à dire quand l’interruption doit être déclenchée :
    • LOW pour déclencher l’interruption chaque fois que la broche est basse,
    • CHANGE pour déclencher l’interruption chaque fois que la broche change de valeur,
    • RISING pour déclencher l’interruption lorsque la broche passe de basse à haute,
    • FALLING pour déclecher l’interruption lorsque la broche passe de haute à basse.

La fonction exécutée à chaque événement sur le port de l’interruption s’appelle une ISR (Interrupt Service Routine). Elle doit être courte pour ne pas interrompre le programme trop longtemps, et les variables globales qui y sont modifiées doivent être « volatiles », c’est à dire précédées de la mention volatile lors de leur déclaration.

Dans une ISR, les fonctions delay et millis ne fonctionnent pas !

 

int pin_LED = 13;    // port numérique associé à la LED intégrée
int pin_button = 2;  // port numérique lié au bouton poussoir
volatile int state = LOW; // variable d'état de la LED (précédée de volatile !!)

void setup() {
   pinMode(pin_LED, OUTPUT);    // configuration du port de la LED en mode SORTIE
   pinMode(pin_button, INPUT_PULLUP);  // configuration du port du bouton en mode ENTRÉE
   // Création de l'interruption
   attachInterrupt(0, blink, CHANGE);
}

void loop() {
   digitalWrite(pin_LED, state); // action sur LED (allumage ou extinction)

   // Suite du programme ... simulé par une instruction d'attente
   delay(100);
}

void blink() {
   state = !state; // inversion de la variable d'état de la LED
}

Dans l’exemple précédent, un changement d’état du bouton (le mode de déclenchement de l’interruption étant défini par la constante CHANGE), provoquera aussitôt l’arrêt de l’exécution du programme pour exécuter la fonction blink(), et ensuite retourner au programme…

Le dernier argument de la fonction attachInterrupt définit le mode de l’interruption, c’est à dire quand l’interruption doit être déclenchée :

  • LOW pour déclencher l’interruption chaque fois que la broche est basse,
  • CHANGE pour déclencher l’interruption chaque fois que la broche change de valeur,
  • RISING pour déclencher l’interruption lorsque la broche passe de basse à haute,
  • FALLING pour déclencher l’interruption lorsque la broche passe de haute à basse.

 

Vous aimerez aussi...

6 réponses

  1. Ben dit :

    Bonjour, petite coquille dans votre article « Une des solutions est d’utiliser un condensateur en parallèle avec le bouton. » cependant l’image qui suit sur le câblage montre le condensateur en parallèle avec la résistance. Cela est trompeur et n’a pas le même effet d’un placement à un l’autre du condensateur.

    Cdlt

  2. Jl dit :

    Bonjour,
    où est déclarée la constante CHANGE et je ne comprends pas qu’un constante puisse changer d’état.
    Cdlt

  3. Stéphane dit :

    Bonjour,
    Je pense qu’il y a dû y avoir des changements sur la page depuis le commentaire de Ben.
    Malheureusement, les chronogrammes ne correspondent pas au schéma ; ce serait le cas si C était en parallèle à R. Dans le cas où C est en parallèle à l’interrupteur et que celui-ci est ouvert depuis « suffisamment longtemps », on à le potentiel en D_ qui est nul et le condensateur chargé sous 5V. Lorsque l’on ferme l’interrupteur, le potentiel en D_ passe « instantanément » à 5V et C est « instantanément » déchargé (« instantanément » car la constante de temps est quasi nulle si on considère la résistance de contact de l’interrupteur négligeable).

Répondre à Jl Annuler la réponse

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *