IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Python Discussion :

Détections sur entrées de GPIO et traitement associé


Sujet :

Python

  1. #21
    Membre Expert
    Homme Profil pro
    Inscrit en
    Avril 2004
    Messages
    1 069
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 1 069
    Par défaut
    Citation Envoyé par tm68780 Voir le message
    Heu non

    Tu dis: Pour peu que le traitement soit plus rapide qu'un tour de circuit.

    Je crois que c'est faux car ce serait "Pour peu que le traitement soit plus rapide que 2 détections successives" pour rappel voiture 2 passe la ligne en même temps ou presque.
    vrai ! mais pas vraiment, en fait c'est plus rapide qu'un état bas. Imaginons que les 2 voitures passent la ligne exactement en même temps, attentePassage doit reprendre la main avant le retour à l'état haut de la 2eme voiture.
    l'idéal est de déclencher une interruption à chaque passage qui empilerait les données. Le programme principale les dépilerait, pas besoin de thread.

    Je pense qu'il doit y avoir moyen de contourner ça, je réfléchis.

    théoriquement, dans le code suivant, attentePassage ne yield que si aucune voiture n'est en train de passer la ligne. C'est une amélioration, mais ça change pas le problème, le traitement doit être plus court que le temps d'un état bas dans le cas où les 2 voitures se suivent de très très très près, sans néanmoins passer la ligne en même temps.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    def attentePassage(nbTours):
     
        bouton1state = 1
        nbTours1     = nbTours
        bouton2state = 1
        nbTours2     = nbTours
     
        passage = []
     
        while nbTours1 and nbTours2:
            #jusqu'à ce qu'au moins une voiture atteigne nbTours
            # remplacer par `while nbTours1 or nbTours2:` pour jusqu'à ce que les 2 voitures atteignent nbTours
     
            if GPIO.input(button1)!= bouton1state: 
                if nbTours1 and bouton1state:
                    nbTours1 -= 1
                    passage.append(1)
                bouton1state = not bouton1state
                continue
     
            if GPIO.input(button2)!= bouton2state: 
                if nbTours2 and bouton2state:
                    nbTours2 -= 1
                    passage.append(2)
                bouton2state = not bouton2state
                continue
     
            if bouton1state and bouton2state and passage:
                yield(passage.pop(0))
     
     
    for p in attentePassage(10):
        print(p)

  2. #22
    Membre confirmé
    Homme Profil pro
    Administrateur systèmes et réseaux
    Inscrit en
    Janvier 2017
    Messages
    99
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haut Rhin (Alsace)

    Informations professionnelles :
    Activité : Administrateur systèmes et réseaux

    Informations forums :
    Inscription : Janvier 2017
    Messages : 99
    Par défaut
    J'ai trouvé quelque chose

    https://deusyss.developpez.com/tutor...Gpio/#LIII-B-9

    La détection de front est quelque chose d'important, et liée aux interruptions. Il existe trois façons de procéder.
    La première consiste à bloquer l'exécution du programme jusqu'à ce que l'événement se produise.
    La seconde solution est liée à l'utilisation d'une boucle. On ajoute des événements à écouter sur un canal, et au sein de la boucle while, on teste si quelque chose s'est produit sur un des canaux écoutés.

    Enfin, la dernière solution est celle qui est la plus proche du concept d'interruption sur microcontrôleur.
    Pour ce faire, en cas d'événement, un thread parallèle est lancé en cas d'interruption. Trois valeurs sont possibles : front montant (GPIO.RISING), front descendant (GPIO.FALLING) ou bien les deux (GPIO.BOTH)).

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    Def my_callback(channel):
        print("un evenement s'est produit")
     
    #ici on ajoute une tempo de 75 ms pour eviter l'effet rebond
    GPIO.add_event_detect(channel, GPIO.BOTH, callback=my_callback, bouncetime=75) 
    #votre programme ici

  3. #23
    Membre Expert
    Homme Profil pro
    Inscrit en
    Avril 2004
    Messages
    1 069
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 1 069
    Par défaut
    ça simplifie le code.

    à tester:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    from time import time
     
     
    pile = []
     
    boutonEvent = lambda numBouton: lambda : pile.append((numBouton,time()))
    passage0 = boutonEvent(0)
    passage1 = boutonEvent(1)
     
    # ~ remplacer ici channel par les valeurs adequates 
    GPIO.add_event_detect(channel, GPIO.FALLING, callback=passage0, bouncetime=75)
    GPIO.add_event_detect(channel, GPIO.FALLING, callback=passage1, bouncetime=75)
     
    def attentePassage(nbTours):
     
        tours = [nbTours,nbTours]
     
        while all(tours):
            #jusqu'à ce qu'au moins une voiture atteigne nbTours
            # remplacer par `while any(tours):` pour jusqu'à ce que les 2 voitures atteignent nbTours
     
            if pile:
                voiture,temps = pile.pop(0)
                if tours[voiture]:
                    tours[voiture] -= 1
                    yield((voiture,nbTours-tours[voiture],temps))
     
    top = time()
    for vt,tr,tm in attentePassage(10):
        print(f'voiture:{vt+1} tour:{tr} temps:{round(tm-top,4)}')

  4. #24
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 776
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 776
    Par défaut
    Salut,

    Citation Envoyé par josmiley Voir le message
    ça simplifie le code.
    Que le code marche ou pas, il serait plus intelligent de remplacer la simple liste par une queue.Queue et éviter de boucler sur while all(tours):.

    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  5. #25
    Membre Expert
    Homme Profil pro
    Inscrit en
    Avril 2004
    Messages
    1 069
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 1 069
    Par défaut
    Citation Envoyé par wiztricks Voir le message
    ... et éviter de boucler sur [B]while all(tours):
    On est bien obligé de boucler sur quelque chose pour lire la queue, non ?

    comme ça ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    from time import time
    from queue import Queue
     
     
    pile = Queue()
     
    boutonEvent = lambda numBouton: lambda : pile.put((numBouton,time()))
    passage0 = boutonEvent(0)
    passage1 = boutonEvent(1)
     
    # ~ remplacer ici channel par les valeurs adequates 
    GPIO.add_event_detect(channel, GPIO.FALLING, callback=passage0, bouncetime=75)
    GPIO.add_event_detect(channel, GPIO.FALLING, callback=passage1, bouncetime=75)
     
    def attentePassage(nbTours):
     
        tours = [nbTours,nbTours]
     
        while all(tours):
            #jusqu'à ce qu'au moins une voiture atteigne nbTours
            # remplacer par `while any(tours):` pour jusqu'à ce que les 2 voitures atteignent nbTours
     
            voiture,temps = pile.get()
            if tours[voiture]:
                tours[voiture] -= 1
                yield((voiture,nbTours-tours[voiture],temps))
     
    top = time()
    for vt,tr,tm in attentePassage(10):
        print(f'voiture:{vt+1} tour:{tr} temps:{round(tm-top,4)}')

  6. #26
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 776
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 776
    Par défaut
    Citation Envoyé par josmiley Voir le message
    On est bien obligé de boucler sur quelque chose pour lire la queue, non ?
    Ecrire une boucle pour attendre l'évènement suivant et le traiter ou "boucler" pour juste constater que la pile est vide et faire chauffer le CPU...

    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  7. #27
    Membre confirmé
    Homme Profil pro
    Administrateur systèmes et réseaux
    Inscrit en
    Janvier 2017
    Messages
    99
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haut Rhin (Alsace)

    Informations professionnelles :
    Activité : Administrateur systèmes et réseaux

    Informations forums :
    Inscription : Janvier 2017
    Messages : 99
    Par défaut
    Merci Josmiley

    Désolé je n'ai pas encore eu le temps de tester ton code et je n'ai pas encore terminé de tester le mien, pour l'instant j'ai quelques problèmes de rebond (avec des touches, ce qui est presque normal...). Il va falloir que j'essaye sur le circuit avec les détecteurs

  8. #28
    Membre confirmé
    Homme Profil pro
    Administrateur systèmes et réseaux
    Inscrit en
    Janvier 2017
    Messages
    99
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haut Rhin (Alsace)

    Informations professionnelles :
    Activité : Administrateur systèmes et réseaux

    Informations forums :
    Inscription : Janvier 2017
    Messages : 99
    Par défaut
    Pareil pour moi je n'ai pas trouvé d'autre solution que de boucler ... Mais bon, on a jamais fini d'apprendre

    Par contre j'utilise: from collections import deque, ce qui me permet de faire du FIFO

  9. #29
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 776
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 776
    Par défaut
    Salut,

    Citation Envoyé par tm68780 Voir le message
    Pareil pour moi je n'ai pas trouvé d'autre solution que de boucler ... Mais bon, on a jamais fini d'apprendre
    Si la condition est nombre de tours, on peut imaginer un callback passage qui décompte le nombre de tours et qui poste l'event "est arrivé" dans la "pile":

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    def passage(nButton, ntours=10):
          def _count():
                nonlocal ntours
                ntours -= 1
                if ntours <= 0:
                      pile.put((nBouton,))
          return _count
    puis on a l'initialisation des callbacks:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    for i in range(0):
         GPIO.add_event_detect(..., callback=passage(i)...)
    Puis on attend que çà se termine:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    n = pile.get()[-1]
    print (n, 'à gagné')
    Le plus important là dedans étant le pile = queue.Queue() i.e. l'objet qui permet de ne pas boucler inutilement à attendre que çà se passe.

    note: code non testé.

    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  10. #30
    Membre confirmé
    Homme Profil pro
    Administrateur systèmes et réseaux
    Inscrit en
    Janvier 2017
    Messages
    99
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haut Rhin (Alsace)

    Informations professionnelles :
    Activité : Administrateur systèmes et réseaux

    Informations forums :
    Inscription : Janvier 2017
    Messages : 99
    Par défaut
    pour Josmiley

    J'ai essayé ton code qui me génère une erreur.
    Avec mon petit niveau je ne comprends pas ton code :-)
    Si tu as envie de chercher...

    TypeError: <lambda>() takes 0 positional arguments but 1 was given

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    from time import time
    from queue import Queue
    import RPi.GPIO as GPIO 
     
    GPIO.setmode(GPIO.BOARD) #on utilise la numérotation pin physique
    button1=11
    button2=12 
    GPIO.setup(button1,GPIO.IN,pull_up_down=GPIO.PUD_UP)
    GPIO.setup(button2,GPIO.IN,pull_up_down=GPIO.PUD_UP)
     
    pile = Queue()
     
    boutonEvent = lambda numBouton: lambda : pile.put((numBouton,time()))
    passage0 = boutonEvent(0)
    passage1 = boutonEvent(1)
     
    # ~ remplacer ici channel par les valeurs adequates 
     
    GPIO.add_event_detect(11, GPIO.FALLING, callback=passage0, bouncetime=75)
    GPIO.add_event_detect(12, GPIO.FALLING, callback=passage1, bouncetime=75)
     
    def attentePassage(nbTours):
     
        tours = [nbTours,nbTours]
     
        while all(tours):
            #jusqu'à ce qu'au moins une voiture atteigne nbTours
            # remplacer par `while any(tours):` pour jusqu'à ce que les 2 voitures atteignent nbTours
     
            voiture,temps = pile.get()
            if tours[voiture]:
                tours[voiture] -= 1
                yield((voiture,nbTours-tours[voiture],temps))
     
     
    top = time()
     
     
    for vt,tr,tm in attentePassage(10):
        print(f'voiture:{vt+1} tour:{tr} temps:{round(tm-top,4)}')

  11. #31
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 776
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 776
    Par défaut
    Salut,

    Message d'erreur qui vous serait familier si vous aviez fait les exercices proposé dans n'importe quel tuto aux chapitres qui parlent des fonctions.

    Çà dit juste que le callback sera appelé avec un paramètre (comme mentionné dans le tuto. que vous avez trouvé) et que la fonction correspondante doit avoir un argument...

    Çà veut dire aussi que sans l'équipement pour "tester", difficile de vous donner un code qui marche, juste des idées à comprendre.

    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  12. #32
    Membre Expert
    Homme Profil pro
    Inscrit en
    Avril 2004
    Messages
    1 069
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 1 069
    Par défaut
    effectivement, j'ai pas lu la doc, le callback prend un argument.
    c'est corrigé.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    from time import time
    from queue import Queue
     
     
    pile = Queue()
     
    boutonEvent = lambda numBouton: lambda channel: pile.put((numBouton,time()))
     
    # ~ remplacer ici channel par les valeurs adequates 
    GPIO.add_event_detect(11, GPIO.FALLING, callback=boutonEvent(0), bouncetime=75)
    GPIO.add_event_detect(12, GPIO.FALLING, callback=boutonEvent(1), bouncetime=75)
     
    def attentePassage(nbTours):
     
        tours = [nbTours,nbTours]
     
        while all(tours):
            #jusqu'a ce qu'au moins une voiture atteigne nbTours
            # remplacer par `while any(tours):` pour jusqu'a ce que les 2 voitures atteignent nbTours
     
            voiture,temps = pile.get()
            if tours[voiture]:
                tours[voiture] -= 1
                yield((voiture,nbTours-tours[voiture],temps))
     
    top = time()
    for vt,tr,tm in attentePassage(10):
        print(f'voiture:{vt+1} tour:{tr} temps:{round(tm-top,4)}')

  13. #33
    Membre confirmé
    Homme Profil pro
    Administrateur systèmes et réseaux
    Inscrit en
    Janvier 2017
    Messages
    99
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haut Rhin (Alsace)

    Informations professionnelles :
    Activité : Administrateur systèmes et réseaux

    Informations forums :
    Inscription : Janvier 2017
    Messages : 99
    Par défaut
    Citation Envoyé par wiztricks Voir le message
    Salut,

    Message d'erreur qui vous serait familier si vous aviez fait les exercices proposé dans n'importe quel tuto aux chapitres qui parlent des fonctions.

    - W
    Oui merci j'ai bien compris


    Citation Envoyé par wiztricks Voir le message
    Salut,

    Çà veut dire aussi que sans l'équipement pour "tester", difficile de vous donner un code qui marche, juste des idées à comprendre.

    - W
    Oui ça aussi c'est évident. Mais par politesse envers la personne qui m'a envoyé ce code, je devais l'informer du résultat...

  14. #34
    Membre Expert
    Homme Profil pro
    Inscrit en
    Avril 2004
    Messages
    1 069
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 1 069
    Par défaut
    Citation Envoyé par wiztricks Voir le message

    Çà veut dire aussi que sans l'équipement pour "tester", difficile de vous donner un code qui marche, juste des idées à comprendre.
    c'est le challenge ...
    et c'est faisable, comme ici https://www.developpez.net/forums/d2...hon-raspberry/

  15. #35
    Membre confirmé
    Homme Profil pro
    Administrateur systèmes et réseaux
    Inscrit en
    Janvier 2017
    Messages
    99
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haut Rhin (Alsace)

    Informations professionnelles :
    Activité : Administrateur systèmes et réseaux

    Informations forums :
    Inscription : Janvier 2017
    Messages : 99
    Par défaut
    Salut Josmiley

    Je n'ai pas encore étudié ton code, je suis occupé à revoir des bases :-)
    mais j'ai essayé ton code, il affiche le cumul des chronos par pilote et non le chrono par tour du pilote

  16. #36
    Membre Expert
    Homme Profil pro
    Inscrit en
    Avril 2004
    Messages
    1 069
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 1 069
    Par défaut
    Citation Envoyé par tm68780 Voir le message
    Salut Josmiley

    Je n'ai pas encore étudié ton code, je suis occupé à revoir des bases :-)
    mais j'ai essayé ton code, il affiche le cumul des chronos par pilote et non le chrono par tour du pilote
    Suffit de faire une soustraction d'un tour à l'autre.

+ Répondre à la discussion
Cette discussion est résolue.
Page 2 sur 2 PremièrePremière 12

Discussions similaires

  1. Réponses: 2
    Dernier message: 13/06/2008, 19h15
  2. [C#] Comment détecter l'appui sur 'Entrée' ?
    Par ArHacKnIdE dans le forum Windows Forms
    Réponses: 6
    Dernier message: 10/01/2008, 17h05
  3. Détection d'entré de la souris
    Par soad dans le forum 2D
    Réponses: 6
    Dernier message: 10/02/2007, 21h35
  4. faire réagir un textarea lors de l'appui sur entrée
    Par keumlebarbare dans le forum Général JavaScript
    Réponses: 8
    Dernier message: 22/10/2006, 17h12
  5. gestion JTable sur entrée
    Par noussa_nouha dans le forum Composants
    Réponses: 9
    Dernier message: 03/08/2006, 12h34

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo