【问题标题】:Raspberry PI with GPIO Input buttons带有 GPIO 输入按钮的 Raspberry PI
【发布时间】:2015-12-10 18:16:06
【问题描述】:

我有一个运行 4 个 GPIO 输入端口的 PI。 目标是,如果按下 4 个按钮中的一个,则应该播放一个 mp3 文件,即 button1 = file1.mp3,button2 = file2.mp3 等等。 它似乎没有那么复杂,但是'魔鬼在细节中':-) 这是我目前 2 个按钮的代码:

#!/usr/bin/env python
#coding: utf8

import time 
from time import sleep
import os
import RPi.GPIO as GPIO

GPIO.setmode(GPIO.BCM)

GPIO.setup(24, GPIO.IN, pull_up_down = GPIO.PUD_DOWN)
GPIO.setup(23, GPIO.IN, pull_up_down = GPIO.PUD_DOWN)


def my_callback_1(channel):
  print("Button 23 Pressed")
  os.system('omxplayer -o both /root/1.mp3')
  sleep(10)

def my_callback_2(channel):
  print("Button 24 Pressed")
  os.system('omxplayer -o both /root/2.mp3')
  sleep(10)

GPIO.add_event_detect(23, GPIO.RISING, callback=my_callback_1, bouncetime=200)
GPIO.add_event_detect(24, GPIO.RISING, callback=my_callback_2, bouncetime=200)

try:
  while 1:
          time.sleep(0.5)

except KeyboardInterrupt:
    # exits when you press CTRL+C
    print("  Bye Bye") 

except:
    print("Other error or exception occurred!")

finally:
    GPIO.cleanup() # this ensures a clean exit

睡眠时间设置为 mp3 文件中较长的时间。 它的工作,但不像我预期的那样。 问题是,当文件已经在播放时按下按钮时,PI 会将按钮按下保持在缓冲区中,并在当前文件之后循环播放文件。 想象一下,有人按下同一个按钮 5 次,同一个 mp3 文件将循环播放 5 次。

所以我在寻找这样的解决方案: 播放文件时,此时应“禁用”所有输入按钮。当mp3文件付费完成后,按钮应该是“重新启用”并且可以按下另一个按钮。

我怎么能这样?感谢您的帮助。

【问题讨论】:

  • “播放文件时,所有输入按钮都应该“禁用”” -- 这是用户的观点。在编程级别,输入不应或不能“禁用”。程序应该接受输入,并根据玩家的当前状态处理(或不处理)事件。该事件将被您的处理程序“禁用”或启用,忽略或处理每个事件。

标签: python-3.x raspberry-pi gpio


【解决方案1】:

我没有看到不添加线程的简单方法。请注意,您已经隐式地使用add_event_detect() 在幕后使用线程,它在单独的线程中运行回调。如果add_event_detect 不支持抑制按钮按下(我认为它不支持),那么您可以通过以下两种方式之一进行线程化 - 使用 python 线程或进程,或者使用 bash 更简单的方式。

要在 bash 中使用后台进程,请删除您的 add_event_detect 调用,然后在您的 while 循环中执行类似(未经测试)的操作:

started_23 = 0
while True:
    if GPIO.input(23) and time.time() - started_23 > 10:
        started_23 = time.time()
        print("Button 23 Pressed")
        os.system('omxplayer -o both /root/1.mp3 &')
    time.sleep(0.200)

注意添加到 system() 调用中的 & 符号 - 这将在后台运行 omxplayer。并且 started_23 变量跟踪声音何时开始,以防止再播放 10 秒。您可以增加它以包括文件时间的长度。您可以类似地在同一循环中添加 GPIO 24 的代码。

【讨论】:

    【解决方案2】:

    谢谢你的帮助,布赖恩。你把我带向了正确的方向! 我得到了它。正如我上面描述的那样,它现在正在工作。 这是我的代码:

    try:
    
            vtc1 = 8        # Time Audiofile 1
            vtc2 = 11       # Time Audiofile 2
            vtc3 = 0        # Time Audiofile 3
            vtc4 = 0        # Time Audiofile 4
    
            vtc = 0         # Current AudioFileTime
            started_t = 0   # Started Time
    
    
            while True:
                    if GPIO.input(23) and time.time() - started_t > vtc:
                            vtc = vtc1
                            started_t = time.time()
                            print("Button 23 Pressed")
                            os.system('omxplayer -o both /root/1.mp3 &')
                    time.sleep(0.200)
    
                    if GPIO.input(24) and time.time() - started_t > vtc:
                            vtc = vtc2
                            started_t = time.time()
                            print("Button 24 Pressed")
                            os.system('omxplayer -o both /root/2.mp3 &')
                    time.sleep(0.200)
    

    问题是,第二个文件是在第一个文件完成之前启动的。因为代码不知道当前播放文件的较长时间。所以我在执行该文件时将音频文件的时间放在“vtc”值中。 如果您按下另一个按钮,它会计算当前文件时间“vtc”播放的时间。而已。 再次感谢。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-07-08
      • 1970-01-01
      • 2017-03-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多