O loop não funciona, a menos que eu use 'print'

11

Este código não liga e desliga o 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()

mas quando imprimo o número no loop, ele funciona:

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()

Alguma idéia do porquê disso?

tazboy
fonte
1
consulte enwp.org/Heisenbug
cat
2
@cat Bingo, "Heisenbugs ocorrer porque tentativas comuns para depurar um programa, como a inserção de instruções de saída"
tazboy
1
"Este código não liga e desliga o led." - Eu peço desculpa mas não concordo.
marcelm

Respostas:

22

Tente substituir o seu printpor um time.sleep(0.05). Você pode ocorrer esse comportamento estranho, já que o GPIO.output é alternado muito rapidamente de HIGH para LOW para ser definido / detectado / visto. Aumente / reduza a duração do sono até que o programa funcione bem (aumente) e rápido o suficiente (diminua).

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
fonte
Sim. Isso faz sentido.
tazboy
51

Desenrole seu loop para entender o que está acontecendo aqui:

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

torna-se em:

    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]

Como você pode ver, a definição do pino baixo segue (próximo a) imediatamente após o alto. De fato, seu LED permanecerá em um estado durante a maior parte do tempo (isto é, o que podemos perceber a olho nu).

Corrija assim (para um ciclo de trabalho 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
fonte
Uau. Isso parece tão óbvio agora. Obrigado por me mostrar.
tazboy
4
Essa deve ser a resposta aceita. Na verdade, ele explica o que aconteceu
2
Também pode ser interessante notar que o motivo pelo qual print()o código original funciona é porque a gravação na tela é um processo incrivelmente lento e está essencialmente agindo conforme o sleep(1)sugerido.
Jacobm001
Embora essa resposta funcione melhor, eu escolhi a outra resposta porque foi a primeira solução escrita para o meu problema. A votação geral determinará a melhor resposta.
tazboy
1
@tazboy nenhuma necessidade de sentir-se sendo pressionados a qualquer escolha particular no que respeita a "resposta aceito"
Ghanima