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?



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

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)

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
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.