raspberry上GPIO的Python回调问题

2024-04-29 07:24:44 发布

您现在位置:Python中文网/ 问答频道 /正文

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

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

按钮用回调函数去抖动。一切都很好,除了新音乐加载到U盘后,按钮不再工作。在

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

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

#!/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() 

希望有人能帮我吗?在

马提亚斯


Tags: toimportclientgpioifosdevicedef
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) 

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

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

相关问题 更多 >