Простая обработка сигналов в C # - PullRequest
3 голосов
/ 29 августа 2009

Я выполняю выборку из реального датчика, и мне нужно отобразить его отфильтрованное значение. Сигнал дискретизируется с частотой 10 Гц, и в течение этого периода он может возрасти до 80% от максимального диапазона.

Ранее я использовал Root Mean Square в качестве фильтра и просто применял его к последним пяти зарегистрированным значениям. Для этого приложения это не было бы хорошо, потому что я не храню неизмененные значения. Другими словами, мне нужно учитывать время в моем фильтре ...

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

Обновление : После нескольких испытаний электронных таблиц я принял исполнительное решение записать все образцы в журнал и применить фильтр Баттерворта .

Ответы [ 4 ]

6 голосов
/ 29 августа 2009

Вам всегда нужно хранить некоторые значения (но не обязательно все входные значения). Токовый выход фильтра зависит от количество входных значений и, возможно, некоторые прошлые выходные значения.

Простейшим фильтром будет Баттерворт первого порядка низких частот фильтр. Это потребует от вас только сохранить один прошлый вывод значение. (Текущий) выход фильтра, y (n):

y (n) = x (n) - a1 * y (n-1)

где x (n) - текущий вход, а y (n-1) - предыдущий вывод фильтра. а1 зависит от частоты среза и частота дискретизации. Частота среза частоты должно быть меньше 5 Гц (половина частоты дискретизации), достаточно низкий, чтобы отфильтровать шум, но не такой низкий что выход будет задержан относительно входа. И из Конечно, не так низко, что реальный сигнал отфильтровывается!

В коде (в основном C #):

double a1 = 0.57; //0.57 is just an example value.
double lastY = 0.0;
while (true)
{
    double x = <get an input value>;

    double y = x - a1 * lastY;

    <Use y somehow>

    lastY = y;
}

Достаточно ли фильтра первого заказа, зависит от вашего Требования и характеристики входного сигнала (а фильтр более высокого порядка может подавлять больше шум за счет большей задержки выходного сигнала).

Для фильтров более высокого порядка необходимо хранить больше значений и код становится немного сложнее. Обычно значения должны быть сдвинуты вниз в массивах; в массиве для прошлых значений y и в массиве для прошлых значений x.

5 голосов
/ 29 августа 2009

В DSP термин «фильтр» обычно относится к усилению или ослаблению (то есть «понижению») частотных составляющих в непрерывном сигнале. Обычно это делается с помощью быстрого преобразования Фурье (БПФ). БПФ начинается с сигнала, записанного в течение определенного промежутка времени (данные находятся в так называемой «временной области»), и преобразует эти значения в так называемую «частотную область», где результаты указывают силу сигнала в серии. частотных «бинов» в диапазоне от 0 Гц до частоты дискретизации (10 Гц в вашем случае). Таким образом, в качестве грубого примера, БПФ, состоящее из ваших данных в одну секунду (10 выборок), сообщит вам силу вашего сигнала при 0-2 Гц, 2-4 Гц, 4-6 Гц, 6-8 Гц и 8-10 Гц.

Чтобы «отфильтровать» эти данные, вы должны увеличить или уменьшить любое или все из этих значений мощности сигнала, а затем выполнить обратное БПФ для преобразования этих значений обратно в сигнал во временной области. Например, предположим, что вы хотели создать фильтр низких частот для преобразованных данных, где частота среза составляла 6 Гц (другими словами, вы хотите удалить любые частотные составляющие в вашем сигнале выше 6 Гц). Вы должны программно установить значение 6-8 Гц на ноль и установить значение 8-10 Гц на 0, а затем сделать обратное БПФ.

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

Скользящее среднее очень легко программировать ( намного проще, чем FFT, поверьте мне), сохраняя коллекцию самых последних измерений. Вы упоминаете, что ваше приложение хранит только значения, которые отличаются от предыдущего значения. Предполагая, что вы также сохраняете время, в которое записывается каждое значение, ваш бегущий средний код должен легко заполнить «пропущенные значения», используя записанные предыдущие значения.

2 голосов
/ 29 августа 2009

У меня нет учебника, который поможет вам, но в C # вы можете рассмотреть возможность использования Reactive LINQ - см. Сообщение в блоге Реактивное программирование (II.) - Введение в Reactive LINQ .

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

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

0 голосов
/ 25 февраля 2011

Да, для сложных систем реального времени, осуществляющих выборку из нескольких потоков данных, могут возникнуть проблемы при обработке данных (расчет и хранение данных) и согласованности данных.

...