2016-01-18 58 views
0

我是一個絕對的python新手,這是我的第一個樹莓項目。我嘗試構建一個簡單的音樂播放器,其中每個輸入按鈕加載一個不同的專輯(8個專輯)和3個按鈕來控制播放(下一個,暫停,最後)。覆盆子上的GPIO的Python回調問題

要加載音樂,我使用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

+0

很難說,因爲在while標誌== 0之後的行中代碼中存在縮進錯誤(在完整源代碼中爲150行)。發佈的代碼應該引發'SyntaxError'異常。你應該發佈實際的來源。可能問題出在那個「while」循環上。 – mhawke

+0

我試圖修復如上所述的縮進 - 但仍然沒有運氣。我沒有得到任何SytaxnError異常。所有工作正常,從USB複製後音樂開始播放。但拔掉USB驅動器後,按鈕仍不起作用。 「你應該發佈實際來源」是什麼意思?這是我擁有的一切。 (我更新了帖子和Dropbox中的代碼)。致謝迄今 – matto

+0

@matto描述問題的最好方法是提供簡短的工作代碼。你幾乎在那裏,只需添加很少的進口就可以澄清你使用的GPIO庫。不建議在Dropbox上提供代碼,因爲在鏈接停止工作後代碼仍然是問題的一部分。簡化工作代碼示例需要一些工作,但通常會導致直接解決方案或更快的回答。 –

回答

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

按鈕不工作的原因是因爲你仍然在回調函數 - 所以它不能再次觸發。解決方法是使用回調函數簡單地設置一個標誌並讓主要的等待循環檢測標誌並進行播放。但請注意,播放可能會阻止,因此主循環也會在此期間停止。