Генерация кода для Arduino (линейная частотная модуляция с фильтром нижних частот)¶
В этом демонстрационном примере производятся расчёт, моделирование и выполнение на целевом устройстве цифрового фильтра нижних частот при линейной частотной модуляции.
Введение¶
Цель этого примера - разработать фильтр нижних частот по заданным параметрам. Для его расчёта воспользуемся библиотекой DSP языка Julia. Работу фильтра проверим в модели Engee на сигнале, полученном линейной частотной модуляцией. После генерации кода из модели Engee воспроизведем фильтрацию сигнала на отладочной плате Arduino.
Аппаратная часть¶
В этом примере используется отладочная плата Arduino MEGA 2560. Выходной сигнал формируется на выходе № 9. Цифро-аналоговое преобразование сигнала выполняется при помощи ШИМ и RC-фильтра нижних частот. Частота ШИМ составляет 62.5 кГц, частота среза RC-фильтра - 14.185 кГц, порядок фильтра - 2. Схема соединения представлена на рисунке ниже.
Параметры RC-цепи: $R = 330 Ом ,\ C = 34 нФ$. На выходе цепочки через токоограничивающий резистор $R_д = 10 кОм$ подключено гнездо аудиовыхода 3.5 мм для вывода сигнала на динамик.
Описание модели¶
Функциональная часть модели, рассматриваемой в этом примере - это подсистема FM
, формирующая переменную скважности Duty
. Эта переменная в пользовательском скетче будет передана в модуль ШИМ контроллера для формирования выходного аналогового сигнала.
Содержимое подсистемы FM
описывает линейную частотную модуляцию по формуле $y = sin(2\cdot\pi \cdot f \cdot t)$. Частота сигнала изменяется линейно: $f = 50\cdot t$ После прохождения через фильтр нижних частот в блоке LPF
отфильтрованный сигнал $y_ф$ получает смещение и масштабируется. Это необходимо для корректного и максимально точного формирования скважности ШИМ. Разрешение ШИМ в этом примере составляет всего 5 бит, однако это позволяет достичь высокой частоты ШИМ.
Скважность ШИМ определяется формулой $Duty = 16\cdot (y_ф+1)$.
Следует заметить, что в целях дополнительной экономии вычислительных мощностей целевого устройства изменение частоты сигнала связано напрямую с временем симуляции. Таким образом, частота модулируемого сигнала в определенный момент превысит и частоту Найквиста, и частоту дискретизации. Следовательно, для корректного представления результатов работы фильтра необходимо выбрать такую частоту среза, которая будет ниже частоты Найквиста.
Расчёт фильтра нижних частот¶
Для фильтрации нижних частот выберем эллиптический фильтр с параметрами:
- частота дискретизации - 2000 Гц (отсюда, частота Найквиста - 1000 Гц),
- частота среза - 400 Гц,
- число полюсов - 6,
- неравномерность характеристики в полосе пропускания - 1 дБ,
- затухания в полосе задержки - 60 дБ.
Pkg.add(["WAV", "DSP"])
fs = 2000
fp = 400;
n = 6;
Rp = 1;
Rs = 60;
Рассчитаем коэффициенты полиномов числителя и знаменателя передаточной функции фильтра:
using DSP;
myfilt = digitalfilter(Lowpass(fp; fs), Elliptic(n, Rp, Rs));
b = coefb(myfilt);
a = coefa(myfilt);
Скопируем полученные коэффициенты в числитель и знаменатель блока LPF
модели.
Результаты моделирования¶
Загрузим и выполним созданную модель:
if "chirp_lpf" in [m.name for m in engee.get_all_models()]
m = engee.open( "chirp_lpf" );
else
m = engee.load( "$(@__DIR__)/chirp_lpf.engee" );
end
data = engee.run(m);
Из полученных данных модели построим графики выходных переменных - сигнала на входе и выходе ФНЧ: LPF_in
и LPF_out
соответственно.
using Plots
plotlyjs()
plot(data["LPF_in"].time, data["LPF_in"].value,
label="До ФНЧ", size=(900,300), lw=2, st=:step)
plot!(data["LPF_out"].time, data["LPF_out"].value,
label="После ФНЧ", size=(900,300), lw=2, st=:step)
xlabel!("Время, сек")
ylabel!("Значение")
Как видно из графика, фильтр выполняет преобразование сигнала по заданным параметрам.
Загрузка кода в Arduino¶
Для загрузки на Arduino необходимо сгенерировать код из подсистемы FM
:
engee.generate_code( "$(@__DIR__)/chirp_lpf.engee",
"$(@__DIR__)/chirp_lpf_code";
subsystem_name="FM")
Сгенерированные в указанной директории файлы подключим в пользовательском скетче chirp_lpf.ino
. Скачаем эти файлы и загрузим в Arduino MEGA при помощи Arduino IDE.
Выполнение кода на Arduino¶
После успешной компиляции и загрузки скетча в целевое устройство на выходе RC-фильтра подключим цифровой осциллограф и снимем переменную составляющую генерируемого сигнала.
Для демонстрации был использован цифровой осциллограф Hantec DSO c подключением к компьютеру и выводом данных в программу DSO Analyzer.