Loop no funciona a menos que use 'print'

11

Este código no enciende ni apaga el 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()

pero cuando imprimo el número en el bucle 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()

¿Alguna idea de por qué es eso?

tazboy
fuente
1
ver enwp.org/Heisenbug
gato
2
@cat Bingo, "Heisenbugs ocurren porque los intentos comunes de depurar un programa, como insertar declaraciones de salida"
tazboy
1
"Este código no enciende ni apaga el led". - Siento disentir.
marcelm

Respuestas:

22

Intenta reemplazar tu printpor a time.sleep(0.05). Puede ocurrir este comportamiento extraño cuando GPIO. La salida se cambia demasiado rápido de ALTO a BAJO para ser configurado / detectado / visto. Aumente / reduzca la duración del sueño hasta que el programa funcione bien (aumente) y lo suficientemente rápido (disminuya).

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
fuente
Sí. Eso tiene sentido.
tazboy
51

Desenrolle su bucle para comprender lo que está sucediendo aquí:

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

se convierte 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]

Como puede ver, el ajuste del pin bajo sigue (cerca de) inmediatamente después de ponerlo en alto. En efecto, su LED permanecerá en un estado la mayor parte del tiempo (es decir, lo que podemos percibir a simple vista).

Solucionelo de esta manera (para un ciclo de trabajo 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
fuente
Guau. Eso parece tan obvio ahora. Gracias por mostrarme
tazboy
44
Esta debería ser la respuesta aceptada. En realidad explica lo que sucedió
2
También vale la pena señalar que la razón por la print()que el código original funciona es porque escribir en la pantalla es un proceso increíblemente lento y esencialmente actúa como sleep(1)lo sugirió.
Jacobm001
Aunque esta respuesta hace un mejor trabajo al descomponerla, elegí la otra respuesta porque era la primera solución escrita a mi problema. La votación general determinará la mejor respuesta.
tazboy
1
@tazboy no necesita sentirse presionado a tomar ninguna decisión en particular con respecto a la "respuesta aceptada"
Ghanima