Etat d'un bouton pressé (résolu)


#1

bonjours a tous,
j’essai de faire fonctionner un bouton branché au GPIO d’un Raspberry Pi 3, qui déclencherai une fonction à chaque fois que l’on appuis dessus.

le montage est simple, un bouton poussoir, une résistance de 10K le tout branché au GPIO. le montage fonctionne avec le code suivant

import time, pygame
import RPi.GPIO as GPIO

GPIO.setmode(GPIO.BCM)
bouton = 26
GPIO.setup(bouton, GPIO.IN, pull_up_down = GPIO.PUD_UP)

pygame.mixer.pre_init(22050, -16, 1, 64)
pygame.init()
root = pygame.display.set_mode((400, 400), 1, 16)
userCHANNEL1 = pygame.mixer.Channel(0)
fichier = "bipnoise.wav"
vol = 0.4

def makenoize():
    p1 = pygame.mixer.Sound(fichier)
    p1.set_volume(vol)
    userCHANNEL1.play(p1)

while True:
    etat = GPIO.input(bouton)
    
    if (etat == 0):
        makenoize() 
        time.sleep(0.5)

mon problème est que time.sleep ne me convient pas , déja car il fait “dormir” ma boucle un laps de temps (je crois?),
et que si je reste appuyé sur mon bouton, ma fonction se relance en boucle.

moi je voudrais que ma fonction ne se lance qu’une seul fois, meme si je reste appuyer sur mon bouton. et je voudrais pouvoir avoir la possibilité d’appuyer plusieurs fois frénétiquement^^ donc sans attendre que le temps de time.sleep soit écoulé.

je cherche depuis des heures et je ne parviens pas a savoir si la solution est dans le programme ou dans le montage.

voila si vous aviez des idées, des pistes ou quelque explication…
merci a vous :slight_smile:

Ps: mon niveau en Python est de quelque mois, mais je n’ai mon Raspberry que depuis quelque jours. :wink:


#2

Bonjour obs,
je n’ai jamais fait de python pour l’instant mais je sais qu’en C un simple “while(1)” peut fonctionner , peut être à essayer . Actuellement de ce que je comprend ta dernière boucle :

se lance, exécute la fonction makenoize() et prend une pause de 0.5 s avant de relancer la boucle et vérifier si etat == 0. Tu pourrais peut être diminuer le temps de ton time.sleep ou peut être le changer: en C il y a sleep qui permet de temporiser en secondes et usleep qui permet de temporisé en ms il doit bien y avoir un équivalent en python je pense .

En espérant que cela t’aide malgré mon inexpérience
Jonathan


#3

oui merci de ta réponse :wink:

le time.sleep ne rempli pas la fonction que je souhaite.
si je met trop de temps je ne peu pas relancer ma fonction tant que le time.sleep est en cour d’exécution, et si je le diminue drastiquement (ou le supprime meme), la fonction se relance automatiquement si j’ai le malheur de rester le doigt posé trop longtemps.

j’essai de comprendre, y a quelque chose a gérer, l’anti rebond ou quelque chose comme ça, je trouve bien des article qui en parle, mais tres sommairement, sans exemple claire que je comprend.

d’autre parle de résoudre se problème électroniquement, avec une résistance ou une diode, mais la encore les solution sont évoqué brièvement …

en plus je connais pas les termes alors pour chercher c’est compliqué.


#4

Je pense que mon problème trouvera sa solution coter électronique, en plaçant un condensateur aux bornes du bouton . Ce dernier va alors absorber les rebonds d’après ce que je lis.

Reste à trouver quel condensateur utiliser. :thinking:


#5

Salut,

J’ai beau travailler du python pour moi et pour aider d’autres personnes, je n’y connais rien donc je ne vais pas pouvoir te donner la réponse en l’état.

Cependant,
Pour mon photomaton, j’ai un bouton qui lance l’action.
Si j’appuie une fois, ça lance la séquence (avec plusieurs sleep)
Si je reste appuyé sur le bouton assez longtemps (soit longtemps du début à la fin ; soit juste avant la fin de la séquence) = mon script prend fin.
Donc c’est faisable.

@+


#6

j’ai pas bien compris ta réponse Nabla.

