Le bouton poussoir

Python est le langage de prédilection du Raspberry Pi

Modérateurs : Francois, Manfraid

vlk
Messages : 1
Enregistré le : sam. 5 oct. 2019 10:42

Le bouton poussoir

Message par vlk » sam. 5 oct. 2019 10:54

Bonjour à tous,

j'ai trouvé cet article publié par Patrice SEIBEL, très efficace.
https://www.framboise314.fr/le-bouton-p ... ment-37033

J’utilise le code en python dans l'article c'est le push05.py.
j'ai juste un petit besoin d’amélioration.
j'aimerais savoir s'il est possible d'avoir un message UNIQUE lors du relâchement (bouton relâché) du bouton et si oui quel code à ajouter ?

je sais c'est plus du python que Raspberry mais si parmi vous il y a une âme charitable ...

D'avance Merci.

vlk

domi
Administrateur
Messages : 3230
Enregistré le : mer. 17 sept. 2014 18:12
Localisation : Seine et Marne

Re: Le bouton poussoir

Message par domi » sam. 5 oct. 2019 11:11

vlk a écrit :
sam. 5 oct. 2019 10:54
je sais c'est plus du python que Raspberry mais si parmi vous il y a une âme charitable ...
Bonjour,

C'est la raison pour laquelle je déplace ce sujet dans la rubrique "Python"
Passionné de Raspberry, Arduino, ESP8266, ESP32, et objets connectés :
Spécial débutant, concevez vous-même votre domotique DIY : https://www.youtube.com/c/DomoticDIY
Conception d'une station météo DIY, et envoi des infos à votre Domotique.

MSG
Raspinaute
Messages : 119
Enregistré le : ven. 26 déc. 2014 18:31

Re: Le bouton poussoir

Message par MSG » ven. 31 janv. 2020 16:50

Bonjour ,

Le contact électrique d'un bouton à 2 états que l'on peut stocker sur un seul bit , valeur 0 ou 1 (False ou True)

Pour gérer les changements d'état , il faut créer 2 position en plus , soit 4 états , en travaillant sur un "Registre" à 2 bits .
Soit :
- Bouton = 0b00 # stable non actionné = 0
- Bouton = 0b01 # bascule
- Bouton = 0b10 # bascule
- Bouton = 0b11 # stable actionné = 1

Définir une fonction pour intégrer le bit GPIO dans le Registre , par la droite (ou par la gauche => à coder):
Variable : Bouton1 = 0
Syntaxe : Bouton1 = Registre (GPIO , Bouton1)

Code : Tout sélectionner

def Registre (bit , mot):
    mot <<= 1		# décale les bits d'un rang vers la gauche
    mot += bit		# ajoute le bit à droite
    mot %= 4		# Modulo 4 , reste de division limitant les valeurs de 0 à 3 (0b00 à 0b11)
    return mot		# retourne la nouvelle valeur du bouton
On obtient alors les états suivants :
- Bouton = 0b00 # stable non actionné =Niveau Bas
- Bouton = 0b01 # bascule appuis = Front Montant
- Bouton = 0b10 # bascule relâché = Front Descendant
- Bouton = 0b11 # stable actionné = Niveau Haut

Le cycle de fonctionnement est le suivant :
- Bouton = 0b00 # stable non actionné = Bas
- Bouton = 0b01 # bascule appuis = Front Montant
- Bouton = 0b11 # stable actionné = Haut
- Bouton = 0b10 # bascule relâché = Front Descendant
- Bouton = 0b00 # stable non actionné = Bas
- Bouton = 0b01 # bascule appuis = Front Montant
- Bouton = 0b11 # stable actionné = Haut
- Bouton = 0b10 # bascule relâché = Front Descendant
etc ...
Les bits se décalant à chaque intégration vers la gauche pour laisse place au nouveau bit venu .

Il ne reste plus qu'à tester la valeur du registre :

Code : Tout sélectionner

if Bouton1 == 0b00 :
   print ('Etat 0"')
if Bouton1 == 0b01 :
   print ('Front montant')
if Bouton1 == 0b11 :
   print ('Etat 1"')
If Bouton1 == 0b10 :
   print ('Front descendant')

Il est possible d'intégrer une fonction Anti-Rebond , si la lecture du bouton est trop rapide , en utilisant tout simplement un registre plus long (sur 3 bits).

