Raspberry Pi (Python) - 按下(并按住)按钮来运行脚本循环

问题描述 投票:0回答:1

我正在尝试编写一个程序,该程序将使 LED 闪烁(并最终 - 希望 - 闪烁一小条 LED )。它看起来像闪电 - 或闪烁的电流(用于电椅万圣节道具)

我从许多来源拼凑了以下内容。该脚本应该让灯泡启动。当按下按钮时,它会运行循环并使 LED 闪烁。这是可行的,但是当松开按钮时,它应该关闭灯泡并退出该循环。但不是剧本。然后它应该只是坐下来等待再次按下按钮。

这里让我挠头!!感谢您的帮助。

import RPi.GPIO as GPIO
import time           
import random
import math

bulb = 18
button = 23
pwms = []
intensity = 1.0

def setupGPIO():
    GPIO.setmode(GPIO.BCM)
    GPIO.setwarnings(False)
    GPIO.setup(bulb, GPIO.OUT, initial=GPIO.LOW)
    GPIO.setup(button, GPIO.IN, pull_up_down=GPIO.PUD_UP)
    # GPIO.add_event_detect(button, GPIO.BOTH, callback=handleButtonPress, bouncetime=300)

def handleButtonPress():
    p = GPIO.PWM(bulb, 300)
    p.start(0)
    while True:
        GPIO.wait_for_edge(button, GPIO.FALLING)
        p.ChangeDutyCycle(random.randint(1, 44) * math.pow(intensity, 2) if intensity > 0 else 0)
        rand_flicker_sleep()
        while GPIO.input(button) == GPIO.LOW:
            print("button is being pressed")

def rand_flicker_sleep():
    time.sleep(random.randint(3, 10) / 100.0)
    
def flicker_it(_):
    global intensity
    intensity = min(0, 1.0)

def main():
    try:
        setupGPIO()
        handleButtonPress()
    except KeyboardInterrupt:
        pass
    finally:
        for p in pwms:
            p.stop()
        GPIO.cleanup()

if __name__ == '__main__':
    main()

它在 Rpi 3b 上使用 python3(如果这有区别的话!)

python python-3.x raspberry-pi raspberry-pi3
1个回答
0
投票

原脚本问题: 无限循环:原始的handleButtonPress函数有一个无限循环,无法正确处理按钮释放以关闭LED。

未使用的变量和函数:脚本中未使用一些变量和函数(pwms 和 flicker_it)。

清理:该脚本无法确保正确清理 GPIO 设置和 PWM 实例。

更新的脚本: 简化的循环:handleButtonPress 函数现在使用 GPIO.wait_for_edge(button, GPIO.FALLING) 等待按钮按下。当按下按钮时,它会进入一个循环,在按住按钮的同时 LED 会闪烁。松开按钮后,LED 熄灭。 删除了未使用的代码:pwms 列表和 flicker_it 函数已被删除,因为脚本中未使用它们。 正确的清理:finally 块确保 PWM 实例停止并清理 GPIO 设置,即使脚本被中断也是如此。

import RPi.GPIO as GPIO
import time           
import random
import math

bulb = 18
button = 23
intensity = 1.0

def setupGPIO():
    GPIO.setmode(GPIO.BCM)
    GPIO.setwarnings(False)
    GPIO.setup(bulb, GPIO.OUT, initial=GPIO.LOW)
    GPIO.setup(button, GPIO.IN, pull_up_down=GPIO.PUD_UP)

def handleButtonPress():
    p = GPIO.PWM(bulb, 300)
    p.start(0)
    try:
        while True:
            GPIO.wait_for_edge(button, GPIO.FALLING)
            while GPIO.input(button) == GPIO.LOW:
                p.ChangeDutyCycle(random.randint(1, 44) * math.pow(intensity, 2) if intensity > 0 else 0)
                rand_flicker_sleep()
            p.ChangeDutyCycle(0)  # Turn off the LED when the button is released
    except KeyboardInterrupt:
        pass
    finally:
        p.stop()
        GPIO.cleanup()

def rand_flicker_sleep():
    time.sleep(random.randint(3, 10) / 100.0)

def main():
    setupGPIO()
    handleButtonPress()

if __name__ == '__main__':
    main()

它是如何工作的: 设置:setupGPIO 函数初始化灯泡和按钮的 GPIO 设置。 按钮按下处理:handleButtonPress 函数等待按钮被按下。按下时,它会通过改变 PWM 信号的占空比来闪烁 LED。闪烁效果是通过随机改变占空比并添加小的睡眠间隔来实现的。

按钮释放处理:释放按钮时,占空比设置为 0,关闭 LED。

清理:finally 块确保 PWM 实例停止并正确清理 GPIO 设置。

此更新的脚本应该能够为您提供所需的效果,即按下按钮时 LED 闪烁,释放按钮时 LED 熄灭,同时确保脚本可以等待再次按下按钮。

© www.soinside.com 2019 - 2024. All rights reserved.