PIC MCU: надежный захват и измерение переходных процессов ударных с помощью АЦП

Я ищу совета, чтобы помочь моей схеме/коду/микроконтроллеру работать более надежно и точно. То, что у меня есть сейчас, почти готово, но мне просто не хватает ноу-хау, чтобы получать стабильные показания. Я попытался нарисовать хорошую картину того, что я делаю, и почему так терпите меня, чтобы объяснить.

Цель моего дизайна очень проста — просто передать громкость барабана . Я делаю это через электретный микрофон, в предусилитель, в АЦП на плате 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МГц. Однако, как упоминалось ранее, он по-прежнему иногда пропускает громкие удары, а удары примерно одинаковой громкости иногда отображаются как совершенно разные числа.

Я знаю, что могу сделать так, чтобы он собирал образцы точнее и быстрее, но я не знаю, как это сделать. Я думаю, в идеале, я просто ищу кого-то, кто скажет мне, что мой предусилитель недостаточно быстр, или я должен изменить время приобретения и т. д.

Был бы очень признателен за все входные данные/предложения.

Как вы обнаружили, пиковое положительное значение АЦП плохо коррелирует с измерением, которое вас действительно интересует, а именно с энергией удара по барабану. По крайней мере, вы должны измерять размах, и, что еще лучше, вы должны измерять среднеквадратичную мощность всех выборок за короткий интервал, например, несколько мс за раз.
Может быть, схема измерителя громкости и вообще не пытайтесь сэмплировать звук.

Ответы (2)

Возможно, пиковый детектор поможет.

Пиковый детектор

Выходной сигнал пикового детектора увеличивается при увеличении входного сигнала. Но когда вход снова падает, выход остается на месте. Когда вы сделали выборку, вы можете закрыть переключатель MOSFET, чтобы снова снизить выходной сигнал. Однако существует риск того, что между вашим образцом АЦП и замыканием переключателя MOSFET внезапно возникнет пик.

Вместо этого вы можете добавить резистор к конденсатору, чтобы выходной сигнал медленно возвращался к базовой линии.

Обнаружение пиков

Это означает, что вам не придется так часто сэмплировать входные данные, потому что теперь этот острый пик был расширен.

Отличная идея, спасибо! Это то, что мне нужно. Если я найду значение резистора, которое просто замедляет выходной уровень настолько, чтобы его можно было прочитать, могу ли я удалить MOSFET?
Да, безусловно. Так гораздо понятнее.
Проведя некоторое исследование, я прочитал, что пиковые детекторы и повторители огибающей очень похожи, и конструкция предусилителя, которую я использую (см. ссылку выше), имеет секцию повторителя огибающей. Могу ли я теоретически заменить конденсатор 10 мкФ на больший и превратить его в пиковый детектор?
@ezra_vdj - Да, абсолютно. Я даже не думаю, что вам нужно будет заменить конденсатор.

Вам нужна более быстрая выборка. Я бы сказал порядка 10 000 выборок в секунду, если вам нужен четко определенный взгляд.

Как ты это делаешь? Избавьтесь от плавающих точек. Только целые числа. Удачи.

Он не работает в цикле. Отбор проб осуществляется по таймеру.
АЦП даже не работает по таймеру, он просто запускается снова сразу после завершения с помощью прерывания.