Plusieurs “Boutons Poussoirs”

Python est le langage de prédilection du Raspberry Pi

Modérateurs : Francois, Manfraid

Poster
Messages : 9
Enregistré le : lun. 29 août 2016 03:59

Plusieurs “Boutons Poussoirs”

Message par Poster » lun. 29 août 2016 04:06

Bonjour à tous,

j'utilise un Raspi 1B sur lequel sont connectés 15 boutons poussoirs + 1 led. Chacun des boutons représentent une boite à lettre, le temps de pression détermine le contenu de la boite (lettre, colis et spécial) et appelle le script bash approprié pour l'envoi d'un email. Actuellement, j'ai plusieurs scripts python (15, un pour chaque bouton) que je souhaiterai fusionner en un seul mais je n'y arrive pas.

Voici le script (un des scripts) :

Code : Tout sélectionner

    #!/usr/bin/env python2.7

    from time import sleep
    import subprocess

    import RPi.GPIO as GPIO

    # GPIO 2 (pin 3)
    CHANNEL = 2

    # durees
    colis = 2
    special = 4

    # GPIO
    GPIO.setmode(GPIO.BCM)
    GPIO.setwarnings(False)

    GPIO.setup(CHANNEL, GPIO.IN, pull_up_down=GPIO.PUD_UP)

    # LED
    GPIO.setup(18,GPIO.OUT)
    GPIO.output(18,GPIO.LOW)

    # fonction de gestion du bouton
    def system_button(CHANNEL):

    # variable de stockage du temps de pression
    button_press_timer = 0

    while True:
    	if (GPIO.input(CHANNEL) == False) :
    		button_press_timer += 0.2
    			GPIO.output(18,GPIO.HIGH)

    	else:
    		if (button_press_timer > special) :
    			print "special : ", button_press_timer
    			subprocess.call("./Special.sh", shell=True)
    			GPIO.output(18,GPIO.LOW)

    		elif (button_press_timer > colis) :
    			print "colis : ", button_press_timer
    			subprocess.call("./Colis.sh", shell=True)
    			GPIO.output(18,GPIO.LOW)

    		elif (button_press_timer > 0.2):
    			print "lettre : ", button_press_timer
    			subprocess.call("./Lettre.sh", shell=True)
    			GPIO.output(18,GPIO.LOW)

    		button_press_timer = 0

    	sleep(0.2)

    GPIO.add_event_detect(CHANNEL, GPIO.FALLING, callback=system_button, bouncetime=200)

    try:
    while True:

    	sleep (2)

    except KeyboardInterrupt:

    GPIO.cleanup()

    GPIO.cleanup()
Merci par avance de votre aide :|

Avatar du membre
Manfraid
Modérateur
Messages : 1402
Enregistré le : ven. 3 oct. 2014 14:50
Contact :

Re: Plusieurs “Boutons Poussoirs”

Message par Manfraid » lun. 29 août 2016 08:32

Salut,


pourrais-tu mettre ton code python entre les balise [ code ] pour que ce soit plus lisible
NAS : DIY OS Debian: DD250Go + 3x2To + 6To
Raspberry pi : 2B OS : Raspbian
Se tromper est humain, Vraiment foutre la merde nécessite le mot de passe de root.

Poster
Messages : 9
Enregistré le : lun. 29 août 2016 03:59

Re: Plusieurs “Boutons Poussoirs”

Message par Poster » lun. 29 août 2016 19:03

Oui, merci.
Je voulais le faire mais j'ai pas trouvé comment insérer la balise [ code ].
Je viens de voir " Les BBCodes sont désactivés " (pas vraiment très moderne tout ça).

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

Re: Plusieurs “Boutons Poussoirs”

Message par domi » lun. 29 août 2016 21:08

Poster a écrit :Oui, merci.
Je voulais le faire mais j'ai pas trouvé comment insérer la balise [ code ].
Je viens de voir " Les BBCodes sont désactivés " (pas vraiment très moderne tout ça).
Bonjour,

