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. #1
    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 Détections sur entrées de GPIO et traitement associé
    Bonjour à tous

    La structure suivante est utilisée pour afficher les données de course d'un circuit 24.
    Or si les voitures passent en même temps la ligne, la deuxième détection est perdue.
    Pourriez vous me dire si par le threading ou par autre chose je peux améliorer mon programme

    Merci d'avance

    Code algo : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    Tant que...
            if attentePassage() == 1:
                ...
                texte1 = pilote1
                texte4 = calculTempsTour()
                Mise a jour de champs dans une fenêtre...
                ...
     
            else:
                texte1 = pilote2
                texte4 = calculTempsTour()
                Mise a jour de champs dans une fenêtre...
                ...
            ...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    def attentePassage():
        while True:
            if GPIO.input(button1)==0: 
                return(1) #renvoi numPiste = 1
     
            if GPIO.input(button2)==0: 
                return(2) #renvoi numPiste = 2

  2. #2
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 741
    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 741
    Par défaut
    Salut,

    Si le signal a détecter est un carré qui dure T s., il faudrait pouvoir lire l'état des N pins dans un intervalle de temps "petit" devant T/N.

    Ce qui veut dire qu'attente passage ne se contente pas de sortir quand il trouve un carré quelque part mais la liste des N états où au moins un est à 0.

    Les threads ne vont rien apporter car avec Python, vous utiliserez au mieux un CPU: la lecture restera séquentielle avec en plus l'overhead du changement de thread par rapport à une lecture séquentielle.

    Par contre, vous devriez pouvoir utiliser GPIO.add_event_detect... ou demander de l'aide dans un forum plus "hardware".

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

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

    Informations forums :
    Inscription : Avril 2004
    Messages : 1 068
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    def attentePassage():
        pistes = {1,2}
        while pistes:
            if 1 in pistes and GPIO.input(button1)==0: 
                pistes.remove(1)
                yield(1) #renvoi numPiste = 1
     
            if 2 in pistes and GPIO.input(button2)==0:
                pistes.remove(2)
                yield(2) #renvoi numPiste = 2
     
    for p in attentePassage():
        print(p)
    ou

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    def attentePassage():
        pistes = [1,2]
        while pistes:
            if 1 in pistes and GPIO.input(button1)==0: yield(pop(0))
            if 2 in pistes and GPIO.input(button2)==0: yield(pop(1))
     
    for p in attentePassage():
        print(p)

  4. #4
    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
    Bonjour
    Merci pour la réponse de W

    Pour les threads, ce que j’ai réussi à comprendre dans les docs me fait également penser que les threads ne m’apportent rien au niveau du temps de traitement.
    Pour ce traitement j’ai 2 tâches prioritaires : la détection de la voiture (attentePassage) et le calcul du temps au tour (calculTempsTour).

    L’affichage reste secondaire. Je pensais qu’il y aurait éventuellement une solution avec une pile (identification et temps) mais avec 2 threads le problème serait probablement l’accès à cette pile.
    Un thread en écriture et l’autre en lecture/écriture.
    Pour ce qui est du traitement des interruptions, tel que je le connais sur le GPIO, je ne gagne rien au niveau du temps de traitement, mais c’est vrai que la détection du front montant du signal est plus appropriée pour le passage d’une voiture au ralenti (signal pas trop long qui ne peux pas être détecté 2 fois).

  5. #5
    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 pour la réponse

    J'ai regardé vite fait et je crois que c'est une bonne solution.
    Je vais prendre le temps de regarder ça

  6. #6
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 741
    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 741
    Par défaut
    Salut,

    Citation Envoyé par tm68780 Voir le message
    (signal pas trop long qui ne peux pas être détecté 2 fois).
    C'est pour çà que l'approche séquentielle doit être "au pire" lire les N ports et retourner ou pas la liste de l'état de chaque port si l'un d'entre eux (ou plusieurs) est passé à 0.
    note: si détecte un port qui est passé à 0, puis on le traite et on retourne voir s'il y a un autre port à traiter ajoute du délai entre 2 lectures successives (et encore plus si on repart à lire la séquence de tous les ports).

    Citation Envoyé par tm68780 Voir le message
    la détection du front montant du signal est plus appropriée pour le passage d’une voiture au ralenti (signal pas trop long qui ne peux pas être détecté 2 fois).
    Le problème du polling est qu'on bouffe déjà un CPU pour scanner l'état des ports. On va pouvoir réaliser N scans par secondes et détecter une transition plus grande que 1/N secondes d'un facteur k.

    Si vous associez un callback à la détection d'une transition, vous pouvez gérer autrement la contrainte CPU: le callback se contentant d'ajouter un évènement à traiter dans une pile/liste/Queue.

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

  7. #7
    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 crois que le code prend effectivement en compte toutes les détections (même très rapprochés) mais il ne fonctionne que si les voitures se suivent.
    Si le 1 a un tour d'avance il ne sera pas compté.

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

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

    Je crois que le code prend effectivement en compte toutes les détections (même très rapprochés) mais il ne fonctionne que si les voitures se suivent.
    Si le 1 a un tour d'avance il ne sera pas compté.
    donnes tout le code/détailles ton algo, pour avoir une vision plus globale de ce qui doit être fait.

  9. #9
    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 pour ta réponse

    Après un top départ chaque passage de voiture doit être comptabilisé et le temps au tour doit être calculé.
    L'essentiel du code est donné dans mon premier message. Pour le reste l'affichage des temps, du nombre de tours, de la voiture en tête, du gagnant n'est que secondaire.

    Comme tu l'as bien comprit la difficulté est de ne pas perdre de détection entre 2 "attentePassage() " et ça avec ton principe de pile c'est gagné...

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

    Informations forums :
    Inscription : Avril 2004
    Messages : 1 068
    Par défaut
    Citation Envoyé par tm68780 Voir le message
    Merci pour ta réponse

    Après un top départ chaque passage de voiture doit être comptabilisé et le temps au tour doit être calculé.
    L'essentiel du code est donné dans mon premier message. Pour le reste l'affichage des temps, du nombre de tours, de la voiture en tête, du gagnant n'est que secondaire.

    Comme tu l'as bien comprit la difficulté est de ne pas perdre de détection entre 2 "attentePassage() " et ça avec ton principe de pile c'est gagné...
    ok, mais tu dis "...mais il ne fonctionne que si les voitures se suivent. Si le 1 a un tour d'avance il ne sera pas compté." Que se passe-t-il entre 2 tours ? sans plus de code je ne peux pas savoir.

  11. #11
    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 fait tourner le code ci-dessous et je constate que:

    Détection button1 --> repère 1 --> pistes = {2}
    Détection button2 --> repère 2 --> pistes = {}
    OK tout va bien

    Détection button2 --> repère 2 --> pistes = {1}
    Détection button1 --> repère 1 --> pistes = {}
    OK tout va bien

    Mais si:
    Détection button1 --> repère 1 --> pistes = {2}
    Détection button1 --> ni condition 1 ni condition 2



    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
    import RPi.GPIO as GPIO
    import time
    
    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)
    
    def attentePassage():
        pistes = {1,2}
        print ("Au debut ",pistes)
        while pistes:
            if 1 in pistes and GPIO.input(button1)==0: 
                print ("niveau1 ",pistes)       #repère 1
                pistes.remove(1)
                print ("niveau1 bis ",pistes)
                yield(1) #renvoi numPiste = 1
     
            if 2 in pistes and GPIO.input(button2)==0:
                print ("niveau2 ",pistes)       #repère 2
                pistes.remove(2)
                print ("niveau2 bis ",pistes)
                yield(2) #renvoi numPiste = 2
     
    for p in attentePassage():
        print(p)

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

    Informations forums :
    Inscription : Avril 2004
    Messages : 1 068
    Par défaut
    haaa okkkk ... c'est pas une course. Je vois.
    faut juste détecter le passage des tours. Je pense qu'il faut simuler un front montant/descendant. je te code ça et je poste ...

    à 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
     
    def attentePassage():
     
        bouton1state = 1
        bouton2state = 1
     
        while True:
     
            if GPIO.input(button1)!= bouton1state: 
                if bouton1state: yield(1) #renvoi numPiste = 1
                bouton1state = not bouton1state
     
            if GPIO.input(button2)!= bouton2state: 
                if bouton2state: yield(2) #renvoi numPiste = 2
                bouton2state = not bouton2state
     
    for p in attentePassage():
        print(p)

  13. #13
    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
    haaa okkkk ... c'est pas une course. Je vois.
    faut juste détecter le passage des tours. Je pense qu'il faut simuler un front montant/descendant. je te code ça et je poste ...

    Heu si :-)

    Désolé j'ai du mal à m'exprimer. C'est bien une course avec un top départ, Puis entre ce top départ et un nombre de tour qu'on aura défini il faut comptabiliser le nombre de tours de chacun, les chronos, afficher qui est en-tête, et au final qui a gagné.

    J'ai cherché du côté interuptions GPIO, mais lors d'une interruption sur front descendant il faut ensuite traiter cette interruption à savoir quel port est concerné et agir en conséquence.
    Donc pour moi, avec mes quelques connaissances, ça ne change rien à la problématique. Il faut enregistrer le passage d'une voiture et son chrono dans une pile et de traiter cette pile pour l'affichage des infos lorsqu’on a le temps

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

    Informations forums :
    Inscription : Avril 2004
    Messages : 1 068
    Par défaut
    Citation Envoyé par tm68780 Voir le message
    ...Puis entre ce top départ et un nombre de tour qu'on aura défini il faut comptabiliser le nombre de tours de chacun, les chronos, afficher qui est en-tête, et au final qui a gagné....
    la course s'arrête quand au moins une voiture a effectué N tours ou quand les 2 ont fait N tours ? c'est une variable que l'on peut intégrer au code et qui mettra fin à la boucle for.

  15. #15
    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
    Vu qu'il n'y a que 2 voitures je dirais que la course est terminée lorsque au moins une voiture a effectué les N tours. mais ce n'est pas important.

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

    Informations forums :
    Inscription : Avril 2004
    Messages : 1 068
    Par défaut
    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
    def attentePassage(nbTours):
     
        bouton1state = 1
        nbTours1     = nbTours
        bouton2state = 1
        nbTours2     = nbTours
     
        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
                    yield(1)
                bouton1state = not bouton1state
     
            if GPIO.input(button2)!= bouton2state: 
                if nbTours2 and bouton2state:
                    nbTours2 -= 1
                    yield(2)
                bouton2state = not bouton2state
     
    for p in attentePassage(10):
        print(p)

  17. #17
    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
    La question que je me pose:

    Est-il possible de définir un thread comme prioritaire ou secondaire ?

    Dans ce cas:
    Le thread1 prioritaire serait chargé d'empiler les identifiants de pistes et les chronos
    Le thread2 secondaire serait chargé de dépiler les infos pour les traiter mais que lorsque thread1 est inactif.

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

    Informations forums :
    Inscription : Avril 2004
    Messages : 1 068
    Par défaut
    Citation Envoyé par tm68780 Voir le message
    La question que je me pose:

    Est-il possible de définir un thread comme prioritaire ou secondaire ?

    Dans ce cas:
    Le thread1 prioritaire serait chargé d'empiler les identifiants de pistes et les chronos
    Le thread2 secondaire serait chargé de dépiler les infos pour les traiter mais que lorsque thread1 est inactif.
    le code que je t'ai donné devrait te permettre de te passer de thread, en général on peut s'en passer. Pour peu que le traitement soit plus rapide qu'un tour de circuit, tu devrais pouvoir faire tes calcules dans la boucle for.

  19. #19
    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
    Oui ce dernier code fonctionne et répond bien.
    Il faut que j'essaye de l'intégrer au reste avec le calcul chrono et l'affichage pour voir.

    Mais ma dernière question reste ouverte :-)

  20. #20
    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
    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.

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 2 12 DernièreDernière

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