ton bouton est de quel genre ? pas de résistance, de diodes ou condensateur dans ton montage?

tu aurais un morceau de code à me montrer?

un simple print () en guise fonction suffira pour voir si ça fonctionne

merci à toi :wink:


#7

Mes boutons (celui du photomaton mais aussi celui qui permet d’éteindre le Rpi ou l’autre qui permet un “reboot” sont de simples boutons poussoirs sans aucun ajout matériel (faudrait que je mette des résistances pour stabiliser la chose ; parfois les fonctions se lancent d’elle même en cas d’artefact sur le réseau électrique et/ou RJ45)

J’ai plus qu’un bout de code ; j’ai un script complet :slight_smile:
Pas sûr qu’il ne te serve (je n’ai pas regardé ton script et avançait une piste).
Je t’envoie un Message Privé avec le lien direct.

++


#8

merci beaucoup :wink:
ton scrip est tres intéressant !!!
je vais tester : GPIO.wait_for_edge(24, GPIO.FALLING)

y a d’autre fonction bien intéressante pour mon projet dans ton script en plus, c’est cool.

Je crois qu’il y a une coquille dans un de tes message,
AfficherTexteTransparent("OK ; voici ce qui dans la boite ...")
il manque le verbe, non? ^^

Tu travailles le Python depuis combien de temps?

Merci encore !


#9

Salut,

On ne peut pas dire que je travaille le python :slight_smile:
Je n’ai pas appris le python, j’ai bossé sur un script (modifications) en direct ; j’ai commencé avec ce script début janvier (script récupéré sur le Net et “travaillé” de type “rétro-ingénierie” ou plutôt “méthode singe”)
Là, pour aider qq’un, j’ai mis les mains dans le cambouis et fortement modifié un autre scriot trouvé sur le net (un autre photomaton)
J’y ai juste passé 2 soirées (jusqu’à plus de minuit donc qq heures).
Bref, je vais devoir apprendre, mais ravi que ça puisse te servir.

(merci pour la coquille, j’avais corrigé chez moi, mais j’ai zappé sur le serveur)

++


#10

yes ,
bon avec ton script, je viens de résoudre mon problème :ok_hand:

le scrip, qui pourra aider:

 def ma_fonction():
     print ("yeahhh!!")

while True : 
        GPIO.wait_for_edge(bouton, GPIO.FALLING)
            if GPIO.input(bouton) == 0:
            ma_fonction()

je viens de parcourir ton site, y a plein d’info intéressante, au plaisir de te recroiser sur le forum

Sujet résolu, (je m’emballe p’être un peu vite, mais ça me parait ok)


#11

Cool !
Content d’avoir aidé.

Tu nous redis si c’est un échec
Et pour la rime, si ça marche, tu me fais un chèque :smiley:


#12

Nan pour un bouton ce n’est pas un echec, je dirais même plus que mes problème venais aussi de mon montage avec la résistance.
vu que tu n’en met pas, j’ai testé^^

par contre j’ai bêtement voulu ajouter 2 autre bouton, et la… bah le
GPIO.wait_for_edge() le fait plus

GPIO.add_event_detect() semble fonctionner lui, malgres une petite latence qui m’agace la…

je creuse la question actuellement…


#13

Ha ouais.
Perso, j’ai 3 boutons mais avec un système différentiel.
Mon bouton en boucle est dans un script python avec la sortie possible.
Mes 2 autres boutons sont des boutons d’action simple avec une boucle sans besoin de sortie de boucle (un produit un “reboot” ; l’autre produit un “poweroff”)

Je vais peut-être dire une bêtise du fait de mon statut de non-informaticien et surtout non codeur … mais … “c’est de l’essai que nait la création” et “seul celui qui essaye pourra réussir” … alors :
Si tu fais 2 scripts dont un script qui écoute le GPIO 24 (par exemple) et un autre qui écoute le GPIO 26
Au démarrage, tu as un script qui lance les 2 scripts (après, on peut sans doute monter le nombre sans trop de souci).
Non ?
++


#14

loool je viens d’éditer ma réponse et je vois ton post…

j’ai la soluce je crois :wink:
merci


#15

On dit que les grands esprits se rencontrent … mais … parfois ils se croisent :slight_smile: