Raspberry PI 带有 GPIO 输入按钮
Raspberry PI with GPIO Input buttons
我有一个PI 运行 4个GPIO输入端口。
目标是,如果按下 4 个按钮中的一个,则应播放 mp3 文件,即 button1 = file1.mp3,button2 = file2.mp3 等等。
它似乎没有那么复杂,但是 'the devil is in the detail' :-)
这是我目前 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 次。
所以我正在寻找这样的解决方案:
在播放文件时,此时所有输入按钮都应为 "disabled"。当mp3文件支付完成后,按钮应该是"re-enabled",可以按下另一个按钮。
我该怎么做?感谢您的帮助。
我没有看到不添加线程就可以做到这一点的简单方法。请注意,您已经隐式地使用 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 的代码。
谢谢你的帮助,布赖恩。你把我带到了正确的方向!
我知道了。正如我上面所描述的,它现在正在工作。
这是我的代码:
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" 的播放时间。而已。
再次感谢。
我有一个PI 运行 4个GPIO输入端口。 目标是,如果按下 4 个按钮中的一个,则应播放 mp3 文件,即 button1 = file1.mp3,button2 = file2.mp3 等等。 它似乎没有那么复杂,但是 'the devil is in the detail' :-) 这是我目前 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 次。
所以我正在寻找这样的解决方案: 在播放文件时,此时所有输入按钮都应为 "disabled"。当mp3文件支付完成后,按钮应该是"re-enabled",可以按下另一个按钮。
我该怎么做?感谢您的帮助。
我没有看到不添加线程就可以做到这一点的简单方法。请注意,您已经隐式地使用 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 的代码。
谢谢你的帮助,布赖恩。你把我带到了正确的方向! 我知道了。正如我上面所描述的,它现在正在工作。 这是我的代码:
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" 的播放时间。而已。 再次感谢。