Генерация кода для Arduino (Прямой цифровой синтез)¶
В этом примере представлена модель прямого цифрового синтеза (DDS) сигналов с последующим выполнением на Arduino.
Введение¶
Задача прямого цифрового синтеза заключается в формировании сигналов заданной формы на выходе генератора с регулируемыми параметрами. В этом примере будет реализовано переключение по внешнему дискретному сигналу между пятью формами выходного сигнала - пилообразный с положительным и отрицательным наклоном, треугольный, синусоидальный и меандр. По двум внешним аналоговым сигналам будет регулироваться частота и амплитуда выходного сигнала.
Аппаратная часть¶
В этом примере в качестве целевого устройства используется отладочная плата Arduino MEGA 2560. Выходной сигнал формируется на выходе № 9. Цифро-аналоговое преобразование сигнала выполняется при помощи ШИМ и RC-фильтра нижних частот. Частота ШИМ составляет $f_{PWM} = 62.5 кГц$, частота среза RC-фильтра $f_{c} = 14.185 кГц$, порядок фильтра - 2. Параметры RC-цепи: $R_ф = 330 Ом ,\ C_ф = 34 нФ$.
Сигнал переключения формы выходного сигнала поступает на цифровой вход № 2 от кнопочного контакта со схемой устранения дребезга на подтягивающем резисторе $R_п = 10 кОм$ и шунтирующем конденсаторе $C_ш = 75 нФ$.
Для регулирования частоты и амплитуды выходного сигнала на аналоговые входы A0 и A1 отладочной платы Arduino подключены потенциометры с сопротивлением $R_{reg} = 10 кОм$.
Схема соединения элементов представлена на рисунке ниже.
Выходной сигнал снимается осциллографом Hantec DSO на выходе фильтра нижних частот. Также для вывода сигнала на динамик после фильтра через токоограничивающий резистор $R_д = 10 кОм$ подключено гнездо аудиовыхода 3.5 мм.
Описание модели¶
Для взаимодействия с периферией контроллера в модели arduino_dds
используется четыре блока C Function
:
DigitalInput_Mode
- инициализирует цифровой вход № 2, опрашивает состояние входа. При моделировании в Engee формирует периодический пилообразный сигнал для организации отрицательного фронта на входе блока счётчикаModeCounter
и переключения формы выходного сигнала.AnalogInput_Freq
- опрашивает значение частоты на аналоговом входе A0. При моделировании в Engee задаёт условную частоту выходного сигнала $frequency = 0.5$.AnalogInput_Amp
- опрашивает значение амплитуды на аналоговом входе A1. При моделировании в Engee задаёт условную амплитуду выходного сигнала $amplitude = 1.0$.HFPWM_Output
- инициализирует работу ШИМ на выходе № 9 с максимально доступной частотой (62.5 кГц) и передаёт в модуль ШИМ контроллера новое значение скважности.
Подробности о работе блоков периферии даны в комментариях к коду в этих блоках.
Алгоритмы расчёта пяти заданных форм сигнала определены в подсистемах: PositiveSaw
- пилообразный с положительным наклоном, NegativeSaw
- пилообразный с отрицательным наклоном, Triangle
- треугольный, Sinusoidal
- синусоидальный и Square
- меандр со скважностью 50 %. Для переключения между алгоритмами формы выходного сигнала используется блок Multiport Switch
, управление на который поступает из подсистемы ModeCounter
. В подсистеме ModeCounter
выделяется отрицательный фронт входного сигнала и подсчитывается число нажатий на кнопочный контакт.
Таким образом, при моделировании в Engee выходной сигнал с неизменяемыми установками частоты и амплитуды будет периодически переключаться между заданными формами сигнала.
Результаты моделирования¶
Загрузим и выполним созданную модель:
if "arduino_dds" in [m.name for m in engee.get_all_models()]
m = engee.open( "arduino_dds" );
else
m = engee.load( "$(@__DIR__)/arduino_dds.engee" );
end
data = engee.run(m);
Из полученных данных модели построим график генерируемого сигнала:
using Plots
plotlyjs()
plot(data["pwmduty"].time, data["pwmduty"].value,
legend=false, size=(900,300), lw=2, st=:step)
xlabel!("Время, сек")
ylabel!("Значение")
Как это можно заметить, приблизительно каждые 0.2 секунды выходной сигнал изменяет свою форму.
Генерация кода для Arduino¶
Для загрузки на Arduino необходимо сгенерировать код из разработанной модели:
engee.generate_code( "$(@__DIR__)/arduino_dds.engee",
"$(@__DIR__)/arduino_dds_code")
Сгенерированные в указанной директории файлы подключим в пользовательском скетче arduino_dds.ino
. Скачаем эти файлы и загрузим в Arduino MEGA при помощи Arduino IDE.
В приложенном скетче происходит определение макросов и глобальных переменных, подлкючение пользовательских сгенерированных файлов и сторонних библиотек, вызов функций инициализации и циклического расчёта модели. В скетче также приведены комментарии для пояснения работы кода.
Работа программы на Arduino¶
После успешной компиляции и загрузки скетча в целевое устройство на выходе RC-фильтра подключим цифровой осциллограф Hantec DSO и снимем форму генерируемого сигнала. В опыте измерений показано переключение между генерируемыми формами, затем - генерация пилообразного сигнала с регулируемой частотой, после - с регулируемой амплитудой.
Для большей репрезентативности работы модели DDS на выход RC-цепочки был подключен динамик, а полученный звук записан в файле arduino_dds_audio.wav
. Следующая ячейка кода позволяет загрузить в скрипт полученный аудио-файл и воспроизвести его. Проиграйте аудиодорожку, чтобы убедиться в работоспособности разработанной модели. В нём записан звук при последовательном переключении формы выходного сигнала, а затем регулировании частоты и амплитуды пилообразного сигнала с положительным наклоном.
using WAV, Base64
x, fs = wavread( "$(@__DIR__)/arduino_dds_audio.wav" );
buf = IOBuffer();
wavwrite(x, buf; Fs=fs);
data = base64encode(unsafe_string(pointer(buf.data), buf.size));
markup = """<audio controls="controls" {autoplay}>
<source src="data:audio/wav;base64,$data" type="audio/wav" />
Your browser does not support the audio element.
</audio>"""
display( "text/html", markup );