GPIO.setup和GPIO.cleanup在KeyboardInterrupt时的RuntimeWarnings不生效

8 投票
3 回答
47236 浏览
提问于 2025-04-18 06:41

我在使用树莓派的代码上遇到了问题。刚开始学Python,所以需要一些帮助。

这是我的代码:

import RPi.GPIO as GPIO
import time

GPIO.setmode(GPIO.BCM)

led1=22
led2=17

GPIO.setup(led1, GPIO.OUT)
GPIO.setup(led2, GPIO.OUT)

def blink():
    GPIO.output(led1, 1)
    time.sleep(1)
    GPIO.output(led1, 0)

    GPIO.output(led2, 1)
    time.sleep(1)
    GPIO.output(led2, 0)

while(blink):
    blink()

try:
    main()
except KeyboardInterrupt:
    GPIO.cleanup()

当我运行这个代码时,控制台出现了以下错误:

运行时警告:这个通道已经在使用中,继续执行。使用 GPIO.setwarnings(False)来禁用警告。GPIO.setup(led1, GPIO.OUT) 和:

运行时警告:这个通道已经在使用中,继续执行。使用 GPIO.setwarnings(False)来禁用警告。GPIO.setup(led2, GPIO.OUT)

如果我理解正确,命令 GPIO.cleanup() 应该重置所有GPIO端口的引脚,并关闭LED。

但实际上并没有发生,事实上有一个LED保持亮着。

我该如何修改我的代码来解决这个问题呢?

3 个回答

2

你在调用 main() 这个函数,但它并没有被声明(定义)。你在使用 while(blink)。所以你需要删掉 "main()",然后把 "Try" 放在你的主函数前面,也就是 while(blink) 循环的前面。别忘了要注意缩进哦。

9

你在提问的时候好像没有包含 main 这个部分。不过,如果程序因为其他原因而退出,而不是因为 KeyboardInterrupt(就是你按下了键盘的中断键),那么就可能会出现问题。为了更好地释放资源,建议把相关代码放在 finally 这个块里。

try:
    main()
except KeyboardInterrupt:
    pass
finally:
    GPIO.cleanup()
10

这里有一些小建议,教你如何有效地将你的函数分开,并让它们更通用。虽然我提供了一个可以运行的Python脚本,但我没有在我的树莓派上测试过,不过我觉得应该没问题——如果有任何问题,请告诉我!

import RPi.GPIO as GPIO
import time

# Module level constants
LED1 = 22
LED2 = 17

# Sets up pins as outputs
def setup(*leds):
    GPIO.cleanup()
    GPIO.setmode(GPIO.BCM)
    for led in leds:
        GPIO.setup(led, GPIO.OUT)
        GPIO.output(led, GPIO.LOW)

# Turn on and off the leds
def blink(*leds):
    # Blink all leds passed
    for led in leds:
        GPIO.output(led, GPIO.HIGH)
        time.sleep(1)
        GPIO.output(led, GPIO.LOW)

if __name__ == '__main__':
    # Setup leds
    setup(LED1, LED2)
    # Run blinking forever
    try:
        while True:
            blink(LED1, LED2)
    # Stop on Ctrl+C and clean up
    except KeyboardInterrupt:
        GPIO.cleanup()

友情提示:

还有一个专门针对树莓派的StackExchange网站: https://raspberrypi.stackexchange.com/

撰写回答