Rasp-Hack-PiButton

De MCHobby - Wiki
Sauter à la navigation Sauter à la recherche

Introduction

Savoir lire l'état d'une entrée du port GPIO du Raspberry PI est une action fondamentale en hacking électronique.
La détection de la pression d'un bouton permet de re-initialiser un programme, de passer à l'étape suivante, jouer du son, etc.

Voici un exemple qui vous propose de lire l'état d'un bouton (actuateur) placé sur le broche 24 du GPIO.
Note: Cet exemple aurait pu également utiliser la broche 23 ou 25.

En fonction de l'état du bouton, le programme allumera la led Rouge ou Verte.

Un Pi-Cobbler ou un Pi-Cobbler PLUS (disponible chez MC Hobby) est utiliser pour faciliter le montage.

Pi-Cobbler ou Pi-Cobbler-Plus?

Avec l'arrivée du Raspberry Pi 3, Raspberry Pi-2 et Raspberry Pi-B PLUS, Raspberry Pi Zero W vient également un GPIO étendu de 40 broches rétro-compatible avec le GPIO des premières générations du Raspberry-Pi qui, lui, n'avait que 26 broches.

GPIO-Compatibility-00v3.jpg

La seule vraie différence réside dans la longueur du GPIO du modèle Pi-3, Pi-2 ou B+ qui contient des broches en plus... et le Pi-Cobbler PLUS qui à également grandi pour accueillir les broches en plus.

Avec l'apparition du Pi Zero, nous pouvons reparler de la correspondance des GPIO.

Pour notre plus grand bonheur, le GPIO du Pi Zero et du Pi 3 (ou Pi 2) sont identiques :) chouette.

RASP-PIZERO-Correspondance-GPIO v2.jpg
Cliquez pour agrandir

Prérequis

Assurez-vous d'avoir mis votre environnement Python à jour.

Matériel

  • Un Pi-Cobbler
  • 2 x résistance de 330 Ohms (Orange, Orange, Brun)
  • 1 x Led Rouge
  • 1 x Led Verte
  • 1 x résistance de 10 KOhms (Brun, Noir, Orange)
  • 1 x Bouton poussoir momentané (aussi appelé actuateur)
  • Un Rapsberry, fil pour breadboard, breadboard.

Résistance Pull-up

Tout comme pour un montage Arduino, il faut utiliser une résistance pull-up pour ramener le potentiel de la broche GPIO à HIGH (niveau haut).
Lorsque l'on pousse le bouton poussoir, le potentiel de la broche GPIO est forcé à LOW (niveau bas). On évite le court-circuit grâce à la résistance Pull-Up.

Pour connecter un bouton sur un GPIO, il faut utiliser le montage suivant:

3.3v --> Résistance pull-up de 10k --> GPIO --> Bouton --> GND

PiButton-schematic.jpg

Note: Ceux d'entre-vous qui utilisent un Arduino noterons que la tension du GPIO d'un Raspberry est 3.3v (et non 5v comme pour un Arduino)

Pull-up/Pull-down interne

Pour les initiés, votre Raspberry-Pi dispose déjà de résistance pull-up ou pull-down que vous pouvez activer au moment de la déclaration de la broche en entrée.

GPIO.setup(23, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)
GPIO.setup(24, GPIO.IN, pull_up_down=GPIO.PUD_UP)

Voyez cet article sur Make Magazine pour plus d'information

Montage

Voici le détail du montage

PiButton bb2.jpg


PiButton bb.jpg

Le script Python

Pour créer facilement ce script sur votre python, nous vous proposons une méthode à base de copier/coller à l'aide des étapes suivantes à réaliser dans un terminal (ou une connexion SSH).

Copier/coller le code

Voici une méthode Copier/Coller super simple

On commence par demander la création du fichier

cat <<! > raspi-button.py

On fait ensuite le copier/coller du code

#!/usr/bin/env python
# -*- coding: latin-1 -*-

import RPi.GPIO as GPIO, time

GPIO.setmode(GPIO.BCM)
GREEN_LED = 18
RED_LED = 23
BUTTON1 = 24

GPIO.setup(GREEN_LED, GPIO.OUT)
GPIO.setup(RED_LED, GPIO.OUT)
GPIO.setup(BUTTON1, GPIO.IN)

while True:
        # Si le bouton est pressé, la broche GPIO est raccordée
        #   à la masse. Le GPIO est donc à LOW (bas).
        # Bouton pressé -> Input = LOW = False 
        if( GPIO.input( BUTTON1 ) == False ):
        	GPIO.output(GREEN_LED, True)
        	GPIO.output(RED_LED, False)
	else:
        	GPIO.output(GREEN_LED, False)
        	GPIO.output(RED_LED, True)

On termine l'opération de saisie simplement avec:

!

Rendre le fichier exécutable

Par défaut, les fichier sont considéré comme des fichiers texte non exécutable... même s'il contiennent des scripts.

Il faut donc indiquer au système d'exploitation qu'il peut autoriser l'exécution de notre raspi-button.py

chmod +x raspi-button.py

Executer le programme

Taper simplement la commande suivante:

 sudo ./raspi-button.py

Déparasitage Logiciel du bouton

Le contact d'un bouton poussoir momentané (actuateur) n'est pas franc.
Il s'accompagne généralement d'une série de "contacts parasites" avant le contact franc et définitif.

Switchbounce.jpg

Voici un exemple issus d'un article dédié au déparasitage des boutons pour Arduino (voir cet article sur notre blog).

