2016-01-12 26 views
1

我需要在樹莓派的python程序中執行一個bash命令,它會啓動一個記錄,如果它們是上面的聲音某個頻率並在8秒後結束或者如果有沉默。記錄完成後,它開始等待新的聲音錄製。每個記錄都標有時間。這是代碼做我引用在這裏:需要通過userinput來結束子進程的循環(GPIO.input)

while GPIO.input(26) == False: 
    timestamp = datetime.datetime.now().strftime('%Y%m%d%H%M%S') 
    process = subprocess.Popen ("rec -c 2 -r 192000 --buffer 50000 -b 32" + filepath + timestamp + ".wav sinc 0.1k silence 1 0.1 0.8% 1 0.4 0.8% vol 6 trim 0 8", shell = True) 
    process.communicate() 

正如你可以看到,完成循環,程序等待GPIO輸入信號(按鈕)。我有一個額外的代碼,它查找子進程的名稱並殺死它。

但是這裏是我的問題:while循環運行時,它只在一個記錄完成和新啓動之間的毫秒內「看起來」輸入「如果我在記錄過程中按下按鈕,循環繼續記錄它只是打破,如果我在推之間。

起初,我想也許while循環是一個不錯的選擇......但如果我沒有錯,問題似乎是正在運行的子進程。

所以這裏是我的問題:我怎樣才能完成這個記錄循環,但可以通過GPIO的用戶輸入在運行記錄期間停止/終止(ctrl + c將不是一個可行的選項)

非常感謝

+0

'while GPIO.input(26)== False:'< - 這個錯誤不會多次觸發嗎?我沒有看到布爾或其他鎖定/去抖動機制的使用,以防止程序啓動100個子進程。 '錄音=假;而GPIO.input(26)== False且不記錄:recording = True; start_recording(); #錄製完成... recording = False;' – jDo

回答

1

問題是,while循環只檢查一次條件每次通過循環。 process.communicate()呼叫等待rec命令完成,所以你是絕對正確的 - 該按鈕只被檢查一次,在rec之後和timestamp = ...之前。

解決方案是在單獨的線程中觀察按鈕,並與rec並行運行。 This answer建議使用來自RPi.GPIO庫的event detection。嘗試是這樣的:

should_exit = False 

def my_callback(channel): 
    if GPIO.input(26): 
     should_exit = True 

GPIO.add_event_detect(26, GPIO.RISING, callback=my_callback, bouncetime=300) 

while not should_exit: 
    timestamp = ... 

my_callback程序應該運行時按下按鈕,並設置should_exit標誌。一旦rec完成,while將檢查should_exit並終止。 (注意 - 未經測試!)

+0

非常感謝,我會試試看 - 我的問題是,我也想取消正在運行的記錄 - 但我猜 - 用這種方法我可以執行kill-script – Esmi

+0

好吧,我嘗試了它 - 事件檢測工程 - 有時 - 但它似乎很不可靠 – Esmi

+0

很高興它比沒有好!恐怕我對RPi.GPIO沒有親身經歷。按鈕是否有適當的上拉或下拉?所有的連接都是固定的嗎?間歇性操作可能是硬件問題。另外,嘗試一個不運行'rec'的循環,但只是打印一條調試消息並查看按鈕是否被正確檢測到。 – cxw