Raspberry PI带有GPIO输入按钮

时间:2015-12-10 18:16:07

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

我有一个运行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文件付款完成后,按钮应该重新启用"并且可以按下另一个按钮。

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

2 个答案:

答案 0 :(得分:0)

在没有添加线程的情况下,我没有看到一种简单的方法。请注意,您隐式使用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。并且starts_23变量会跟踪声音的启动时间,以防止再重播10秒。您可以增加它以包括文件时间的长度。您可以在同一循环中为GPIO 24添加代码。

答案 1 :(得分:0)

感谢您的帮助,Brian。你带我到了正确的方向! 我知道了。它正如我上面所描述的那样工作。 这是我的代码:

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)

问题是,借调的文件是在第一次完成之前启动的。因为代码不知道当前播放文件的时间长度。因此,当执行此文件时,我将audiofile的时间放在“vtc”值中。 如果按另一个按钮,它将计算播放当前文件时间“vtc”的时间。而已。 再次感谢。