Il faut définir alors les nouvelles valeurs avec la même fonction (insersion de bit à droite):
- Bouton = 0b000 # stable non actionné = Niveau Bas
- Bouton = 0b001 # 1er lecture front montant
- Bouton = 0b011 # 2eme lecture front montant validée = Front montant
- Bouton = 0b111 # stable actionné = Niveau Haut
- Bouton = 0b110 # 1er lecture front descendant
- Bouton = 0b100 # 2eme lecture front descendant validée = Front descendant

et gérer les rebonds :
- Bouton = 0b101 # 2eme lecture front descendant = rebond détecté => retourner la valeur bouton à 0b111 ou 0b010
- Bouton = 0b010 # 2eme lecture front montant = rebond détecter => retourner la valeur bouton à 0b000 ou 0b001

Bud Spencer
Raspinaute
Messages : 1089
Enregistré le : lun. 15 août 2016 21:38

Re: Le bouton poussoir

Message par Bud Spencer » ven. 31 janv. 2020 18:22

Code : Tout sélectionner

if bouton :
	sleep(antirebond)
	while(bouton): 
		sleep(0.1)
	sleep(antirebond)
	action()
;)
Le premier ennemi de la connaissance n’est pas l’ignorance, c’est l’illusion de la connaissance (S. Hawking).

MSG
Raspinaute
Messages : 119
Enregistré le : ven. 26 déc. 2014 18:31

Re: Le bouton poussoir

Message par MSG » ven. 31 janv. 2020 19:29

Un test avec un Registre anti rebond sur 3 bits :

Code : Tout sélectionner

