RPI#2 : 2 boutons

Posted on Sun 20 October 2013 in misc

Le montage

Voici le montage, les boutons poussoir sont connectés sur les ports GPIO #18 (pin 12) et GPIO #23 (pin 16).

<http://tristan.lt/images/rpi-2-2-boutons/image>`__

Configuration des inputs

Nous allons donc utiliser les pin 16 et 12 au sens GPIO.BOARD ou les n° GPIO #18 et #23 au sens GPIO.BCM. La commande suivante permettant de placer le pin 16 en mode entrée.

GPIO.setup(button_pin1=16, GPIO.IN)

Pull up, down ou pas...

Un port GPIO en entrée peut être configuré pour avec une tolérance, ceci afin de ne pas réagir aux interférences qu'il est succeptible de recevoir. Nous avons fait un montage Pull-Down afin de protéger l'entrée de ce type d'interférences.

Voir : http://www.coactionos.com/embedded-design/28-using-pull-ups-and-pull-downs.html

Utilisation des Callbacks

La méthode la plus simple serait de vérifier toutes les microsecondes la valeur de notre input comme cela :

while True:
    if GPIO.input(button_pin1):
          print('Bouton 1 enfoncé')
    if GPIO.input(button_pin2):
          print('Bouton 2 enfoncé')

Cette technique fonctionne mais présente 2 désagréments

  • Il faut mettre en place du code pour ne détecter que l'appuie
  • La consommation CPU monte en flêche
  • Plutôt que d'occuper notre CPU a vérifier l'état des boutons, une bonne méthode serait de configurer une interruption lors de l'appui sur celui-ci.
def button_one(channel):
 print('Bouton 1 presse !')

GPIO.add_event_detect(button_pin1, GPIO.RISING)
GPIO.add_event_callback(button_pin1, button_one, bouncetime=1000)

Nous commençons par définir une fonction (ici button_one). Ensuite il s'agit de branché le signal de l'évennement sur notre fonction. GPIO.add_event_detect permet de dire s'il l'événement est déclenché sur un front montant (appuie) ou descendant (relâchement) d'un bouton, dans le cas d'un poussoir normalement ouvert. GPIO.add_event_callback permet de branché l'événement configuré pour notre bouton sur la fonction que nous avons établis.

bouncetime

L'attribut bouncetime permet de gommer les imperfections physiques des interrupteurs. En effet, à moins d'un interrupteur parfait, lors d'un appui, le port reçoit un signal qui peux générer plusieurs événements... Fâcheux, mais l'attribut bouncetime permet de ne pas prendre en compte les nouveaux événements pour le délai définit (en milisecond). Trop court nous risquons de générer plusieurs événements, trop long et il faut attendre pour cliquer sur le boutons plusieurs fois.

Notez que ce de-bounçage aurai pu être réaliser grâce a un condensateur bien placé (mais où? :) ) .

Le code

#!/usr/bin/env python3
#-*- coding: utf-8 -*-

import RPi.GPIO as GPIO,time
import signal, sys

DEBUG = 1
GPIO.setmode(GPIO.BOARD)


button_pin1 = 16
GPIO.setup(button_pin1, GPIO.IN)
button_pin2 = 12
GPIO.setup(button_pin2, GPIO.IN)

# Definition d'une fonction qui est appelée lors du ctrl+c
# celle-ci remet a zero les bus du RPI
def stop(signal, frame):
 print('SIGINT > Sortons !')
 GPIO.cleanup()
 sys.exit(0)

def button_one(channel):
 print('Bouton 1 presse !')

def button_two(channel):
 print('Bouton 2 relache !')


# Branchement  du signal SIGINT sur notre fonction de sortie
signal.signal(signal.SIGINT, stop)

# Branchement d'une fonction de callback sur le front montant créé par l'appuie sur le bouton
GPIO.add_event_detect(button_pin1, GPIO.RISING)
GPIO.add_event_callback(button_pin1, button_one, bouncetime=1000)

# Branchement d'une fonction de callback sur le front descendant créé pare relachement du bouton
GPIO.add_event_detect(button_pin2, GPIO.FALLING)
GPIO.add_event_callback(button_pin2, button_two, bouncetime=1000))
# Pour toujours...
while True:
 time.sleep(1)

GO

root@raspberrypi:~# python3 button.py
Bouton 2 relache !
Bouton 1 presse !
Bouton 1 presse !
Bouton 1 presse !
Bouton 1 presse !
Bouton 2 relache !
Bouton 2 relache !