Page 1 sur 3

Le bouton poussoir

Posté : sam. 5 oct. 2019 10:54
par vlk
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

Re: Le bouton poussoir

Posté : sam. 5 oct. 2019 11:11
par domi
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"

Re: Le bouton poussoir

Posté : ven. 31 janv. 2020 16:50
par MSG
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

Re: Le bouton poussoir

Posté : ven. 31 janv. 2020 18:22
par Bud Spencer

Code : Tout sélectionner

if bouton :
	sleep(antirebond)
	while(bouton): 
		sleep(0.1)
	sleep(antirebond)
	action()
;)

Re: Le bouton poussoir

Posté : ven. 31 janv. 2020 19:29
par MSG
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

Re: Le bouton poussoir

Posté : ven. 31 janv. 2020 19:58
par MSG
@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 .

Re: Le bouton poussoir

Posté : ven. 31 janv. 2020 20:11
par dyox

Re: Le bouton poussoir

Posté : ven. 31 janv. 2020 20:51
par Bud Spencer
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.

Re: Le bouton poussoir

Posté : ven. 31 janv. 2020 20:56
par dyox
il y a le "when_released", non ?

Re: Le bouton poussoir

Posté : ven. 31 janv. 2020 21:27
par Bud Spencer
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