[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:
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.
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.