除非我使用“打印”,否则循环不起作用


11

此代码不会打开和关闭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()

但是当我打印出循环中的数字时,它确实起作用了:

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

知道为什么吗?



2
@cat Bingo,“发生Heisenbug的原因是调试程序的常见尝试,例如插入输出语句”
tazboy

1
“此代码不会打开和关闭led。” - 我不敢苟同。
marcelm

Answers:


22

尝试用替换您printtime.sleep(0.05)。由于GPIO。输出从HIGH切换到LOW的速度太快而无法设置/检测/看到,因此可能会发生这种奇怪的行为。增加/减少睡眠持续时间,直到程序正常运行(增加)并足够快地运行(减少)。

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

是的 那讲得通。
tazboy

51

展开循环以了解此处发生的情况:

for number in range(0,10):
    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)
    GPIO.output(21,GPIO.LOW)
    time.sleep(1)
    GPIO.output(21,GPIO.HIGH)
    # [and so on]

如您所见,将其设置为高电平之后立即将其设置为低电平。实际上,您的LED大部分时间都将保持一种状态(即我们可以用肉眼看到的状态)。

像这样修复它(占空比为50:50):

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

哇。现在看来是如此明显。谢谢你给我看
tazboy

4
这应该是公认的答案。它实际上解释了发生的情况

2
可能还值得注意的是,print()导致原始代码正常工作的原因是因为写入屏幕是一个非常缓慢的过程,并且基本上按照sleep(1)您的建议进行操作。
Jacobm001

尽管此答案的分解效果更好,但我还是选择了另一个答案,因为这是我所遇到问题的第一个书面解决方案。总体投票将确定更好的答案。
tazboy

1
@tazboy无需感到自己对“接受的答案”有任何选择的压力
Ghanima
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.