Rasp-Hack-PiButton
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 d'AdaFruit (disponible chez MC Hobby) est utiliser pour faciliter le montage.
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
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)
Montage
Voici le détail du montage
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-blink.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.
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
xxx
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-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 # 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)