微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何使用 gpiozero 按钮方法检查某个按钮何时被按下

如何解决如何使用 gpiozero 按钮方法检查某个按钮何时被按下

我目前正在开展一个小项目,以开始使用 Python 进行物理计算 - 使用树莓派。我正在尝试使用 3 个 LED 和一个按钮来制作游戏。 3 个 LED 将按特定顺序闪烁不同的时间,当琥珀色 LED 亮起时,您必须单击按钮。到目前为止,我已经尝试使用 gpiozero 来识别按钮何时打开并查看它是否在琥珀色 LED 开启的时间范围内。

游戏代码https://codeshare.io/G7qk1j (如果上面的链接不起作用,请告诉我)

代码

def gameEasy():
    print("Level 1 - trial run")
    how_long_to_react = 5
    time_till_started = time.time() + 4
    while time.time() < time_till_started:
        button.when_pressed = None
    button.when_pressed = lambda:clickedRight(ambTime,greenTime,time.time())
    redLed.on()
    time.sleep(2)
    redLed.off()
    AmberLed.on()
    ambTime = time.time()
    greenTime = ambTime + how_long_to_react
    time.sleep(how_long_to_react)
    AmberLed.off()
    greenLed.on()
    time.sleep(0.1)
    greenLed.off()
    time.sleep(10)

目前,为了让它工作,首先,红色 LED 将亮起 2 秒,然后琥珀色 LED 将亮起(目前仅 4 秒作为测试)。当琥珀色 LED 亮起时,即第一次记录时,稍后会检查按钮是否在范围内被单击。我的问题是,如果在计算此变量 (ambTime) 之前单击按钮,则第 58 行将触发错误

    button.when_pressed = lambda:clickedRight(ambTime,time.time()) 
NameError: free variable 'ambTime' referenced before assignment in enclosing scope

我明白为什么会这样,但我不确定如何在琥珀色 LED 亮起之前“阻止”任何按钮点击。如您所见,我有一个 while 循环来尝试在前 4 秒内阻止任何命令,但它充当延迟而不是后台循环(因此它在 4 秒后才会启动下一个代码)。

我注意到这种方法 - button.when_pressed = lambda:clickedRight(ambTime,time.time()) - 它总是在检查按钮按下情况,无论该行在代码中的哪个位置,所以我是否将这一行放在之前并不重要AmberLed.on()

我希望我已经正确地解释了这一点,这一直困扰着我很长一段时间,所以任何帮助将不胜感激。我尝试过多处理,但对如何在此处集成它感到非常困惑,但我愿意接受任何建议。我完全理解您可能无法测试您的代码,因此我很乐意尝试任何事情并回答出现的任何问题(如果有的话)。

谢谢。

解决方法

正如您所指出的;运行...

    button.when_pressed = lambda:clickedRight(ambTime,greenTime,time.time())

...立即启动一个监控按钮点击的线程,如果 您的 lambda 函数在 ambTime 定义之前运行,它将失败。 最简单的解决方案可能是将 ambTime 初始化为某个值 在设置 button.when_pressed 操作之前,例如:

def gameEasy():
    ...
    ambTime = None
    button.when_pressed = lambda:clickedRight(ambTime,time.time())
    ...

在您的 clickedRight 函数中,明确检查是否 ambTime 具有有效值。也许是这样的:

def clickedRight(led_clicked_time,led_after_turnedon_time,button_time):
    if led_clicked_time is not None and (
      button_time >= led_clicked_time and
      button_time <= led_after_turnedon_time
    ):
        print("Yay")
    else:
        print("Missed")
    button.when_pressed = None

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。