2016-01-12 3 views
1

Мне нужно выполнить команду bash в программе python на малине pi, которая запускает запись, которая действительно начинает запись, если их звук выше определенную частоту и заканчивается после 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-входного сигнала (кнопка). У меня есть дополнительный код, который ищет имя подпроцесса и убивает его.

Но вот моя проблема: пока цикл работает, он только «смотрит» на вход в миллисекундах между одной записью и новым запуском ». Если я нажимаю свою кнопку во время записи, цикл продолжается после записи . это только ломается, если я нажимаю между ними.

Сначала я думал, что, может быть, в то время как петля плохой выбор ... но если я не ошибаюсь, проблема, кажется, работает подпроцесс.

Итак, вот мой вопрос: как я могу выполнить этот цикл записи, но могу остановить/убить во время текущей записи через пользовательский ввод с помощью GPIO. (Ctrl + c не будет жизнеспособным вариантом)

Большое спасибо

+0

'в то время как GPIO.input (26) == False:' <- не срабатывает ли этот огонь несколько раз, когда это ложно? Я не вижу никакого использования логических или других механизмов блокировки/debouncing, чтобы ваша программа не запускала 100 подпроцессов. 'record = False; в то время как GPIO.input (26) == False и не записывается: запись = True; начать запись(); # запись заканчивается ... запись = False; ' – jDo

ответ

1

Проблема в том, что цикл while проверяет условие только один раз через цикл. Вызов process.communicate() ждет завершения команды rec, поэтому вы абсолютно правы - кнопка проверяется только один раз, сразу после rec и до timestamp = ....

Решение состоит в том, чтобы следить за кнопкой в ​​отдельном потоке, работая параллельно с rec. This answer предлагает использовать event detection из библиотеки RPi.GPIO. Попробуйте что-то вроде этого:

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

Смежные вопросы