Я ищу совета, чтобы помочь моей схеме/коду/микроконтроллеру работать более надежно и точно. То, что у меня есть сейчас, почти готово, но мне просто не хватает ноу-хау, чтобы получать стабильные показания. Я попытался нарисовать хорошую картину того, что я делаю, и почему так терпите меня, чтобы объяснить.
Цель моего дизайна очень проста — просто передать громкость барабана . Я делаю это через электретный микрофон, в предусилитель, в АЦП на плате PIC18F2620. Моя цель при захвате громкости барабанов — отобразить самые громкие показания за заданный период дискретизации, чтобы пользователь знал, насколько громко он играет. Период выборки установлен примерно на 500 мс, что дает пользователю время, чтобы прочитать его правильно.
Там, где это становится немного сложнее, и где я изо всех сил пытаюсь уловить самую громкую точку транзиентов барабанного удара. Проблема с этими транзиентами заключается в том, что они появляются и исчезают так быстро, что иногда, когда я наношу им хороший удар, они не отображают значение, близкое к тому, насколько громкими они должны были быть. Ниже показано, как выглядит переходный процесс барабана, показывающий, насколько коротким является этот самый громкий момент.
Мой инстинкт подсказывает, что тогда мне нужно больше выборок в секунду, но затем я задаюсь вопросом, решит ли эту проблему меньшее количество, но более длинных выборок (я просто не знаю).
Хорошо, надеюсь, я смог нарисовать картину контекста, вот как я это делал.
Все начинается с электретного конденсаторного капсюля (с номинальным уровнем звукового давления до 130 дБ) и конструкции предусилителя из этого ответа, за исключением того, что я использую LMC6484IMX. Я включил эту деталь на тот случай, если вы увидите, что этот предусилитель не подходит для того, что я пытаюсь сделать.
Выход этого затем подается на вход АЦП моего PIC18F2620. Я решил запустить весь рабочий процесс ADC с прерываниями, чтобы избежать опроса и потери времени.
Он начинается с запуска выборки в качестве прерывания с высоким приоритетом путем захвата и сохранения самой большой выборки:
void __interrupt(high_priority) ISRs(void)
{
if(PIR1bits.ADIF == 1)
{
ADC = (ADRESH << 8) | (ADRESL); // Get ADC value from registers
if(ADC > ADCpeak) // Check if volume result is greater than existing temp
{
ADCpeak = ADC; // If it is then make that new temp peak
}
else{} // If it isn't then do nothing
ADCON0bits.GODONE = 1; // Start ADC again
PIR1bits.ADIF = 0; // Clear interrupt flag
}
}
Затем, когда время таймера 0 истекает, остальные обрабатываются как прерывания с низким приоритетом. Он предназначен для работы со скоростью обновления экрана пользователя (~ 500 мс). Я планирую обрабатывать результаты с помощью формул, поэтому я рад, что это будет прерываться дополнительными выборками / другими высокоприоритетными прерываниями, пока математика будет работать в фоновом режиме:
void __interrupt(low_priority) adcISR(void)
{
if(INTCONbits.TMR0IF == 1)
{
float adcr = (float)((ADCpeak*100)/1024); // Convert ADC reading to percentage
volume = adcr; // New volume int ready for displaying
ADCpeak = 0; // Reset ADC peak
TMR0 = 61618; // Reload timer
INTCONbits.TMR0IF = 0; // Clear flag
}
}
Прямо сейчас я устанавливаю время сбора данных АЦП на 12Tad и тактовую частоту преобразования на Fosc/8, и все работает нормально. Тактовая частота тоже 8МГц. Однако, как упоминалось ранее, он по-прежнему иногда пропускает громкие удары, а удары примерно одинаковой громкости иногда отображаются как совершенно разные числа.
Я знаю, что могу сделать так, чтобы он собирал образцы точнее и быстрее, но я не знаю, как это сделать. Я думаю, в идеале, я просто ищу кого-то, кто скажет мне, что мой предусилитель недостаточно быстр, или я должен изменить время приобретения и т. д.
Был бы очень признателен за все входные данные/предложения.
Возможно, пиковый детектор поможет.
Выходной сигнал пикового детектора увеличивается при увеличении входного сигнала. Но когда вход снова падает, выход остается на месте. Когда вы сделали выборку, вы можете закрыть переключатель MOSFET, чтобы снова снизить выходной сигнал. Однако существует риск того, что между вашим образцом АЦП и замыканием переключателя MOSFET внезапно возникнет пик.
Вместо этого вы можете добавить резистор к конденсатору, чтобы выходной сигнал медленно возвращался к базовой линии.
Это означает, что вам не придется так часто сэмплировать входные данные, потому что теперь этот острый пик был расширен.
Вам нужна более быстрая выборка. Я бы сказал порядка 10 000 выборок в секунду, если вам нужен четко определенный взгляд.
Как ты это делаешь? Избавьтесь от плавающих точек. Только целые числа. Удачи.
Дэйв Твид
Спехро Пефхани