Effectivement, et cela est normal, pour comprendre pourquoi, il faut bien lire les règles du forum :lol: :lol:
Il est écrit : "Vous avez accès aux BBcodes (au dessus de la zone d’édition des messages). Afin de luter contre les spammeurs, cette fonctionnalité est désactivée pour les nouveaux inscrits (< 5 messages)."
Souvent, les spammeurs postent un message, et constatent que le BBCode ne fonctionne pas pour leur liens et leurs images, ils ne postent pas plus de spam.

Merci de ta compréhension, et avec mes excuses pour ce désagrément.

Cdt,
Domi
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.

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

Re: Plusieurs “Boutons Poussoirs”

Message par Bud Spencer » lun. 29 août 2016 22:39

Facile, voila une suggestion simple

Tu crées un tableau (liste) d'objets indexés qui représente tes 15 boites. Chaque objet doit posséder une variable qui représente l'état du bouton et une autre pour stocker un datetime en ms. Dans ta boucle de programme principale, tu initialises un entier que tu construis bit à bit en fonction de l'état de tes 15 entrées. Chacun des bits de l'entier représente bien sur l'index d'un objet dans le tableau. Tu fait tourner ta boucle toutes les 0.2 secondes (apparemment c'est ton unité de base de temps), et à chaque boucle, tu compares la valeur actuelle des entrées avec celle de l'entier stocké précédemment. Si il y à changement de valeur, tu repositionnes respectivement la propriété d'état des objets qui on changés.

Pour chaque objet:
- au passage de 1 à 0 de l'état (bouton On vu que tu est pull up), tu stocks le datetime dans la variable prévue pour ca.
- au passage de 0 à 1 (relâche bouton), tu compares la différence de temps entres le datetime stocké et le datetime courant et tu lances la fonction d'envois avec le paramètre correspondant au type (lettre, colis ....).

Il semblerait que ta led doit être allumée quand il y a au moins une action en cours, donc pour gérer ca simplement, il suffit de la maintenir allumée tant que la valeur de l'entier ne correspond pas à celle qui représente tes 15 bits (boutons) à 1 (relâchés).

Bien entendu, La fonction d'envois doit obligatoirement être threadée ou être une instance asynchrone, sinon la notion de temps d'appuis sera fausse.

Si tu préfère utiliser le temps de rotation de ta boucle plutôt qu'une valeur datetime, tu peux aussi déclarer une variable de comptage de tours pour la boucle.

Si tu n'est pas trop 'poo', tu peux aussi utiliser un tableau à 2 dimensions directement dans ta boucle et lancer les threads d'envois depuis celle ci mais c'est moins 'moderne'.

Bien sur ce n'est pas optimum. Pendant que ta boucle va 'slepper', les appuis < 0.2 sec. ne seront pas pris en compte, et un appuis de 0.40 ms pourrait être interprété comme un 0.2 sec mais je ne pense pas que ce soit gênant et si ca l'était, le bouclage pourrait facilement être optimisé notamment en doublant la vitesse de la boucle.

Personnellement, j'avais utilisé ce genre de méthode pour un cours (en c# ou c++, je sais plus exactement) ou le programme simulait un distributeur de boissons chaudes 'multi buveurs' et la longueur d'appuis sur le bouton définissait une quantité de sucre de 0 à 5. J'avais quand même des gens qui avaient réussi à me faire du café au chocolat sucré avec du thé mais heureusement ce n'était qu'une simulation :lol:

Poster
Messages : 9
Enregistré le : lun. 29 août 2016 03:59

Re: Plusieurs “Boutons Poussoirs”

Message par Poster » mar. 30 août 2016 06:31

Okay domi, je vais poster pour profiter la liberté (d'édition) ! :lol:

Poster
Messages : 9
Enregistré le : lun. 29 août 2016 03:59

Re: Plusieurs “Boutons Poussoirs”

Message par Poster » mar. 30 août 2016 06:35

Merci Bud Spencer, je comprend la logique utilisé, mais par contre je suis incapable de la réaliser. Je ne parle pas le python, je le baragouine :oops:

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

Re: Plusieurs “Boutons Poussoirs”

Message par Bud Spencer » mar. 30 août 2016 23:28

Ha, forcement sans un minimum de maitrise du langage, c'est vrai que c'est moins facile :? . Je te rassure, je suis mois aussi un 'baragouineur' en Python puisque j'ai laissé tomber ce langage depuis au moins 15 ans et hormis pour de rares exceptions je ne l'utilise jamais. Ceci dit, ton problème est assez simple à résoudre et si j'ai 5 minutes demain soir, je te ferais un bout de code d'exemple.

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

Re: Plusieurs “Boutons Poussoirs”

Message par Bud Spencer » mer. 31 août 2016 21:39

Arggg ! moi non plus j'ai pas les 5 messages réglementaires pour avoir droit au bbcode :o

Bon, il faut que je trouve un truc a écrire, parce que je t'ais fait le bout de code promis mais comme je fais plutôt dans le genre 'compact' et sans commentaire, si je le met tel quel, tu t'y retrouveras pas ...

************EDIT*****************
Voila, j'ai les 5 messages :D

Comme je ne sais pas ce que font tes script .sh, j'ai créer un script extérieur (en python) pour tester . Il y a donc 2 scripts. Le serveur principale qui interface les gpio's (postmaster.py) et un client qui exécute les taches d'envois (postclient.py). Tu peux facilement adapter pour appeler tes script sh. Par flemme, je n'ai utilisé que 4 gpio's en entrée mais tu peux mettre tes 15 a toi sans problème.

Pour rester simple (enfin, le plus possible pour toi), je ne l'ai pas fais en objet. J'ai simplement utilisé des tableaux (listes) pour stocker les valeurs (bt0[] à bt3[] qui sont stockés dans un autre tableau bts[]). Les valeurs de listes bt sont respectivement:
['n° gpio', état du bouton, nombre de cycle en 1/10 de seconde].

Le principe est simple.

Le serveur fait la lecture des entrées toute les 0.1 seconde. Quand une entré est a 0 , la valeur [_,_,x] du bt gpio concerné est incrémenté de 1. quand elle revient à 1 (bouton relâché), le subprocess client est appelé en lui passant en paramètre le n° de la gpio et le nombre de dixième de seconde ou le bouton est resté appuyé. La led gpio18 est gérée. Elle est allumée si au moins un bouton est appuyé. J'ai aussi mis un signal pour pouvoir faire le GPIO.cleanup quand on quitte le programme (ctrl+c).

Le client, lui, affiche la gpio responsable de l'event et le mode (lettre, colis ...).

Bien sur, les 2 fichiers doivent se trouver dans le même répertoire, sinon il faut indiquer le path du client a l'appel subprocess. Le code est très compact, mais c'est pour qu'il puisse tenir sur une image pas trop grosse. Il ni a aucun commentaire dans le code, c'est pour t'obliger à réfléchir pour comprendre :lol: et surtout parce que j'ai horreur des commentaires dans du code, je trouve que ca le rend beaucoup moins lisible. Si toutefois il y a des trucs que tu ne comprend pas, même après réflexion, n'hésite pas à demander, je ne suis pas avare d'explication.

Le serveur:
postmaster.gif
postmaster.gif (27.62 Kio) Vu 6815 fois
Le client:
postclient.gif
postclient.gif (12.82 Kio) Vu 6815 fois
Le résulat:
postresult.gif
postresult.gif (18.99 Kio) Vu 6815 fois
Voila, cela devrait t'aider te passer des tes 15 scripts et sans doute t'apprendre de nouvelles choses. Bien que j'ai codé ca rapidos et fait seulement quelques essais cela pourrait sans doute être amélioré, mais en tout cas, c'est fonctionnel.
Modifié en dernier par Bud Spencer le mer. 31 août 2016 23:26, modifié 3 fois.

Poster
Messages : 9
Enregistré le : lun. 29 août 2016 03:59

Re: Plusieurs “Boutons Poussoirs”

Message par Poster » mer. 31 août 2016 23:05

Cool :lol:

Répondre

Retourner vers « Python »