覆盆子上的GPIO的Python回调问题

时间:2016-01-18 10:36:49

标签: python callback raspberry-pi

我是一个绝对的蟒蛇新手,这是我的第一个覆盆子项目。我尝试构建一个简单的音乐播放器,其中每个输入按钮加载不同的专辑(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() 

希望有人能帮助我吗?

的Matthias

2 个答案:

答案 0 :(得分:0)

这就是我的诀窍。可能它不是最好的解决方案,但它可以解决问题。 只有主要功能被改变了。通过注释在行的开头突出显示更改。

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() 

答案 1 :(得分:0)

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