La boucle ne fonctionne que si j'utilise «imprimer»

11

Ce code ne permet pas d'allumer et d'éteindre la led.

import  RPi.GPIO as GPIO
import time
GPIO.setmode(GPIO.BCM)
GPIO.setwarnings(False)
GPIO.setup(21,GPIO.OUT)
for number in range(0,10):
    GPIO.output(21,GPIO.LOW)
    time.sleep(1)
    GPIO.output(21,GPIO.HIGH)
GPIO.cleanup()

mais quand j'imprime le numéro dans la boucle ça marche:

import  RPi.GPIO as GPIO
import time
GPIO.setmode(GPIO.BCM)
GPIO.setwarnings(False)
GPIO.setup(21,GPIO.OUT)
for number in range(0,10):
    GPIO.output(21,GPIO.LOW)
    time.sleep(1)
    GPIO.output(21,GPIO.HIGH)
    print(number)
GPIO.cleanup()

Une idée pourquoi c'est?

tazboy
la source
1
voir enwp.org/Heisenbug
cat
2
@cat Bingo, "Heisenbugs se produit parce que des tentatives courantes de débogage d'un programme, telles que l'insertion d'instructions de sortie"
tazboy
1
"Ce code ne permet pas d'allumer et d'éteindre la led." - Je ne suis pas d'accord.
marcelm

Réponses:

22

Essayez de remplacer votre printpar un time.sleep(0.05). Vous pouvez rencontrer ce comportement étrange car GPIO.output passe trop rapidement de HIGH à LOW pour être défini / détecté / vu. Augmentez / réduisez la durée du sommeil jusqu'à ce que le programme fonctionne correctement (augmentation) et suffisamment rapide (diminution).

import  RPi.GPIO as GPIO
import time
GPIO.setmode(GPIO.BCM)
GPIO.setwarnings(False)
GPIO.setup(21,GPIO.OUT)
for number in range(0,10):
    GPIO.output(21,GPIO.LOW)
    time.sleep(1)
    GPIO.output(21,GPIO.HIGH)
    time.sleep(0.05)
GPIO.cleanup()
Technico.top
la source
Oui. Ça a du sens.
tazboy
51

Déroulez votre boucle pour comprendre ce qui se passe ici:

for number in range(0,10):
    GPIO.output(21,GPIO.LOW)
    time.sleep(1)
    GPIO.output(21,GPIO.HIGH)

se transforme en:

    GPIO.output(21,GPIO.LOW)
    time.sleep(1)
    GPIO.output(21,GPIO.HIGH)
    GPIO.output(21,GPIO.LOW)
    time.sleep(1)
    GPIO.output(21,GPIO.HIGH)
    GPIO.output(21,GPIO.LOW)
    time.sleep(1)
    GPIO.output(21,GPIO.HIGH)
    # [and so on]

Comme vous pouvez le voir, le réglage de la broche basse suit (près de) immédiatement après l'avoir tournée vers le haut. En effet, votre LED restera dans un état la plupart du temps (c'est-à-dire ce que nous pouvons percevoir à l'œil nu).

Fixez-le comme ceci (pour un cycle d'utilisation de 50:50):

for number in range(0,10):
    GPIO.output(21,GPIO.LOW)
    time.sleep(1)
    GPIO.output(21,GPIO.HIGH)
    time.sleep(1)
Ghanima
la source
Sensationnel. Cela semble si évident maintenant. Merci de m'avoir montré.
tazboy
4
Cela devrait être la réponse acceptée. Cela explique en fait ce qui s'est passé
2
Il peut également être intéressant de noter que la raison pour laquelle print()le code d'origine fonctionne est que l'écriture à l'écran est un processus incroyablement lent et agit essentiellement comme sleep(1)vous l' avez suggéré.
Jacobm001
Bien que cette réponse réussisse mieux à la décomposer, j'ai choisi l'autre réponse car c'était la première solution écrite à mon problème. Le vote global déterminera la meilleure réponse.
tazboy
1
@tazboy pas besoin de vous sentir pressé dans un choix particulier concernant la "réponse acceptée"
Ghanima