Приветствую всех любителей электроники!
Данная статья ориентирована на людей со средним ("молодым"????) уровнем знаний в электронике и выше.
Используемые сокращения в статье
АЧХ — Амплитудно-частотная характеристика
МК — Микроконтроллер
БПФ — Быстрое преобразование Фурье
ДПФ — Дискретное преобразование Фурье
Бывают ситуации, когда нам известен спектр сигнала, но форму сигнала мы не можем представить в виду сложности основого сигнала. Ещё чаще возникает вопрос об построении АЧХ, но вот прибора под рукой нет, особенно если работаешь в гаражном кооперативе дома.
В данной статье я хочу поделиться скромным девайсом, моделирующее аналоговый сигнал сложной формы математическим методом и способное построить АЧХ по данному сигналу.
"Математическим методом!?"
Да, на устройство ничего не будет подаваться из-вне. Всё моделирует, строит и вычисляет непосредственно микроконтроллер. Я специально выделил это место, чтобы не обнадёживать людей, которые хотят увидеть полностью законченный и работающий измерительный прибор.
/*кхе-кхе*/
Да, цифры перед фамилией для университета, я студент, параллельно работающий техником (программирование STM32)
Краткие сведения
Для разработки устройства нам потребуется:
Любая отладочная плата с МК семейства STM32F1xx. В моём случае это STM32F103ZET6
Любой доступный программатор для STM32, у меня это самодельный st-link V2.1. Если будут желающие, выкачу отдельную статью про него и исходными файлами, вещь!
Китайский модуль TFT-экрана;
3 потенциометра на 10кОм стандартные китайские;
соединительные провода, обычные провода (придётся паять), корпус пластиковый, крепёжные винты м3 для экрана.
Уравнение аналогового сигнала будет состоять из трёх гармоник. Для регулирования частоты каждой гармоники используем потенциометры.
Разработка кода будет на HAL+CMSIS через STM32CubeMX в Keil uVision5.
Создание проекта в STM32CubeMX
Выбираем контроллер STM32F103ZET6. Выбираем программирование МК по последовательной шине (SWD – Serial Wire Debug). Подключаем внешний кварц на 8МГц. Подключаем SPI (serial peripheral interface), характеристики SPI:
Подробнее об этом этапе
Тут можно выбрать любой МК семейства F1 как было сказано ранее, у них всё одно и тоже, в том числе и распиновка SPI и АЦП. Способ программирования у меня стоит по SWD. Выбирайте как вам удобно, с этим понятно.
Также включаем АЦП. Задействуем 3 канала АЦП, под одну составляющую гармонического сигнала отводим 1 канал АЦП. Забирать данные с АЦП будем при помощи DMA в режиме прерывания. АЦП и DMA выставим в одиночном режиме, будем вручную выключать АЦП и включать, когда это будет нужно. Не забудьте включить прерывание по DMA!
Кроме этого, активируем ещё 3 вывода МК, настроем их как выходы и присвоим названия. Данные выводы будут использованы для управления дисплеем. Выбор драйвера (chip select), сброс (reset), и разрешения записи данных (data chip).
Помимо этого нужно конечно же подать питание, и включить подсветку. Подсветку можно сделать постоянную, а можно организовать регулируемую, через транзистор с помощью таймера в режиме ШИМ. Питание и подсветку я подавал от самой платы...
Теперь перейдём в дерево тактирования (clock tree) и разгоним МК до максимально допустимой частоты в 72МГц.
Стоит заметить, что в таком положении частоту АЦП можно выставить только на 12МГц, при 14МГц возможных. Чтобы выставить максимум, необходимо понизить частоту системной шины. Однако в данном проекте АЦП не выполняет сверхважную задачу, поэтому оставляем 12МГц.
Разработка программы для микроконтроллера
Прежде всего необходима библиотека для дисплея на базе ILI9341. В интернете есть множество вариантов готовых библиотек для данного дисплея, однако в большинстве своём они ограничены, тяжелы в понимании за счёт отсутствия эстетики написания кода, могут вообще не работать или написаны под какое-то конкретное семейство STM32. Поэтому было принято решение написать универсальную для любого семейства STM32 библиотеку уже с полным набором удобных функций на базе библиотек из интернета, однако данная библиотека подходит для любого драйвера, так как она написана на CMSIS. Таким образом её можно подключать в любой проект. Саму инициализацию SPI будет делать CubeMX (так быстрее, при желании скину код инициализации SPI на CMSIS с возможностью разгона частоты до 44МГц). Инициализацию библиотека делает сама. Она имеет понятные названия функций, их легко использовать.
Основные функции:
1) void taskSolution (uint16_t k);
Данная функция решает основное уравнение, описывающее гармонический сигнал, подготавливая значение выборки для удобного вывода на дисплей. Для данного проекта выбрано следующее уравнение:
где in – это частота гармоники, величина которой зависит от изменения на входе канала АЦП;
k – номер выборки;
N – количество выборок (N = 256);
void taskSolution(uint16_t k){
firstHarm = 1.0 * cos(((2*PI)/X_LINE_LENGTH)*firstHarmFreq*k + PI/2); //значение 1-ой гармоники
secHarm = 1.0 * cos(((2*PI)/X_LINE_LENGTH)*secHarmFreq*k + PI/2); // 2-ой
thirdHarm = 1.0 * cos(((2*PI)/X_LINE_LENGTH)*thirdHarmFreq*k - PI); // 3-ей
Fk = firstHarm + secHarm + thirdHarm; // Сложеник гармоник и получие выборки
//Главное уравнение:
//Fk = (1.0 * cos((2*PI/N)*0*k + PI/2) + 1.0 * cos((2*PI/N)*2*k + PI/2) + 1.0 * cos((2*PI/N)*3*k - PI));
Fk = ((Fk*MULT_SIGNAL_VAL)+START_POINT_Y); // конверсия значения для отображения на экран
}
Само собой функция стоит в цикле до некого опеределённого значения, в данном случае 256 выборок (X_LINE_LENGTH
). По мимо этого в конце функции я зачем-то делаю конверсию. Тут всё просто. Я использую функцию косинуса и значит у меня значение колеблется от 0 до 1, это понятно. Значит мне его нужно просто умножить на некую константу, чтобы удобно было вывести уже большое значение (номер пикселя) на экран + это помогает сразу получить из "плавующей" переменной довольно точную целую.
2) uint32_t MAP (uint32_t au32_IN, uint32_t au32_INmin, uint32_t au32_INmax, uint32_t au32_OUTmin, uint32_t au32_OUTmax);
Данная функция конвертирует диапазон изменения значения АЦП (0-4095) в диапазон частот сигнала (0-15);
3) void displaySignal (uint16_t k);
Данная функция выводит Полученное значение выборки на дисплей;
4) void clearNextPosition (uint16_t k, uint16_t COLOR).
Перед выводом на дисплей используем функцию очистки следующего значения выборки. Так как экран обновляется в данном случае слева направо, и чтобы не очищать сразу весь участок сигнала (устранение мерцания), а добиться плавности отображения изображения очищаем только следующий столбец пикселей экрана;
5) void visualSignalIncrement (uint16_t k, uint16_t COLOR);
Чтобы визуально сигнал был хорошо различим, зажжём сверху и снизу основного значения функции ещё один пиксель, таким образом сигнал будет жирнее;
6) Функции:
void visualFFT_Increment (uint16_t k, uint16_t harmonic, uint16_t COLOR);
void displayFFT (uint16_t k); void clearLastFFT_VAL (uint16_t k);
void displayFFT_VAL (uint16_t k);
аналогичны функциям вывода сигнала на экран. Принцип работы такой же, отличие заключается только в определении амплитуды и частоты каждой гармоники, и расчёт спектра сигнала;
Нюанс построения АЧХ в проекте
Я не использовал сложные формулы для вычисления спекртра в данном проекте. Т.к. мне известна формула гармонического сигнала, его параметры, я просто брал значение его аплитуды и частоты и рисовал соответсвующую гармонику на АЧХ. В дальнейшем конечно, устройство можно доработать, тем более, что это может лишь показаться сложным на первый взгляд. Если хочется понять принцип работы алгоритма БПФ и ДПФ, на harb есть понятная и позновательная статья на данную тему, там использован другой язык и нет микроконтроллера, но это не важно, поскольку очень понятно описывается сам алгоритм, чтобы вы могли применить его у себя в проекте.
7) Для отслеживания параметров сигнала и спектральных характеристик необходимо нарисовать координатные оси с соответствующими значениями. Данную операцию выполняют функции drawGridSignal(BLACK); drawGridFFT(BLACK);
Из названия функции можно увидеть, что первая функция отвечает за отрисовку координатной оси для гармонического сигнала, а вторая для АЧХ. Количество выборок: 256 (X_LINE_LENGTH). Максимальная частота гармоники: 15 Гц (LIMIT_FREQ);
Процесс сборки устройства
Устройство мне необходимо было сделать довольно быстро для своих нужд, но так, чтобы ничего не развалилось и нормально работало. Поэтому плату я не делал, это было бы долго и дорого, даже если не учитывать около недели на разработку платы, китайцы бы везли платы больше месяца + они стоили бы около 25-35$. А так плат с STM у меня в избытке, как и программаторов с иными коплектующими, поэтому, условно, собрал из того, что было, не задумываясь над ценой конструкции. Разве что покупал пластиковый корпус, так как у меня пока нет своего 3D-принтера, увы... Вырезать пластиковый корпус конечно то ещё удовольствие и не очень красиво выходит по итогу, но тут уж как говорится:
"Лучше сделать и пожалеть, чем не сделать и потом жалеть" ????
Все исходники я выложил на GitHub. Там вы можете скачать проект в CubeMX и сам проект в Keil uVision5. Проект должен завестись сразу же, файл библиотеки уже подключён в проект, ничего стороннего скачивать не нужно.
По вопросам моего самодельного программатора и прочим пишите в комментариях. Кроме этого недавно приехали сделанные мной платы на недавно появившуюся STM32G4 (48 пин делал). Очень удобная, с дополнительным функциональным, по сравнению с китайскими платами, да и китайцы сами ещё не успели выкатить дешёвую и удобную версию для данного семейства, если есть желание узнать про это побольше, пишите, с огромной радостью выкачу обзор.
Спасибо за внимание!
Комментарии (18)
Alyoshka1976
12.06.2023 15:26Ограничение (очень строгое) видов сигнала учётом только амплитудного спектра? Учет фазового спектра прибавил бы универсальности.
Anzorik_228 Автор
12.06.2023 15:26Ну... Да, так и есть, можно вместить в экран ещё и ФЧХ, только я делал уже конкретно под себя и ФЧХ мне не было надобности добавлять. А так, если в общем, можно, не составит больших усилий
strvv
12.06.2023 15:26+1/s да и я как прочитал — и амплитудный спектр только одного уровня = 1.0… т.е. даже прямоугольный меандр не смоделируешь. /s
но решение прекрасное!
sainquake
12.06.2023 15:26Круто, но почему все ещё кейл? Зачем вы себе палки в колеса ставите?
Anzorik_228 Автор
12.06.2023 15:26По разным причинам, программировать он мне не мешает, тем более важные и коммерческие проекты я пишу на CMSIS, а там помощи не много надо от ПО. Пока для меня есть всё необходимое, за исключением пары неудобств. Друг также говорил, он перешёл на VS Code, но я всё же пока keil пользуюсь + на работу когда пришёл там также коллега keil использует
REPISOT
12.06.2023 15:26У вас АЦП считывает напряжение на потенциометрах. Зачем ему даже 12 МГц тактовой (не говоря уж о 14)! Ставьте минимальную частоту. И шумы меньше будут.
(платы) стоили бы около 25-35$
Это что имелось в виду? Плата + все компоненты?
Потому что известная китайская компания делает 10 плат 100х100 за 5$. Первый заказ бесплатно. Платите только за доставку.
Ее конкурент сейчас вообще по акции делает за 2$.
Сроки доставки — да, есть такое.Anzorik_228 Автор
12.06.2023 15:26В процессе работы смотрел отклик, был случай "шального" перестраивания, но его потом устранил без необходимости понижать частоту. Можно было работать и с внутренним тактированием, но тут уже просто "почему бы не разогнать на максимум камешек")
Anzorik_228 Автор
12.06.2023 15:26Ну, на том же pcbway вы заплатите за небольшую платку 5 баксов и 10 за доставку. На первый заказ хоть и скидка, но я его не беру в расчёт, т.к. это только для первого. Ну и к общей цене я сложил и компоненты разуемеется.
eugene_e
12.06.2023 15:26+2Так а в чём смысл делать генератор сигнала, который виден только на экране? Я читал статью и был уверен, что сигнал выводится наружу с помощью ЦАП. А когда оказалось, что нет, то, мягко говоря, удивился. Сам график можно построить с помощью любого математического или сигнального пакета, для этого не нужно отдельное устройство. Устройство имеет смысл если оно умеет делать то, что невозможно сделать на обычном компе без внешних устройств.
Было бы идеально добавить в проект вывод сигнала на пин, и показать
с помощью осциллографа что генерится то же самое что и на дисплее.Anzorik_228 Автор
12.06.2023 15:26-1Такая задача стояла, поэтому в начале статьи ваш вопрос затронут, чтобы не заставлять читать всю статью тех, кто ожидал увидеть готовый измерительный прибор
eugene_e
12.06.2023 15:26В начале статьи сказано что на вход прибора ничего не подаётся. Про выход не сказано ничего. Вход и выход - это разные вещи.
Anzorik_228 Автор
12.06.2023 15:26Нет, здесь только математические вычисления. В заголовке статьи указано моделирование сигнала и АЧХ математическим методом
Prohard
12.06.2023 15:26+1Что может быть проще? LTSpice и все дела. И зачем громоздить спектр, если из уравнения и так все ясно? И АЧХ тут вообще ни причем.
ivanstor
АЧХ сигнала не бывает. У сигнала бывает спектр. АЧХ бывает у устройства, физического и абстрактно-математического (трехполюсника). Что и видно из расшифровки этой аббревиатуры, как русской, так и английской. А так — хорошая статья, на уровне лабораторки, может быть курсовой.
Может быть устройство, которое бы вычисляло АЧХ реальных трехполюсников (RC, LC, LRC цепочек) по принципу импульсное воздействие → анализ отклика, было бы познавательнее. Тем более у микроконтроллера всё нужное есть на борту. Но это так...
С грамотностью у автора проблемы, но это сейчас скорее правило, чем исключение.
Anzorik_228 Автор
/
j_aleks
Ваауу, ЛИТЕРАТУРНЫЕ критики подтянулись...
le2
обожаю такие унижения. Типа - ну ты конечно что-то написал, но я этого достиг еще на лабораторке или курсовой. Клинический случай - хвастать достижениями из обучения в ВУЗе.
Но вот конкретный пример - задача квантования сигнала. Квантовать можно сигнал только ограниченный по спектру. Мы цифровым способом ограничиваем входной сигнал. Мы ограничили что? Спектр? Ну да, но практически это АЧХ, который измерить нельзя, потому что это процесс в софте.
Refridgerator
Ну если привязываться конкретно к реальным трехполюсникам, то нужно заодно и мат.модель для идеального трехполюсника делать, чтобы сравнить теорию с практикой.