[manu@localhost Electricité]$ python3
Python 3.5.7 (default, Apr  4 2019, 11:58:21) 
[GCC 5.5.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> from Bouton import Reg_AR
>>> b = 0
>>> b = Reg_AR (0 , b) ; bin(b)
Etat 0
'0b0'
>>> b = Reg_AR (0 , b) ; bin(b)   <--- Niveau Bas
Etat 0
'0b0'
>>> b = Reg_AR (1 , b) ; bin(b)   <--- Appuis bouton
Etat 0
'0b1'
>>> b = Reg_AR (1 , b) ; bin(b)   <--- Front Montant détecté
Front Montant
'0b11'
>>> b = Reg_AR (1 , b) ; bin(b)   <---- Niveau Haut
Etat 1
'0b111'
>>> b = Reg_AR (1 , b) ; bin(b)
Etat 1
'0b111'
>>> b = Reg_AR (1 , b) ; bin(b)
Etat 1
'0b111'
>>> b = Reg_AR (1 , b) ; bin(b)   <--- Niveau Haut
Etat 1
'0b111'
>>> b = Reg_AR (0 , b) ; bin(b)   <--- Bouton relâché
Etat 1
'0b110'
>>> b = Reg_AR (0 , b) ; bin(b)   <--- Front Descendant détecté 
Front Descendant
'0b100'
>>> b = Reg_AR (0 , b) ; bin(b)   <--- Niveau Bas
Etat 0
'0b0'
>>> b = Reg_AR (0 , b) ; bin(b)
Etat 0
'0b0'
>>> 
>>>
Et le test anti rebond :

Code : Tout sélectionner

>>> b = Reg_AR (0 , b) ; bin(b)
Etat 0
'0b0'
>>> b = Reg_AR (0 , b) ; bin(b)   <--- Niveau Bas
Etat 0
'0b0'
>>> b = Reg_AR (1 , b) ; bin(b)   <--- Appuis bouton                                            
Etat 0                                                                      
'0b1'                                                                       
>>> b = Reg_AR (0 , b) ; bin(b)   <--- Rebond détecté => valeur bouton forcée à Niveau Bas 
Anti-Rebond
'0b0'
>>> b = Reg_AR (1 , b) ; bin(b)   <--- Appuis bouton 
Etat 0
'0b1'
>>> b = Reg_AR (1 , b) ; bin(b)  <--- Front Montant détecté
Front Montant
'0b11'
>>> b = Reg_AR (1 , b) ; bin(b)   <--- Niveau Haut
Etat 1
'0b111'
>>> b = Reg_AR (1 , b) ; bin(b)
Etat 1
'0b111'
>>> b = Reg_AR (0 , b) ; bin(b)   <--- Bouton relâché
Etat 1
'0b110'
>>> b = Reg_AR (1 , b) ; bin(b)   <--- Rebond descendant détecté => valeur bouton forcée à Niveau Haut
Anti-Rebond
'0b111'
>>> b = Reg_AR (0 , b) ; bin(b)   <--- Bouton relâché
Etat 1
'0b110'
>>> b = Reg_AR (0 , b) ; bin(b)   <--- Front Descendant détecté
Front Descendant
'0b100'
>>> b = Reg_AR (0 , b) ; bin(b)   <--- Niveau Bas
Etat 0
'0b0'
>>>
Ici , le code Python du test , à adapter ...

Code : Tout sélectionner

def Reg_AR (bit , mot):
    """Registre avec Anti Rebond
    
    bit = valeur binaire GPIO
    mot = regsitre binaire
        
    Syntaxe: b1 = Reg_AR (GPIO , b1)"""
    
    NB = 0b000  # 0 Niveau Bas
    M1 = 0b001  # 1 Montant 1er
    RM = 0b010  # 2 Rebond montant
    FM = 0b011  # 3 Front Montant
    FD = 0b100  # 4 Front Descendant
    RD = 0b101  # 5 Rebond Descendant
    D1 = 0b110  # 6 Descendant 1er 
    NH = 0b111  # 7 Niveau Haut    

    mot <<= 1
    mot += bit
    mot %= 2**3
    
    if (mot == NB) or (mot == M1) :
        print("Etat 0")
    if (mot == NH) or (mot == D1):
        print("Etat 1")
    if mot == FM :
        print("Front Montant")
    if mot == FD :
        print("Front Descendant")
    if mot == RM :
        print ("Anti-Rebond")
        return NB
    if mot == RD :
        print ("Anti-Rebond")
        return NH

    return mot

MSG
Raspinaute
Messages : 119
Enregistré le : ven. 26 déc. 2014 18:31

Re: Le bouton poussoir

Message par MSG » ven. 31 janv. 2020 19:58

@Bud Spencer
L'anti rebond peut être géré de diverse manières .

Là , je fais d'une pierre deux coups et l'intègre avec la détection des fronts montants et descendants .

dyox
Raspinaute
Messages : 969
Enregistré le : dim. 28 déc. 2014 15:28
Localisation : Le long de la côte, au dessus du pays des bigoudennes, aïe

Re: Le bouton poussoir

Message par dyox » ven. 31 janv. 2020 20:11


Bud Spencer
Raspinaute
Messages : 1089
Enregistré le : lun. 15 août 2016 21:38

Re: Le bouton poussoir

Message par Bud Spencer » ven. 31 janv. 2020 20:51

Sauf que la on parle d'une action exécutée au relâchement du bouton, donc après un appuis et comme tu ne peux pas détecter un release sans avoir préalablement eu une validation d'évaluation d'un pressed, tu n'est pas plus avancé avec gpiozero :P . L'autre solution est d'utiliser l'évent d'une interruption down->up, mais là, il est préférable d'oublier python

Juste à titre informatif, la méthode que je de donne est c'elle que l'on utilise quand on programme ce type d'action en assembleur.
Détection du changement d'état avec protection anti-rebond et attente du relâchement avec anti rebond pour confirmer la demande d'action.
Le premier ennemi de la connaissance n’est pas l’ignorance, c’est l’illusion de la connaissance (S. Hawking).

dyox
Raspinaute
Messages : 969
Enregistré le : dim. 28 déc. 2014 15:28
Localisation : Le long de la côte, au dessus du pays des bigoudennes, aïe

Re: Le bouton poussoir

Message par dyox » ven. 31 janv. 2020 20:56

il y a le "when_released", non ?

Bud Spencer
Raspinaute
Messages : 1089
Enregistré le : lun. 15 août 2016 21:38

Re: Le bouton poussoir

Message par Bud Spencer » ven. 31 janv. 2020 21:27

dyox a écrit :
ven. 31 janv. 2020 20:56
il y a le "when_released", non ?
Absolutly, mais la ca devient de l'évènementiel et ca rejoint ce que j'écrivait :
L'autre solution est d'utiliser l'évent d'une interruption down->up, mais là, il est préférable d'oublier python
Le premier ennemi de la connaissance n’est pas l’ignorance, c’est l’illusion de la connaissance (S. Hawking).

Répondre

Retourner vers « Python »