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 :

[micropython] problème boucle infinie


Sujet :

Python

  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Avril 2004
    Messages
    41
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 41
    Par défaut [micropython] problème boucle infinie
    Bonjour,

    Je n'ai pas trouvé de forum consacré à l'utilisation de micropython, mais je n'ai peut être pas bien cherché...
    En vue de la prochaine rentrée scolaire, je me suis lancé dans la programmation de robots avec micropython (mu editor) et, sur les exemples que je lis, je vois beaucoup de programmes basés sur une boucle infinie
    Cela me perturbe car, jusqu'à maintenant, on m'avait toujours appris qu'il ne fallait jamais avoir une boucle dont on ne sort jamais (cas très classique de programme qui plante).

    J'ai essayé d'écrire des petits programmes en utilisant une boucle While qui s'arrête lorsqu'une condition est remplie. En voici un qui permet normalement de suivre une ligne noire jusqu'au premier carrefour rencontré.
    Le robot est piloté par une carte micro:bit. Il possède 2 capteurs de ligne espacés de près de 3 cm qui enjambent une ligne noire de 15 mm de largeur
    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
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
     
    from microbit import *
    import neopixel
     
    np = neopixel.NeoPixel(pin13, 12)
     
    moteurG = pin0
    moteurD = pin1
    ligneG = pin11
    ligneD = pin5
     
    def allumer(rouge, vert, bleu):
        for numero in range(0, 12):
            np[numero] = (rouge, vert, bleu)
        np.show()
     
    def avancer(vitesse):
        pin12.write_digital(0)      # moteur D marche avant
        pin8.write_digital(0)       # moteur G marche avant
        carrefour = False
        allumer(0, 0, 0)
        while not carrefour:
            gauche = ligneG.read_digital()
            droite = ligneD.read_digital()          # fond noir - blanc
            if ((gauche == 1)and(droite == 0)):     # tourner à gauche
                allumer(0, 50, 0)                   # allumer en vert
                moteurD.write_analog(vitesse)
                moteurG.write_analog(0)
                while ((ligneG.read_digital() == 1) and
                       (ligneD.read_digital() == 0)):
                    pass                            # fond blanc - noir
            elif ((gauche == 0)and(droite == 1)):   # tourner à droite
                allumer(0, 0, 50)                   # allumer en bleu
                moteurD.write_analog(0)
                moteurG.write_analog(vitesse)
                while ((ligneG.read_digital() == 0)and
                       (ligneD.read_digital() == 1)):
                    pass
            elif ((gauche == 0)and(droite == 0)):   # fond blanc - blanc
                allumer(50, 50, 50)                 # allumer en blanc
                moteurD.write_analog(vitesse)       # avancer tout droit
                moteurG.write_analog(vitesse)
                while ((ligneG.read_digital() == 0)and
                       (ligneD.read_digital() == 0)):
                    pass
            else:                                   # fond noir - noir
                carrefour = True
                allumer(0, 0, 0)
        moteurG.write_analog(0)
        moteurD.write_analog(0)
     
     
    avancer(300)
    allumer(50, 0, 50)       # allumer en violet
    Dans ce programme, le robot (Bit:Bot de 4Tronix) n'avance pas. Pourquoi ?
    En fait dès que j'allume le robot (après avoir flashé le programme dans sa mémoire), il reste immobile et les leds s'allument en violet. Autrement dit, il n'effectue pas la procédure "avancer" (ou il en sort immédiatement)

    J'ai essayé d'ajouter une instruction break, mais rien n'y fait. Je cherche depuis plus d'une semaine en vain. Merci de m'aider ou de me donner une piste.

  2. #2
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 679
    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 679
    Par défaut
    Citation Envoyé par patrice rabiller Voir le message
    J'ai essayé d'ajouter une instruction break, mais rien n'y fait. Je cherche depuis plus d'une semaine en vain. Merci de m'aider ou de me donner une piste.
    Commencez par vous assurer que votre robot sait avancer "simplement" avant de vouloir lui faire faire des choses plus compliquées.

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

  3. #3
    Membre averti
    Profil pro
    Inscrit en
    Avril 2004
    Messages
    41
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 41
    Par défaut
    Bien entendu, j'ai commencé par faire avancer mon robot, en avant, en arrière, en le faisant tourner ... J'ai aussi testé les capteurs (sonar, réflecteur de lignes) indépendamment des moteurs pour voir s'ils fonctionnent bien.
    En réalité, je ne démarre pas vraiment en programmation (10 ans de basic, 15 ans de turbo pascal et 15 ans de Delphi) mais je suis novice en python et là, quelque chose m'échappe.

  4. #4
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 679
    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 679
    Par défaut
    Citation Envoyé par patrice rabiller Voir le message
    mais je suis novice en python et là, quelque chose m'échappe.
    Votre code, c'est des commandes que vous expédiez à un robot et qu'on ne sait pas ce qu'elles sont supposées faire...
    Pour le reste, vous pouvez utiliser "print" pour afficher les différentes valeurs qui ont testées dans vos conditions/

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

  5. #5
    Membre averti
    Profil pro
    Inscrit en
    Avril 2004
    Messages
    41
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 41
    Par défaut
    Il est vrai que mon code n'est pas assez documenté concernant les commandes envoyées au robot. Cependant, j'ai quand même quelques questions concernant les variables booléennes en Python :

    1) Ma variable "carrefour" est une variable booléenne initialisée avec la valeur False. Est-il équivalent de dire
    • While not(carrefour):
    • While not carrefour:
    • While carrefour is False:
    • While (carrefour == False):

    2) Les variables "gauche" et "droite" sont des valeurs binaires (0 ou 1). Elles disent si le réflecteur voit un fond blanc (0) ou un fond noir (1). Peut-on les assimiler à des variables booléennes en écrivant "if (gauche and not(droite)):" au lieu de "if ((gauche == 1) and (droite == 0)):" ?
    3) On peut bien sortir d'une boucle "while not(carrefour)" en assignant, dans la boucle, la valeur True à la variable carrefour n'est-ce pas ? Doit-on utiliser break pour quitter la boucle While lorsque le robot arrive sur un carrefour ? Cela se produit lorsque les 2 capteurs gauche et droite se trouvent sur fond noir.

    Merci de m'avoir lu.

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

    Vous posez des questions basiques sur Python (micropython devrait être son cousin) pour lesquelles, vous auriez une réponse par vous même en lançant l'interpréteur Python et en tapant quelques instructions.
    C'est pas compliqué d'écrire:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    >>> v = False
    >>> while not(v):
    ...     v = not v
    ...     print('done?')
    ...
    done?
    >>>
    pour vérifier que...

    Cela se produit lorsque les 2 capteurs gauche et droite se trouvent sur fond noir.
    Il n'est pas si compliqué d'ajouter des "print" à votre code:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
        while not carrefour:
            gauche = ligneG.read_digital()
            droite = ligneD.read_digital()          # fond noir - blanc
            print (carrefour, gauche, droite)
            ... 
            else:   
                print ('noir/noir')                                # fond noir - noir
                carrefour = True
                allumer(0, 0, 0)
    pour visualiser ce qu'il se passe.

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

  7. #7
    Membre averti
    Profil pro
    Inscrit en
    Avril 2004
    Messages
    41
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 41
    Par défaut
    Citation Envoyé par wiztricks Voir le message
    Salut,

    Vous posez des questions basiques sur Python (micropython devrait être son cousin) pour lesquelles, vous auriez une réponse par vous même en lançant l'interpréteur Python et en tapant quelques instructions.
    C'est pas compliqué d'écrire:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    >>> v = False
    >>> while not(v):
    ...     v = not v
    ...     print('done?')
    ...
    done?
    >>>
    pour vérifier que...



    Il n'est pas si compliqué d'ajouter des "print" à votre code [...]

    pour visualiser ce qu'il se passe.

    - W
    Non, ce n'est pas compliqué ... sauf qu'il s'agit d'un programme embarqué sur le robot et qu'il n'y a pas d'affichage sur le robot : juste quelques leds qui peuvent me servir d'indicateur en fonction de leur couleur. Je ne peux même pas exécuter le programme pas à pas.
    Micropython est basé sur python 3, avec juste les bibliothèques de base et la bibliothèque liée au pilotage de la carte BBC Micro:bit. On édite le programme sur un PC (par exemple avec Mu) puis on branche la carte via un cable USB, puis on "flashe" (téléverse) le programme dans un format .hex. Ensuite on débranche le cable USB et le robot est piloté par son programme embarqué.

    Je vais essayer d'ajouter, pour ralentir l'exécution, des instructions "sleep" associées à des leds de différentes couleurs pour comprendre le cheminement du programme. Je vais également tester mes variables booléennes avec d'autres leds (il y en a une douzaine). Ça ne sera pas aussi simple que des "print" mais j'espère y arriver.

    Merci de votre assistance.

  8. #8
    Rédacteur/Modérateur

    Avatar de Jerome Briot
    Homme Profil pro
    Freelance mécatronique - Conseil, conception et formation
    Inscrit en
    Novembre 2006
    Messages
    20 317
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Freelance mécatronique - Conseil, conception et formation

    Informations forums :
    Inscription : Novembre 2006
    Messages : 20 317
    Par défaut
    Citation Envoyé par wiztricks Voir le message
    Il n'est pas si compliqué d'ajouter des "print" à votre code:
    Sauf qu'il n'y a pas toujours d'afficheur graphique en embarqué.
    La méthode la plus robuste consiste à utiliser des pattern avec les LEDs pour mettre en évidence le passage ou non dans certaine partie de code.
    D'où la fonction allumer dans le code ci-dessus.

    Citation Envoyé par patrice rabiller Voir le message
    Cela me perturbe car, jusqu'à maintenant, on m'avait toujours appris qu'il ne fallait jamais avoir une boucle dont on ne sort jamais (cas très classique de programme qui plante).
    C'est pourtant bien comme ça que fonction les microcontrôleurs. Leur rôle est d'exécuter des tâches dès, et tant, qu'ils sont sous-tension.

    Il ne faut pas oublier que les microcontrôleurs tournent très rapidement.

    Essaie en remplaçant la condition sur carrefour par un temps maxi de fonctionnement. Par exemple pour 10 secondes :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    while running_time() < 10000:

  9. #9
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 679
    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 679
    Par défaut
    Citation Envoyé par patrice rabiller Voir le message
    Non, ce n'est pas compliqué ... sauf qu'il s'agit d'un programme embarqué sur le robot et qu'il n'y a pas d'affichage sur le robot : juste quelques leds qui peuvent me servir d'indicateur en fonction de leur couleur.
    Bon, ben... Peut être commencez par tester la fonction "allumer" qui devrait afficher une couleur en fonction de.... et balader le robot manuellement pour voir si, déjà, le changement de couleur fonctionne.

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

  10. #10
    Membre averti
    Profil pro
    Inscrit en
    Avril 2004
    Messages
    41
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 41
    Par défaut
    J'ai essayé votre proposition en mettant while running_time() à la place de while not(carrefour). Du coup, le robot avance pendant 10 secondes en suivant la ligne, mais ne s'arrête plus au premier carrefour : c'est complètement logique.
    Ça voudrait donc dire que, dès le départ, alors que la variable carrefour est initialisée à False, le premier passage dans la boucle while se termine en allant directement à la clause else :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
        while not carrefour:
            ...
            If gauche==1 and droite==0:        #noir/blanc > tourner à droite
            ...
            elif gauche==0 and droite==1:        #blanc/noir > tourner à gauche
            ...
            elif gauche==0 and droite==0:        #blanc/blanc > tout droit
            ...
            else:
                carrefour=True
    Est-ce que ça voudrait dire qu'il faut que les capteurs soient correctement calibrés et pour cela attendre un peu avant que les valeurs lues soient correctes ?
    Au départ, je place mon robot avec les capteurs de part et d'autre de la ligne noire : ils doivent donc lire "blanc/blanc" et le robot doit continuer tout droit. Comment se fait-il que, dès le départ, les valeurs lues soient noir/noir ?

    La réponse est peut-être que, comme vous dites, les capteurs fonctionnent à très grande vitesse et les valeurs lues à la volée doivent être "lissées" en prenant la moyenne des valeurs lues sur une très courte période (100 microsecondes par exemple) ?

  11. #11
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 679
    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 679
    Par défaut
    Citation Envoyé par patrice rabiller Voir le message
    Au départ, je place mon robot avec les capteurs de part et d'autre de la ligne noire : ils doivent donc lire "blanc/blanc" et le robot doit continuer tout droit. Comment se fait-il que, dès le départ, les valeurs lues soient noir/noir ?
    Et quand/comment avez vous vérifié que blanc produisait 0 et que noir produisait bien 1?

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

  12. #12
    Rédacteur/Modérateur

    Avatar de Jerome Briot
    Homme Profil pro
    Freelance mécatronique - Conseil, conception et formation
    Inscrit en
    Novembre 2006
    Messages
    20 317
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Freelance mécatronique - Conseil, conception et formation

    Informations forums :
    Inscription : Novembre 2006
    Messages : 20 317
    Par défaut
    Pour ma part, je ferais un programme plus simple pour tester seulement le comportement des capteurs dans un premier 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
    34
    35
    36
    from microbit import *
    import neopixel
     
    np = neopixel.NeoPixel(pin13, 12)
     
    ligneG = pin11
    ligneD = pin5
     
     
    def allumer(rouge, vert, bleu):
        for numero in range(0, 12):
            np[numero] = (rouge, vert, bleu)
        np.show()
     
     
    def testSensor():
     
        allumer(0, 0, 0)
     
        while running_time() < 10000:
     
            gauche = ligneG.read_digital()
            droite = ligneD.read_digital()
     
            if gauche and not droite:
                allumer(50, 0, 0)
            elif droite and not gauche:
                allumer(0, 50, 0)
            elif droite and gauche:
                allumer(0, 0, 50)
            else:
                allumer(0, 0, 0)
     
     
    testSensor()
    allumer(50, 0, 50)
    C'est juste un premier jet à améliorer…

    Sinon, il y existe un forum plus orienté programmation systèmes embarqués : https://www.developpez.net/forums/f1...teme/embarque/

  13. #13
    Membre averti
    Profil pro
    Inscrit en
    Avril 2004
    Messages
    41
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 41
    Par défaut
    J'ai pu confirmer ce que disait la notice du fabricant par ailleurs, en créant ce petit programme :
    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
     
    from microbit import *
    import neopixel
     
    np = neopixel.NeoPixel(pin13, 12)
     
    ligneG = pin11      # capteur gauche
    ligneD = pin5       # capteur droit
     
     
    while True:
        gauche = ligneG.read_digital()      # Vrai (ou 1) si capteur sur fond NOIR
        droite = ligneD.read_digital()      # Faux (ou 0) si capteur sur fond BLANC
        if (gauche and not(droite)):            # Noir Blanc
            np[5] = (50, 50, 50)
            np[11] = (0, 0, 0)
        elif (not(gauche) and droite):          # Blanc Noir
            np[5] = (0, 0, 0)
            np[11] = (50, 50, 50)
        elif (not(gauche) and not(droite)):     # Blanc-Blanc
            np[5] = (0, 0, 0)
            np[11] = (0, 0, 0)
        else:                                   # Noir-Noir
            np[5] = (50, 50, 50)
            np[11] = (50, 50, 50)
        np.show()
    Dans ce programme, la led n° 5 (sur la gauche du robot) s'allume lorsque le capteur gauche est au-dessus d'un fond noir et la led n° 11 (sur la droite du robot) s'allume lorsque le capteur droit est sur un fond noir.
    J'ai supposé que VRAI = 1 et FAUX = 0, ce qui me paraît naturel dans de nombreux langages. Dans cet exemple aussi, je constate que les variables binaires gauche et droite (0/1) se comportent bien comme des variables booléennes puisqu'on peut écrire if gauche: en lieu et place de if gauche==1:.
    Par contre, la cadence des lectures des capteurs étant très rapide, on ne peut pas savoir, dans une situation donnée (noir/blanc par exemple), s'il n'y a pas, de temps en temps, un couple isolé de valeurs noir/noir. Un tel résultat noyé parmi tous les résultats noir/blanc doit passer inaperçu dans l'exécution du programme : la persistance rétinienne (ou l'inertie des leds) doit rendre invisible un changement aussi rapide de l'allumage. Il en résulterait que cela pourrait être la cause du dysfonctionnement de mon programme.

  14. #14
    Expert confirmé Avatar de BufferBob
    Profil pro
    responsable R&D vidage de truites
    Inscrit en
    Novembre 2010
    Messages
    3 041
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : responsable R&D vidage de truites

    Informations forums :
    Inscription : Novembre 2010
    Messages : 3 041
    Par défaut
    salut,

    j'y vais de ma petite contrib :

    Citation Envoyé par patrice rabiller Voir le message
    (...) sur les exemples que je lis, je vois beaucoup de programmes basés sur une boucle infinie
    Cela me perturbe car, jusqu'à maintenant, on m'avait toujours appris qu'il ne fallait jamais avoir une boucle dont on ne sort jamais (cas très classique de programme qui plante).
    un programme pris dans une boucle infinie ne plante pas, il s'exécute indéfiniment à moins qu'on le cut avec un signal ou qu'à l'intérieur de la boucle les opérations exécutées mènent à planter le programme (allocation mémoire/descripteurs/etc. par exemple)

    c'est très sain une boucle while True:, on peut gérer plus finement le flux d’exécution avec des mots-clés comme break ou continue, dans beaucoup de langages on trouve une tournue do {...} while (repeat ... until en Pascal) permettant d'exécuter une première fois le bloc avant d'évaluer la condition, en Python la seule façon de tourner proprement le code dans ce sens c'est de faire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    while True:
       # traitements
       # ...
       if condition:
          break

  15. #15
    Membre averti
    Profil pro
    Inscrit en
    Avril 2004
    Messages
    41
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 41
    Par défaut
    Oui, je suis d'accord avec toi, BufferBob : les boucles infinies de type while True: sont bien pratiques.
    Cependant, je fais partie de la vieille génération qui a appris le précepte de finitude de Donald Knuth : "Un algorithme doit toujours se terminer après un nombre fini d'étapes".
    Donc, dans la mesure du possible, par principe, j'essaierai d'avoir toujours une instruction break permettant de sortir à coup sûr d'une boucle while True: Cette condition de sortie pourra être une durée à ne pas dépasser, une variable qui prend une valeur particulière et dont on est sûr qu'elle finira par se produire.

    @Jérôme Briot :
    Nos derniers messages ont dû se croiser et j'ai fait un programme analogue à celui que tu proposes.
    Ce matin, je vais approfondir la piste des lectures "aberrantes" qui pourraient se produire au niveau des capteurs. Si mon idée est juste, alors je pourrai résoudre mon problème ...

    Merci à tous. Je vous tiendrai informés si je trouve une solution.

  16. #16
    Membre averti
    Profil pro
    Inscrit en
    Avril 2004
    Messages
    41
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 41
    Par défaut Boucle infinie : résolu partiellement
    J'ai trouvé un début de réponse.

    En faisant des tests de lecture des capteurs de ligne, j'ai constaté qu'au-dessous de 3000 lectures, il y avait 100% d'erreurs ! Mais si j'augmentais le nombre de lectures (4000 puis 5000 jusqu'à 10000) le nombre de lectures aberrantes diminuait progressivement (on tombe encore à 10% à 15% de mauvaises lectures lorsqu'on fait 10000 lectures). En réalité, ces erreurs étaient toujours obtenues lorsque les capteurs étaient sur un fond blanc. Sur un fond noir les données lues ne comportaient aucune erreur.
    J'en ai conclu que les erreurs de lecture se produisaient essentiellement au début de l'expérience, comme si les capteurs avaient besoin d'un temps de chauffe avant de fonctionner correctement.
    J'ai donc ajouté une instruction sleep avant de faire mes comptages.
    Bingo ! Il faut, au moins 2 secondes de latence au démarrage avant que les capteurs soient opérationnels.

    Maintenant, je sais pourquoi ma boucle "while not carrefour:" s'arrêtait tout de suite : au démarrage, les capteurs ne sont pas prêts et ils retournent systématiquement la valeur 1 (noir) même si on est sur fond blanc.

    J'espère pouvoir vous confirmer qu'on peut ainsi se passer d'une boucle "while True" dans mon programme.

  17. #17
    Responsable Arduino et Systèmes Embarqués


    Avatar de f-leb
    Homme Profil pro
    Enseignant
    Inscrit en
    Janvier 2009
    Messages
    13 120
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Sarthe (Pays de la Loire)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Janvier 2009
    Messages : 13 120
    Billets dans le blog
    47
    Par défaut
    Bonjour,

    Citation Envoyé par patrice rabiller Voir le message
    J'espère pouvoir vous confirmer qu'on peut ainsi se passer d'une boucle "while True" dans mon programme.
    Un microcontrôleur ne fonctionne pas comme un "PC de bureau". Il n'exécute qu'un seul programme très spécialisé, il n'y a pas de système d'exploitation à qui "rendre la main" lorsque son programme se termine. Tant qu'il est allumé, on a donc intérêt à le conserver dans un état connu, celui qu'on a programmé

  18. #18
    Membre averti
    Profil pro
    Inscrit en
    Avril 2004
    Messages
    41
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 41
    Par défaut
    Voila : j'ai pu finir de développer ma routine. Il s'agissait de suivre une ligne noire jusqu'au prochain carrefour.
    Au départ, le robot enjambe une ligne noire. Les capteurs sont de part et d'autre de la ligne. Ils voient donc blanc/blanc.
    Si l'un des capteurs voit noir, (à gauche ou à droite) alors le robot tourne légèrement (à droite ou à gauche)
    Si les 2 capteurs voient noir, alors le robot est arrivé au carrefour et il s'arrête.
    Il est impossible de réaliser cette opération avec la boucle While ... True.
    Ce problème est très classique mais très mal documenté : il n'est mentionné nulle part que les capteurs ont besoin de 2 secondes pour être opérationnels.

    Une première routine pour faire bouger le robot en précisant les vitesses des roues à gauche et à droite :
    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
     
    def moteur(vGauche, vDroite):
        # Permet d'avancer ou de reculer avec des vitesses entre -100 et 100
        # Les vitesses positives font avancer, les négatives font reculer
     
        directG.write_digital(0)    # marche avant à gauche par défaut
        directD.write_digital(0)    # marche avant à droite par défaut
        if vGauche < 0:
            directG.write_digital(1)                # marche arrière à gauche
            moteurG.write_analog(1023 + 10.23 * vGauche)
        else:
            moteurG.write_analog(10.23 * vGauche)   # marche avant à gauche
        if vDroite < 0:
            directD.write_digital(1)                # marche arrière à droite
            moteurD.write_analog(1023 + 10.23 * vDroite)
        else:
            moteurD.write_analog(10.23 * vDroite)   # marche avant à droite
    Une seconde routine pour aller jusqu'au prochain carrefour :
    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
     
    def allerAuCarrefour(vitesse):
        carrefour = False
        allumer(0, 0, 0)
        while not(carrefour):
            gauche = ligneG.read_digital()
            droite = ligneD.read_digital()
            if (gauche and droite):                 # fond noir/noir
                carrefour = True
                allumer(0, 0, 0)
            elif (gauche and not droite):           # fond noir/blanc
                moteur(0, vitesse)                  # tourner à gauche
                allumer(0, 50, 0)                   # allumer en vert
                while (ligneG.read_digital() and
                       not ligneD.read_digital()):  # tant que noir/blanc
                    pass
            elif (not gauche and droite):           # fond blanc/noir
                moteur(vitesse, 0)                  # tourner à droite
                allumer(0, 0, 50)                   # allumer en bleu
                while (not ligneG.read_digital() and
                       ligneD.read_digital()):      # tant que blanc/noir
                    pass
            else:                                   # fond blanc/blanc
                moteur(vitesse, vitesse)            # tout droit
                allumer(50, 50, 50)                 # allumer en blanc
                while (not ligneG.read_digital() and
                       not ligneD.read_digital()):  # tant que blanc/blanc
                    pass
        moteur(0, 0)
    Évidemment, le programme principal, avant d'appeler la procédure "allerAuCarrefour", impose un délai d'attente de 2 secondes.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Problème boucle infinie bloquer comment bloquer outlook
    Par traersa dans le forum VBA Outlook
    Réponses: 2
    Dernier message: 09/03/2018, 11h03
  2. Problème boucle infinie
    Par Hafa10 dans le forum Langage
    Réponses: 9
    Dernier message: 16/05/2015, 19h01
  3. [XL-2007] Problème boucle infinie
    Par s.byczek dans le forum Macros et VBA Excel
    Réponses: 4
    Dernier message: 08/02/2012, 14h49
  4. [XL-2010] Problème boucle infini
    Par Zaelos dans le forum Macros et VBA Excel
    Réponses: 9
    Dernier message: 24/01/2012, 10h49
  5. problème boucle infinie
    Par hanou88 dans le forum C
    Réponses: 7
    Dernier message: 05/11/2010, 01h15

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