Cette période de "contact parasite" est appelée période transitoire.

Comme un Raspberry est terriblement rapide, il pourrait détecter plusieurs fois les signaux haut et bas durant la période transitoire.
Dans le cadre de ce projet, cela pourrait se manifester de différentes façon:

  • La Led rouge semble clignoter légèrement avant de s'éteindre ou l'allumer.
  • La Led verte ne semble pas s'allumer d'un coup et clignote un peu.
  • Les deux leds "semblent" allumées en même temps pendant une très courte période.

Conséquences du parasitage

dans le cas de ce projet, les conséquences néfastes du parasitage sont purement esthétique.
Par contre, lors de la conception d'un compteur (qui compte le nombre de pression), cette période transitoire fera grimper artificiellement la valeur du compteur.
Difficile dans ce cas de compter le nombre de fois qu'un événement s'est produit.

Solution: le déparasitage logiciel

Le déparasitage logiciel consiste à faire une seconde vérification du signal après une courte pause.
Comme la période transitoire est très courte (de l'ordre de la milliseconde), faire une pause de 10 millisecondes entre deux lectures successives permet de s'assurer que le signal à vraiment changé de "façon définitive".
La pression du bouton n'étant humainement jamais inférieur à 10 ms, ont est certain de ne pas rater la pression du bouton lorsque l'action se présentera.

Si l'on se trouve dans une période transitoire, il est fort probable que la deuxième lecture ne soit pas identique (pas la même valeur).
Dans ce cas, il suffit d'ignorer le changement d'état car c'est une lecture parasite.

Le script python ci-dessous met ces quelques explications en oeuvre.

Déparasitage Matériel

Vous pouvez utiliser une capacité de 10nF en parallèle avec votre bouton pour éliminer une bonne partie des parasites.

Vous pouvez vous inspirer des explications et montages de notre tutoriel bouton pour Arduino. N'oubliez pas d'utiliser une tension de 3.3 Volts pour votre Pi ;-)

Script Python - déparasitage logiciel

Voici le script Python incluant le déparasitage logiciel du bouton.
En plus de faire le déparasitage, il stocke également l'état du bouton dans la variable BUTTON1_STATE en faisant en sorte qu'il soit le vrai reflet de l'état du bouton.
Lorsque le bouton est enfoncé, BUTTON1_STATE est True, lorsque le bouton est relâché BUTTON1_STATE est False.

Copier/coller le code

Voici une méthode Copier/Coller super simple

On commence par demander la création du fichier

cat <<! > raspi-button2.py

On fait ensuite le copier/coller du code

#!/usr/bin/env python
# -*- coding: latin-1 -*-

import RPi.GPIO as GPIO, time

GPIO.setmode(GPIO.BCM)
GREEN_LED = 18
RED_LED = 23

BUTTON1 = 24
# Dernier état connu du bouton
# Par defaut: le bouton n'est pas considéré comme activé
BUTTON1_STATE = False

GPIO.setup(GREEN_LED, GPIO.OUT)
GPIO.setup(RED_LED, GPIO.OUT)
GPIO.setup(BUTTON1, GPIO.IN)

while True:
        # -- Lecture avec déparasitage logiciel
        # Si le bouton est pressé, la broche GPIO est raccordée
        #   à la masse. Le GPIO est donc à LOW (bas).
        #   Bouton pressé -> Input = LOW = False         
        gpioRead1 = GPIO.input( BUTTON1 )
        state1    = not(gpioRead1)
        # SI changer d'etat ALORS refaire lecture de déparasitage
        if( state1 != BUTTON1_STATE ):
                # - attendre 10ms
                time.sleep( 10 / 1000 )
                # faire une 2ieme lecture
                gpioRead2 = GPIO.input( BUTTON1 )
                state2 = not(gpioRead2)
                # SI les deux lectures concordent
                # ALORS memoriser le nouvel etat du bouton
                if( state1 == state2 ):
                        BUTTON1_STATE = state2


        # -- Programme principal --
        # SI le bouton est pressé
        # ALORS allumer la LED verte  
        if( BUTTON1_STATE == True ):
                GPIO.output(GREEN_LED, False)
                GPIO.output(RED_LED, True)
        else:
                GPIO.output(GREEN_LED, True)
                GPIO.output(RED_LED, False)


On termine l'opération de saisie simplement avec:

!

Rendre le fichier exécutable

Par défaut, les fichier sont considéré comme des fichiers texte non exécutable... même s'il contiennent des scripts.

Il faut donc indiquer au système d'exploitation qu'il peut autoriser l'exécution de notre raspi-button2.py

chmod +x raspi-button2.py

Executer le programme

Taper simplement la commande suivante:

 sudo ./raspi-button2.py

Où acheter

Vous pouvez trouver plusieurs modèles de bouton chez MCHobby

Traduit avec l'autorisation d'AdaFruit Industries - Translated with the permission from Adafruit Industries - www.adafruit.com

Toute référence, mention ou extrait de cette traduction doit être explicitement accompagné du texte suivant : «  Traduction par MCHobby (www.MCHobby.be) - Vente de kit et composants » avec un lien vers la source (donc cette page) et ce quelque soit le média utilisé.

L'utilisation commercial de la traduction (texte) et/ou réalisation, même partielle, pourrait être soumis à redevance. Dans tous les cas de figures, vous devez également obtenir l'accord du(des) détenteur initial des droits. Celui de MC Hobby s'arrêtant au travail de traduction proprement dit.