Пытаюсь сделать своего рода проект светомузыки. Вкратце что делает код в данный момент. Данный код производит запись аудио с 3 источников и считывает уровень громкость. Если громкость становиться выше 100 единиц, то активируется другой код связанный с Ардуино. В нем необходимо поочередно активировать пины с задержкой. Проблема заключается в том что time.sleep останавливает работу записи звука и если в момент когда код стоит на паузе звук станет выше 100 единиц программа это не успеет зафиксировать и пропустит. Мне нужно, что следующее: 1. считывание 3 каналов звука с трех дорожек 2. Если звук в одной из дорожек стал выше 100, то необходимо активировать пин11 потом задержка, отключить пин11 задержка активировать пин9 потом задержка, отключить пин9. 3. если во время действия 2 условия звук в одном из двух других аудио каналах будет выше 100 то ПОСЛЕ окончания 2 условия необходимо сделать то же самое в, то же самое и с другими дорожками. РЕДАКТИРОВАННО: Я видимо не корректно описал работу pyaudio. Она не считывает данные с ардуино. Она работает непосредственно с ПК. Установлена программа, которая создает виртуальные аудио дорожки эти аудио дорожки прикрепляются к 3 открытым приложениям. Название аудио дорожек Line (1-4). Обращение к ним происходит через Код (Python): device_indices = [3, 4, 5, 6] . Код (Python): from pyfirmata import Arduino, SERVO, util import time, pyfirmata import pyaudio import audioop from random import randint, uniform import random t1 = random.uniform(0.05, 0.1) t2 = random.uniform(0.1, 0.15) t3 = random.uniform(0.5, 0.53) win1 = 1 win2 = 1 win3 = 1 arduino = 1 # вкл адруино kanal1 = 100 kanal2 = 100 kanal3 = 100 kanal4 = 50000 start_time = time.time() start_time1 = time.time() start_time2 = time.time() listening_start_time = time.time() listening_start_time1 = time.time() listening_start_time2 = time.time() if arduino == 1: p0 = uniform(60, 70) board = Arduino('COM6') pin_9 = 9 board.digital[pin_9].mode = pyfirmata.OUTPUT pin_10 = 10 # 1 board.digital[pin_10].mode = pyfirmata.OUTPUT pin_11 = 11 board.digital[pin_11].mode = pyfirmata.OUTPUT pin_12 = 12 board.digital[pin_12].mode = pyfirmata.OUTPUT while True: def open_microphone_stream(device_index): p = pyaudio.PyAudio() stream = p.open(format=pyaudio.paInt16, channels=1, rate=44100, input=True, frames_per_buffer=1024, input_device_index=device_index) return stream def record_from_multiple_microphones(): device_indices = [3, 4, 5, 6] # индексы микрофонов streams = [open_microphone_stream(idx) for idx in device_indices] return streams if __name__ == "__main__": audio_streams = record_from_multiple_microphones() if win3 == 1: data2 = audio_streams[1].read(1024) # Чтение данных со второго микрофона rms2 = audioop.rms(data2, 2) print("2 Канал:", rms2) if win1 == 1: data3 = audio_streams[2].read(1024) # Чтение данных с третьего микрофона rms3 = audioop.rms(data3, 2) print("3 Канал:", rms3) if win2 == 1: data4 = audio_streams[3].read(1024) # Чтение данных с четвертого микрофона rms4 = audioop.rms(data4, 2) print("4 Канал:", rms4) audio_streams[0].stop_stream() audio_streams[0].close() audio_streams[1].stop_stream() audio_streams[1].close() audio_streams[2].stop_stream() audio_streams[2].close() audio_streams[3].stop_stream() audio_streams[3].close() if __name__ == "__main__": audio_streams = record_from_multiple_microphones() if win1 == 1: if rms3 > kanal1 and time.time() - start_time > 5: start_time = time.time() listening_start_time = time.time() execute_code1() def execute_code1(): time.sleep(t1) board.digital[pin_11].write(1) time.sleep(t2) board.digital[pin_11].write(0) time.sleep(t3) board.digital[pin_9].write(1) time.sleep(t2) board.digital[pin_9].write(0) if win2 == 1: if rms4 > kanal1 and time.time() - start_time1 > 5: start_time1 = time.time() listening_start_time1 = time.time() execute_code2() def execute_code2(): time.sleep(t1) board.digital[pin_11].write(1) time.sleep(t2) board.digital[pin_11].write(0) time.sleep(t3) board.digital[pin_9].write(1) time.sleep(t2) board.digital[pin_9].write(0) if win3 == 1: if rms2 > kanal3 and time.time() - start_time2 > 5: start_time2 = time.time() listening_start_time2 = time.time() execute_code3() def execute_code3(): time.sleep(t1) board.digital[pin_11].write(1) time.sleep(t2) board.digital[pin_11].write(0) time.sleep(t3) board.digital[pin_9].write(1) time.sleep(t2) board.digital[pin_9].write(0)
Не забывайте, что ADC в ATmegа один, и делать замеры он будет поочереди. А каждый замер это 13 тактов, и совсем не на частоте осцилятора. Не помню точно, но тактирование ADC, для его корректной работы, идёт на частоте сотен килогерц. Добавьте время на получение результатов и запуск нового отсчёта. Одновременного замера не получится.
в ардуине, скорее всего, сделано через одно место. Согласно даташиту, прежде, чем проводить замеры, необходимо выдержать паузу после включения аналоговых цепей. Я так подозреваю, что в ардуине это делается перед каждым замером. Посему, если хочется очень быстрых замеров, то только нативные Си и только на прерываниях. Никаких дурин и, тем более, питонов.
1. Если вы пользуетесь стандартной функцией analogRead() - то она естественно каждый раз повторяет процедуру инициализации и зачистки после себя. Поэтому надо переводить АЦП в авто-режим. Примеры для Ардуины - есть. И примеры ускорения АЦП - тоже 2. А как же без "дурин" ? Софт без харда как свадьба без жениха.)))))) 3. А насчет питонов - это вы верно..
Я видимо не корректно описал работу pyaudio. Она не считывает данные с ардуино. Она работает непосредственно с ПК. Установлена программа, которая создает виртуальные аудио дорожки эти аудио дорожки прикрепляются к 3 открытым приложениям. Название аудио дорожек Line (1-4). Обращение к ним происходит через Код (Python): device_indices = [3, 4, 5, 6]
Я видимо не корректно описал работу pyaudio. Она не считывает данные с ардуино. Она работает непосредственно с ПК. Установлена программа, которая создает виртуальные аудио дорожки эти аудио дорожки прикрепляются к 3 открытым приложениям. Название аудио дорожек Line (1-4). Обращение к ним происходит через Код (Python): device_indices = [3, 4, 5, 6]
По сути мне просто нужно избавиться от time.sleep(). Что бы он не останавливал работу пргограммы. Код (Python): time.sleep(t1) board.digital[pin_11].write(1) time.sleep(t2) board.digital[pin_11].write(0) time.sleep(t3) board.digital[pin_9].write(1) time.sleep(t2) board.digital[pin_9].write(0) Я попробывал изменить код по сути вышел костыль Код (Python): if win2 == 1: if rms4 > kanal1 and time.time() - start_time1 > 5: start_time1 = time.time() listening_start_time1 = time.time() P11 = 1 P9 = 1 Stop =1 print("WWWWWWWWWWWWWWWW:") if P11 == 1 and time.time() - start_time1 > 0.2: start_time1 = time.time() print("111111111111111111:") P11 = 0 P111=1 board.digital[pin_11].write(1) if P111 == 1 and time.time() - start_time1 > 0.2: start_time1 = time.time() print("22222222222:") P111 = 0 Next = 1 board.digital[pin_11].write(0) if P9 == 1 and Next==1 and time.time() - start_time1 > 0.2: start_time1 = time.time() print("33333333:") P9 = 0 P99 = 1 Next = 0 board.digital[pin_9].write(1) if P99 == 1 and time.time() - start_time1 > 0.2: start_time1 = time.time() print("44444444:") Stop = 0 P99 = 0 board.digital[pin_9].write(0) Но есть один нюанс если во время выполнения этого учатка кода Активируется один из других Код (Python): if win3 == 1: if rms2 > kanal3 and time.time() - start_time2 > 5: или Код (Python): if win1 == 1: if rms3 > kanal1 and time.time() - start_time > 5: То он не успевает полность выполнеиться и происходит свого рода смешивание незавершонного кода с новым. Я понимаю что это очень плохой вариант решить проблему но другие у меня не получились.