【问题标题】:Python callback issue with GPIO on raspberry覆盆子上 GPIO 的 Python 回调问题
【发布时间】:2016-06-11 19:07:30
【问题描述】:

我绝对是 python 新手,这是我的第一个 raspberry 项目。我尝试构建一个简单的音乐播放器,其中每个输入按钮加载不同的专辑(8 个专辑)和 3 个按钮来控制播放(下一个、暂停、最后一个)。

为了加载音乐,我使用 USB 驱动器,一旦连接它就会自动触发复制过程。

按钮使用回调函数去抖动。一切都很好,只是在使用 USB 驱动器加载新音乐后,按钮不再起作用。

这很可能是一个简单的编程问题,我 - 作为一个初学者 - 只是看不到。

这是使用两个按钮的代码:

#!/usr/bin/env python 

import RPi.GPIO as GPIO 
import os 
import pyudev 
from time import sleep 
from mpd import MPDClient 
from socket import error as SocketError 

# Configure MPD connection settings 
HOST = 'localhost' 
PORT = '6600' 
CON_ID = {'host':HOST, 'port':PORT} 

#Configure Buttons 
Button1 = 25 
Button2 = 24 


GPIO.setmode(GPIO.BCM) 
GPIO.setup(Button1, GPIO.IN) 
GPIO.setup(Button2, GPIO.IN) 


client = MPDClient() 

#Function to check if USB is connected 
def checkForUSBDevice(name): 
        res = "" 
        context = pyudev.Context() 
        for device in context.list_devices(subsystem='block', DEVTYPE='partition'): 
                if device.get('ID_FS_LABEL') == name: 
                        res = device.device_node 
        return res 

#Function to load music from USB         
def loadMusic(client, con_id, device): 
        os.system("mount "+device+" /music/usb") 
        os.system("/etc/init.d/mpd stop") 
        os.system("rm -r /music/mp3/*") 
        os.system("cp -r /music/usb/* /music/mp3/") 
        os.system("umount /music/usb") 
        os.system("rm /music/mpd/tag_cache") 
        os.system("/etc/init.d/mpd start") 
        os.system("mpc clear") 
        os.system("mpc ls | mpc add") 
        os.system("/etc/init.d/mpd restart") 

#Function to connect to MPD 
def mpdConnect(client, con_id): 
        try: 
                client.connect(**con_id) 
        except SocketError: 
                return False 
        return True 

#Function to load an Album 
def loadAlbum(number): 
    mpdConnect(client, CON_ID)   
    if client.status()["state"] == "play" or client.status()["state"] == "pause": client.stop()  
    os.system("mpc clear") 
    os.system("mpc ls "+str(number)+" | mpc add") 
    client.play() 
    client.disconnect() 



#Callback Function 
def buttonPressed(channel): 
    if channel == Button1: 
        print('Button 1 HIT') 
        loadAlbum(1) 
    elif channel == Button2: 
        print('Button 2 HIT') 
        loadAlbum(2) 


def main(): 
    GPIO.add_event_detect(Button1, GPIO.RISING, callback=buttonPressed, bouncetime=200) 
    GPIO.add_event_detect(Button2, GPIO.RISING, callback=buttonPressed, bouncetime=200) 

    # This function just creates an endless loop which does 
    # nothing, in order for the button detection to work  
    try: 
        flag = 0 
        while flag == 0: 
            device = checkForUSBDevice("MUSIC") # MUSIC is the name of my thumb drive  
            if flag == 1: 
                flag = 0 
            else: 
                flag = 0 

            if device != "":  
            # USB thumb drive has been inserted, new music will be copied  
                print('USB erkannt, Musik wird kopiert.', device) 
                loadMusic(client, CON_ID, device)   
                print('Musik wurde kopiert, USB kann entfernt werden!', device) 
                while checkForUSBDevice("MUSIC") == device: 
                    sleep(1.0) 
                print('USB wurde entfernt.') 
                loadAlbum(1) 

    except KeyboardInterrupt: 
        GPIO.cleanup()  



if __name__ == "__main__": 
    main() 

希望有人可以帮助我吗?

马蒂亚斯

【问题讨论】:

  • 这很难说,因为在while flag == 0: 之后的代码行中存在缩进错误(完整源代码中的第 150 行)。发布的代码应引发SyntaxError 异常。您应该发布实际来源。可能问题出在while 循环上。
  • 我试图修复上面提到的缩进 - 但仍然没有运气。我没有收到任何 SytaxnError 异常。一切正常,音乐从 USB 复制后开始播放。但是拔掉U盘后按钮仍然不起作用。 “您应该发布实际来源”是什么意思?这就是我所拥有的。 (我更新了帖子和 Dropbox 中的代码)。到目前为止感谢
  • @matto 描述问题的最佳方式是提供简短的工作代码。您快到了,只需添加一些导入即可澄清您使用的 GPIO 库。不建议在 Dropbox 上提供代码,因为在链接停止工作后,代码仍是问题的一部分。使工作代码示例简短需要一些工作,但通常会导致直接解决方案或更快的答案。
  • 感谢您的支持和建议。我已将代码缩短为“两个按钮”版本并将其粘贴到问题中。现在它应该是所有相关的东西。希望任何人都可以提供帮助!
  • “按钮不再起作用”是什么意思?回调函数是否仍然被调用?是否打印了相应按钮的调试消息?您需要尝试确定问题是否与事件处理有关,或者是否与音乐文件的加载和播放有关。

标签: python callback raspberry-pi


【解决方案1】:

这就是我的诀窍。可能这不是最好的解决方案,但它似乎可以解决问题。 仅更改了主要功能。更改在行首以注释突出显示。

def main():  
    GPIO.add_event_detect(Button1, GPIO.RISING, callback=buttonPressed, bouncetime=200)  
    GPIO.add_event_detect(Button2, GPIO.RISING, callback=buttonPressed, bouncetime=200)  

    # This function just creates an endless loop which does  
    # nothing, in order for the button detection to work   
    try:  
        flag = 0  
        while flag == 0:  
            device = checkForUSBDevice("MUSIC") # MUSIC is the name of my thumb drive   
            if flag == 1:  
                flag = 0  
            else:  
                flag = 0  

            if device != "":   
            # USB thumb drive has been inserted, new music will be copied   
                print('USB erkannt, Musik wird kopiert.', device) 

# Stop the callback before loading the files from the USB:  
                GPIO.remove_event_detect(Button1) 
                GPIO.remove_event_detect(Button2) 

                loadMusic(client, CON_ID, device)    
                print('Musik wurde kopiert, USB kann entfernt werden!', device)  
                while checkForUSBDevice("MUSIC") == device:  
                    sleep(1.0)  
                print('USB wurde entfernt.')  
                loadAlbum(1)  

# Recall the main function 
                main() 

    except KeyboardInterrupt:  
        GPIO.cleanup() 

【讨论】:

    【解决方案2】:

    按钮不再起作用的原因是因为您仍在回调函数中-因此无法再次触发。解决方案是使用回调函数简单地设置一个标志,并让主等待循环检测标志并进行播放。但请注意,播放可能会阻塞,因此主循环也会在此期间停止。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-02-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-05-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多