Рязанов Илья А., ryasanov@gmail.com
Когда-то давно основной задачей любого осциллографа было фиксация формы сигнала. И действительно, базовый функционал определил название, ведь дословно, осциллограф означает пишущий колебания (осцилло – качаюсь, граф – пишу ). Но современный осциллограф давно уже больше, чем "рисователь" сигнала, теперь это комплексный измерительный прибор, который помимо формы сигнала измеряет массу других связанных параметров: амплитудное, среднее, среднеквадратическое, средневыпрямленное напряжение, частота сигнала, всевозможные коэффициенты, плотность распредения и многое другое. Но особым пунктом всегда стоит спектр сигнала. Думаю, никому не нужно объяснять, какую роль играет спектральный анализ в современной метрологии. Потому при разработке анализатора сигналов LESO4 мы особое внимание уделили возможности исследовать спектр сигнала. Однако аппаратно в анализаторе сигналов LESO4, не реализована возможность расчета БПФ. Прибор по сути своей представляет собой умный многоканальный АЦП с аналоговой обвязкой. Используя API функции, можно сконфигурировать аналоговый измерительный тракт (открытый/закрытый вход, входной делитель/усилитель) и получить выборку сигнала при требуемой эквивалентной частоте дискретизации. Расчет спектра целиком и полностью ложится на программное обеспечение управляющей программы.
Получение спектра дискретного сигнала осуществляется дискретным преобразованием Фурье (ДПФ). Недостаток ДПФ состоит в очень низком быстродействии, поэтому на практике используют разновидность ДПФ - быстрое преобразование Фурье (БПФ), которое в зарубежной литературе называется - Fast Fourier Transform (FFT). В целом, алгоритм БПФ не является секретом и доступен в любом учебнике по цифровой обработки сигналов. При должном навыке программирования алгоритм можно написать самому, однако на изобретение велосипеда уйдет достаточно много времени, да и разобраться с алгоритмом придется на все 110%, потому как подводных камней предостаточно. В своей разработке мы пошли другим путем, решили использовать готовую библиотеку с уже написанным и полностью отлаженным алгоритмом. В этой статье попробую привести пример простенькой программы с использованием свободной библиотеки libFFTW (сайт проекта: http://www.fftw.org/), являющейся стандартом де-факто для многих программ в мире Open Source.
Особенности libFFTW:
- Распространяется по лицензии GPL (да, на свое ПО мы тоже даем лицензию GPL).
- Поддержка одномерного и многомерных БПФ преобразований.
- Кроссплатформенность (можно скомпилировать на любой платформе, где есть компилятор С).
- Поддержка многопоточности (POSIX thread и MPI).
- Написана на C, теоретически можно использовать с любым языком программирования. Из коробки есть поддержка Fortran (Месье знает толк в извращениях).
- Библиотека работает с комплексными и реальными числами.
Используя библиотеку, достаточно просто получить спектр сигнала, но визуализация спектра – самостоятельная и не простая задача, потому в нашем простом примере спектр используем для нахождения базовой основной частоты сигнала и в программе ограничимся текстовым режимом работы. Итак, задача: используя осциллограф LESO4 и библиотеку libFFTW, найти частоту сигнала.
Алгоритм будет простым. Сначала считаем с прибора выборку сигнала, пропустим через прямое БПФ. Затем в массиве полученных спектральных отсчетов находится элемент с наибольшим значением и запоминается его индекс. Полученный индекс умножим на шаг БПФ. Полученное значение и есть частота исследуемого сигнала. Это - основная частота, потому как в спектре может быть несколько гармоник. Нетрудно догадаться, что точность расчета частоты сигнала зависит от частоты дискретизации и количества выборки отсчетов. Для более сложных манипуляций со спектром не стоит забывать про окна сглаживания, которые придется реализовывать, но это совсем другая история.
Шаг БПФ определяется:
STEPFFT = fd / N,
где:
fd - частота дискретизации сигнала;
N - Количество отсчетов;
Эти величины устанавливаются в приборе посредством вызова api функций:
leso4SetSamplFreq(sampe_frequency_25MHz);
leso4SetSamplesNum(8192);
В приборе 8192 – максимальный размер выборки. Тогда шаг дискретизации будет равен почти 3 кГц:
STEPFFT = fd / N = 25000000 / 8192 = 3051,7578125 Гц
Описание используемых функций библиотеки libFFTW
Для начала БПФ в библиотеке FFTW нужно создать план преобразования. План преобразования представляет собой дескриптор типа fftw_plan
, в котором находятся параметры преобразования.
fftw_plan fftw_plan_dft_1d(int n, fftw_complex *in, fftw_complex *out, int sign, unsigned flags);
Создание плана одномерного БПФ преобразования. Функция принимает следующие параметры:
n
– сколько отсчетов будем преобразовывать, размер выборки;
in
– указатель на входной массив отсчетов;
out
– указатель на массив выходных отсчетов;
sign
– направления преобразования (FFTW_FORWARD
— прямое БПФ преобразование, FFTW_BACKWARD
– обратное БПФ преобразование, flags
– дополнительные флаги преобразования);
Итак, "все идет по плану". Запускаем преобразования в соответствии с планом plan
:
void fftw_execute(const fftw_plan plan);
Мы же хорошие программисты, прибираемся за собой: освобождаем память после преобразования. Функции передается дескриптор преобразования plan
:
void fftw_destroy_plan(fftw_plan plan);
Тип данных fftw_complex
, представляет собой массив из двух элементов
typedef double fftw_complex[2];
Первый элемент - реальная часть, второй - мнимая.
Ниже приведен листинг программы, рассчитывающий частоту сигнала:
Для компиляции программы должны быть установлены библиотеки libFFTW и libLESO4.
Компиляция в Linux или в Windows с помощью MinGW:
gcc -o leso leso4_fft.c -I{путь к заголовочным файлам} -L{путь к динамическим библиотекам} -lLESO4 -lfftw3-3
Как видно, если использовать готовые библиотеки, то ничего сложного в реализации ЦОС на ПК нет. Даже на языке программирования С. Этот прием расчета частоты я использовал в программе LESOscope для анализатора сигналов LESO4. Программная обработка отсчетов реального сигнала на компьютере очень удобна для разработки различных алгоритмов ЦОС в разных стендах и просто для изучения уже написанных алгоритмов.