Генератор сигналов прямоугольной и синусоидальной формы на Arduino


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

Внешний вид генератора сигналов прямоугольной и синусоидальной формы на Arduino

В этой статье мы рассмотрим как на основе платы Arduino достаточно просто сконструировать генератор сигналов прямоугольной и синусоидальной формы. При формировании сигналов прямоугольной формы данный генератор может формировать прямоугольную волну с перепадами уровней 5V/0V с частотой от 1 Гц до 2 МГц. Частотой формируемого сигнала можно будет управлять с помощью инкрементального энкодера. Коэффициент заполнения (цикл занятости) данного сигнала будет равен 50%, но его можно изменить, внеся соответствующие изменения в программу. Рассматриваемый нами генератор не является промышленным устройством и его не рекомендуется использовать на серьезном производстве, но для домашних условий использования он вполне подойдет.

Также на нашем сайте вы можете посмотреть проекты более "продвинутых" генераторов для формирования сигналов прямоугольной и синусоидальной формы:

Если же вам нужно исключительно простое решение для формирования сигналов прямоугольной формы с частотой до 1 МГц с помощью платы Arduino, то рекомендуем этот проект.

Необходимые компоненты

  1. Плата Arduino Nano (купить на AliExpress).
  2. Алфавитно-цифровой ЖК дисплей 16х2 (купить на AliExpress).
  3. Инкрементальный энкодер, угловой кодер (Rotary Encoder) (купить на AliExpress).
  4. Резисторы 5,6 кОм и 10 кОм (купить на AliExpress).
  5. Конденсатор 0,1 мкФ (купить на AliExpress).
  6. Перфорированная плата.
  7. Набор для пайки.

Работа схемы

Схема генератора сигналов на основе платы Arduino представлена на следующем рисунке.

Схема генератора сигналов прямоугольной и синусоидальной формы на основе платы ArduinoПлата Arduino Nano управляет всеми процессами в схеме. ЖК дисплей используется для отображения частоты формируемого сигнала, а с помощью углового кодера производится установка частоты сигнала. Также на нашем сайте вы можете прочитать статью о подключении инкрементального энкодера к плате Arduino.

Схема запитывается от USB кабеля Arduino. Необходимые соединения в схеме представлены в следующей таблице.

Контакт платы Arduino Куда подключен
D14 контакт RS ЖК дисплея
D15 контакт RN ЖК дисплея
D4 контакт D4 ЖК дисплея
D3 контакт D5 ЖК дисплея
D6 контакт D6 ЖК дисплея
D7 контакт D7 ЖК дисплея
D10 to Rotary Encoder 2
D11 to Rotary Encoder 3
D12 to Rotary Encoder 4
D9 выход прямоугольного сигнала
D2 контакт D9 платы Arduino
D5 выход SPWM сигнала

В схеме мы будем формировать прямоугольную волну (сигнал прямоугольной формы) на контакте D9 платы Arduino. Его частоту мы будем регулировать с помощью углового кодера. Для формирования синусоидального сигнала мы будем формировать SPWM сигнал (синусоидальный ШИМ (широтно-импульсной модуляции) сигнал) на контакте D5, его частота будет зависеть от частоты сигнала прямоугольной формы, которая будет подаваться на контакт D2 и будет действовать как прерывание и затем мы с помощью процедуры обработки (обслуживания) прерывания будем управлять частотой синусоидального сигнала.

Вы можете собрать схему проекта на макетной или даже на печатной плате, но мы решили спаять ее на перфорированной плате, в результате у нас получилась конструкция, показанная на следующих рисунках:

Вид собранного генератора сигналов на основе платы Arduino на перфорированной плате

Формирование прямоугольного сигнала с изменяемой частотой

Если вы знакомы с Arduino, то вы должны знать что плата Arduino может достаточно просто формировать ШИМ сигнал (с помощью функции analogwrite) на ряде своих контактов. Но с помощью этой функции можно управлять только коэффициентом заполнения (скважностью) ШИМ сигнала, но нельзя управлять его частотой – а это как раз и нужно для нашего генератора сигналов. Управление частотой сигнала прямоугольной формы можно осуществить используя таймеры платы Arduino и непосредственно переключая состояние контактов на их основе. Помочь нам в этом может библиотека Arduino PWM Frequency Library (библиотека управления частотой ШИМ сигнала), более подробно работу с ней мы рассмотрим далее в статье.

Вид сформированного нашим генератором прямоугольного сигнала

Но в использовании этой библиотеки есть ряд слабых сторон. Дело в том, что данная библиотека изменяет настройки по умолчанию Таймера 1 (Timer 1) и Таймера 2 (Timer 2) платы Arduino. В связи с этим вы уже не сможете, к примеру, использовать библиотеку для управления серводвигателем или другие библиотеки, задействующие эти таймеры платы Arduino. Также функция analogwrite на контактах 9,10,11 & 13 использует Timer 1 и Timer 2, следовательно, вы уже не сможете формировать SPWM сигнал (синусоидальный ШИМ сигнал) на этих контактах.

Но преимуществом этой библиотеки является то, что она не мешает работа Таймера 0 (Timer 0) платы Arduino, который в нашем случае является более важным чем Timer 1 и Timer 2 потому что в этом случае вы можете без проблем использовать функцию задержки (delay) и функцию millis(). Также контакты 5 и 6 управляются Таймером 0, поэтому мы без проблем сможем использовать на этих контактах функцию analogwrite или осуществлять управление сервомотором.

Формирование синусоидальной волны (колебания) с помощью Arduino

Мы знаем, что микроконтроллеры являются цифровыми устройствами, поэтому они не могут формировать синусоидальную волну в "чистом" виде. Но есть два способа формирования синусоидальной волны с помощью микроконтроллера: первый заключается в использовании ЦАП (цифро-аналогового преобразователя), а второй - в использовании синусоидального ШИМ сигнала (SPWM). К сожалению, в платах Arduino (за исключением платы Arduino Due) нет встроенного ЦАПа для формирования синусоидальной волны. Конечно, можно было бы использовать внешний ЦАП, но мы решили не усложнять таким образом схему проекта и использовать метод формирования синусоидального ШИМ сигнала с дальнейшим преобразованием его в синусоидальный сигнал (волну).

Что такое SPWM сигнал

SPWM расшифровывается как Sinusoidal Pulse Width Modulation и переводится как синусоидальная широтно-импульсная модуляция (синусоидальная ШИМ). Этот сигнал в определенной степени похож на обычный ШИМ сигнал, но в нем коэффициент заполнения контролируется таким образом чтобы получить среднее напряжение похожее на синусоидальную волну. Например, при коэффициенте заполнения (скважности) 100% среднее выходное напряжение будет 5V, а при коэффициенте заполнения 25% оно будет всего лишь 1.25V, таким образом, управляя скважностью (коэффициентом заполнения) мы можем получить заранее определенные изменяемые значения среднего напряжения, то есть синусоидальную волну. Этот метод обычно используется в инверторах.

Принцип формирования SPWM сигнала показан на следующем рисунке.

Принцип формирования SPWM сигнала

Синим цветом на этом рисунке показан SPWM сигнал. Заметьте, что его скважность (коэффициент заполнения) изменяется от 0% до 100%, а затем снова возвращается в 0%. Представленный график построен для диапазона изменения напряжений от -1.0 до +1.0V, но в нашем случае, поскольку мы используем плату Arduino, масштаб подобного графика будет от 0V до 5V. Мы рассмотрим как в программе для Arduino формировать SPWM сигнал далее в статье.

Преобразование SPWM сигнала в синусоидальную волну

Преобразование SPWM сигнала в синусоидальную волну обычно требует использования схемы H-моста (H-bridge), которая состоит минимум из 4-х переключателей мощности (power switches). Подобные схемы обычно используются в инверторах. Мы не будем в статье подробно рассматривать эти вопросы поскольку нам с помощью нашей синусоидальной волны не нужно запитывать какое-либо устройство, нам всего лишь нужно ее сформировать. К тому же с помощью H-моста невозможно получить чистую синусоидальную волну – для этой цели необходимо использовать фильтр нижних частот (ФНЧ), состоящий из конденсаторов и индуктивностей.

Вид сформированной в нашем генераторе синусоидальной волны

Но мы в целях упрощения проекта для этой цели применили простой RC-фильтр. Если же вы хотите повысить качество формирования синусоидальной волны, то вы можете вместо RC-фильтра применить LC-фильтр. Значение сопротивления резистора в нашем RC-фильтре составляет 620 Ом, а значение емкости конденсатора составляет 10 мкФ (номиналы отличаются от тех, которые приведены в начале статьи в разделе "необходимые компоненты", но я надеюсь в комментариях к данной статье более опытные в этих вопросах специалисты подскажут где же здесь правда – статья переведена с другого сайта и там присутствует эта опечатка, к сожалению). На представленном рисунке желтым цветом показан SPWM сигнал с контакта 5 платы Arduino, а синим цветом - синусоидальный сигнал, полученный после прохождения SPWM сигнала через наш RC-фильтр.

Библиотека для управления частотой ШИМ сигнала в Arduino

Эту библиотеку вы можете скачать по следующей ссылке - Arduino PWM Frequency Library.

По представленной ссылке вы скачаете библиотеку в виде ZIP файла. После извлечения информации из этого ZIP файла вы получите каталог (папку) с именем PWM. Перейдите в папку с библиотеками Arduino IDE (для пользователей операционной системы Windows эта папка будет располагаться по адресу C:\Users\User\Documents\Arduino\libraries) и скопируйте туда эту PWM папку. Возможно, в библиотеках Arduino IDE у вас уже есть папка с именем PWM – в этом случае вам ее необходимо заменить на новую (скачанную) папку.

Объяснение программы для Arduino

Полный код программы приведен в конце статьи, здесь же мы рассмотрим его наиболее важные фрагменты. Перед компиляцией программы не забудьте добавить в библиотеки Arduino указанную библиотеку Arduino PWM Frequency Library, иначе компиляция программы будет выдавать вам ошибку.

Нам необходимо формировать ШИМ сигнал с изменяемой частотой на контакте 9 платы Arduino. Эта частота будет устанавливаться с помощью углового кодера, а ее значение будет отображаться на экране ЖК дисплея. А когда ШИМ сигнал будет формироваться на контакте 9 он также будет создавать прерывание на контакте 2 поскольку мы соединили оба этих контакта. Используя это прерывание мы можем управлять частотой SPWM сигнала, который будет формироваться на контакте 5.

Как обычно вначале программы мы должны подключить используемые библиотеки. Библиотека для работы с ЖК дисплеем встроена в Arduino IDE, а библиотеку для изменения частоты ШИМ сигнала мы только что скачали.

Далее мы объявим глобальные переменные и также дадим имена контактам, к которым подключены ЖК дисплей, инкрементальный энкодер и с которых снимаются формируемые сигналы.

Внутри функции setup мы инициализируем ЖК дисплей и последовательную связь (для целей отладки программы), а также зададим режим работы для контактов, к которым подключен угловой кодер. Также мы покажем на экране ЖК дисплея приветственное сообщение.

Далее мы должны использовать такую важную в нашем случае команду как InitTimerSafe, которая инициализирует timer 1 и timer 2 для формирования ШИМ сигнала с изменяемой частотой. Помните, что как только вы используете эту функцию, все настройки по умолчанию для этих таймеров будут сброшены.

Также мы используем внешнее прерывание на контакте 2. То есть всегда, когда будет изменяться состояние контакта 2, будет вызываться процедура обработки прерывания (ISR - Interrupt service routine). В нашем случае этой процедурой обработки прерывания выступает функция generate_sine.

Далее, в функции void loop нам необходимо проверять произошел ли поворот оси энкодера и только когда это произошло нам следует корректировать (изменять) частоту ШИМ сигнала. Если вы впервые сталкиваетесь с таким устройством как инкрементальный энкодер, то вначале рекомендуем прочесть статью о его подключении к плате Arduino.

Если ось инкрементального энкодера вращается по часовой стрелке нам необходимо увеличивать частоту формируемого сигнала при помощи изменения коэффициента умножения. По умолчанию мы устанавливаем его значение равным 32768 что соответствует коэффициенту заполнения (скважности) ШИМ 50% потому что 32768 составляет 50% от 65536. Далее, изменяя это значение, мы можем изменять и коэффициент заполнения ШИМ. После установки коэффициента умножения функция SetPinFrequencySafe используется для установки частоты выходного сигнала на контакте 9.

Внутри функции для обработки прерывания (ISR) нам необходимо написать код для формирования SPWM сигнала. Существует много способов формирования SPWM сигнала в плате Arduino – можно найти даже библиотеки, специально написанные для этой цели. Мы выбрали самый простой из этих способов – мы будем использовать функцию sin(), доступную в Arduino. Функция sin() возвращает изменяющееся значение в диапазоне от -1 до +1 и если мы построим ее зависимость от времени мы как раз получим синусоидальную волну.

После этого все, что нам остается сделать, это преобразовать значение из диапазона от -1 до +1 в диапазон от 0 до 255 и затем передать его в функцию analogWrite. В данном случае мы использовали простое умножение на 255 и затем применили функцию map для преобразования значения из диапазона от -255 до +255 в диапазон от 0 до +255. Затем это значение просто подается на контакт 5 с помощью функции analogWrite. Значение переменной angle (а она у нас имитирует время) увеличивается на 0.2 каждый раз при вызове процедуры (функции) обработки прерывания, что позволяет нам управлять частотой формируемого синусоидального сигнала.

Тестирование работы генератора сигналов

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

Тестирование работы генератора сигналов

Подключите зонд к выходу прямоугольной и синусоидальной волны в схеме. Подключите к этим двум контактам светодиоды если у вас нет осциллографа. Подайте питание на схему и вы увидите приветственное сообщение на экране ЖК дисплея. Затем, вращая ручку углового кодера, вы можете установить желаемое значение частоты сигнала. Формируемые сигналы будет наглядно видно на экране осциллографа. Если вы используете для проверки схемы светодиоды, то вы увидите что частота их мигания будет изменяться с вращением ручки углового кодера.

Тестирование генератора сигналов прямоугольной и синусоидальной формы с помощью осциллографа

Более подробно работу проекта вы можете посмотреть на видео, приведенном в конце статьи.

Исходный код программы (скетча)

Если вы поняли принцип формирования сигналов, описанный в статье, то понимание кода программы не должно вызвать у вас затруднений.

Видео, демонстрирующее работу схемы

Источник статьи

(Проголосуй первым!)
Загрузка...
19 745 просмотров

Комментарии

Генератор сигналов прямоугольной и синусоидальной формы на Arduino — 40 комментариев

  1. Добрый день. Именно не работает. Максимум Частота на видео. Реально 150 герц- очень медленно и дальше виснет. Явно- программный косяк. скетч пробовал и с первоисточника.

    • Доброе утро. Может быть опечатка просто где-нибудь в скетче, которую мы никак совместными усилиями не можем найти. А те, кто нашел, не отписался здесь что поправить. Если бы у меня сейчас был доступ к железу я бы мог попробовать ее найти, но пока такой возможности нет. Чтобы найти эту ошибку надо разбивать программу на небольшие части и тестировать ее по частям, сразу в целой программе тяжеловато бывает ошибку найти

      • Вырезал из скетча синус- прямоугольный сигнал заработал по написанному. Еще в программе нет кольцевой прокрутки частоты и даже множителя. они как бы прописаны, но не работают, видимо символов не хватает. Удалось множитель зациклить, после х1000 переходит на х1. Частоты покамест уходят в минуса. долго разбираться. не понятно на каком языке написана, команды не стандартные

        • Ну хотя бы что то уже заработало, уже хорошо. А где в программе вы увидели нестандартные команды?

          • 70-72 строки. изначальнов самоучителе по ардуино прописаны другие команды. Но здесь адекватно зароботало вот так: multiplier = multiplier * 10;
            if (multiplier>=100000)
            multiplier=1;

            • Ну так это обычные команды арифметических операций и условный оператор. Не вижу в них ничего необычного. Но если у вас заработал проект при небольшом изменении условия (multiplier>=100000), то я рад что у вас получилось

  2. Здравствуйте. А если я хочу через шину подключить сам дисплей, что тогд ужно поменять в программе?

    • я поменял библиотеку . просто изначально в программе есть конкретные пины под выводы и как в таком случае надо поменять саму программу?

        • Он нужен для регулировки контрастности ЖК дисплея. Можно исключить его из схемы если вас устраивает его контрастность по умолчанию

      • Надо смотреть описание самой библиотеки, на каких контактах она что разрешает или запрещает. Какие таймеры она задействует в своей работе. А затем в программе нужно будет поменять строку const int signal_pin = 9, изменив в ней номер контакта на тот, который нужен вам

      • Это зависит от библиотеки. Не видя ее невозможно же точно сказать что вам именно нужно поменять в программе

      • Здравствуйте ещё раз. Я все сделал, что хотел, но теперь есть одна неудобная вещица. Когда пытаюсь поставить частоту выше 2000Гц, значение частоты на дисплее очень медленно появляется. не знаете с чем это может быть связанно?

          • Точно не знаю, но можно попробовать поменять значения емкости и сопротивления компонентов RC-фильтра.

  3. День добрый. помогите скрестить два проекта в одном устройстве .Генератор с модулем 9833 и прерывания щим для создания прибора био резонансного лечения по А.Мишину. Генератор я собрал на ардуино по статье Владимира "Про ардуино и не только генератор 9833", да он работает, но мне нужно еще и новая фенкция в том же устройстве. Режим прохода частоты синуса от 30 кгц до 900 кгц с прерыванием через каждые 20 периодов частоты на 38 процентов от периода. Для этого ардуина должна видеть что генерит 9833 и производить расчет паузы и запрет тактования модуля на время прерывания функцией "При SLEEP1 = 1 запрещается внутреннее тактирование". я понимаю что надо сделать но в программировании "000". готов к мотивации по доработки данного устройства в разумных пределах. Автору проекта писал но реакция ноль, поэтому есть моральное право обратиться к Вам. Прибор только для личного пользования.

    • Марат, по Мишину если, можно использовать синус , 20 периодов и резкая смена фазы на 180 градусов. AD9833 это позволяет сделать легко, а вот режим sweep на этой микросхеме я пока не нашел кто бы внятно обьяснил как?

    • А вы в какую сторону ее хотите поменять? С выхода Ардуино вы больше 5 В все равно не получите. Если хотите меньше - то можно поставить обычный потенциометр, если хотите больше - придется ставить усилитель. Но сейчас усилители не проблема - они сейчас есть в виде одной микросхемы

  4. Игорь, может быть если у вас получится этот проект все таки до конца довести, не поможете мне опечатки в статье исправить и дописать некоторые ваши соображения по практической реализации этого проекта? Был бы вам весьма признателен. Перевел я этот проект с иностранного сайта, по принципу действия все логично, разобрался, понял. Но вот с опечатками недосмотрел

  5. Добрый вечер, спаял а вот что 16-02не хочет работать,сигналы на ресет и синхро наверное брались из данных а теперь шина данных на нане заполнена, сигналы по схеме выходят с А0 и А1, програмно не могу найти и вот что то не работает информационное табло. на Ардуино нано Д15-13 нет, понимаю что аналаговые их подменяют и всетаки что то не работает...куда идти

    • Добрый вечер. Да, с D15 в таблице опечатка вышла, надо поправить в ближайшее время. Но если открыть схему в отдельной вкладке браузера там все соединения на схеме отлично видны.
      В этих ситуациях идут от простого к сложного, то есть тестировать проект по частям (если есть такая возможность). В вашей ситуации можно порекомендовать сначала разобраться с ЖК дисплеем - убрать из программы все лишние строки (возможно, удалить из схемы некоторые соединения, не оказывающих влияния на работу с дисплеем) и отладить работу с ним. После того как это получится, протестировать генерацию синусоидального сигнала, а когда с ним все получится, тогда уже переходить к тестированию генерации прямоугольного сигнала

      • тормоза у меня еще на уровне прошивки и дисплея, пока только клеточкив стандартных схемах рс сигнал весь ракидан на данных а ту снимается с А0 А1вроде все нормально подкинул

        • Так в чем у вас основная проблема? В том, что ЖК дисплей 16х2 не работает? К примеру, на нашем сайте есть статья "Подключение жидкокристаллического (ЖК) дисплея к Arduino". И подобная статья есть еще на многих сайтах в сети потому что подключение такого дисплея к Arduino - это одна из базовых вещей, которой сайты пытаются научить своих посетителей. Мне казалось, что с этим вопросом не должно быть особых проблем (при условии, конечно, что ЖК дисплей попался исправный).

          • Дело в том ,как мне кажется константы заданы неверно,дисплей исправный , не выводится информация на него-
            const int rs = 14, en = 15, d4 = 4, d5 = 3, d6 = 6, d7 = 7; //контакты к которым подключен ЖК дисплей// мне кажется что данные 14 и15 изначально заданы неверно, аппаратно эти сигналы подключены на аналог А0-1, на экране клеточки вместо буковок

            • Да, с контактами ЖК дисплея здесь опечатка вышла, недосмотрел я, извиняюсь. Нужно не только в таблице их изменить, но и в программе

          • энкодерные нажатия вроде реагируют/моргает светодиод на ардуино нано/
            куда копаться не знаю, до измерения сигалов пока не дошел, визуализации ету

          • и собственно жк дисплей в этой схеме подключен не совсем так,как везде все сообщения с ардуиной проходят через пины данных/дигитал/

            • может константы задать 0 и2

            • подчитал подгрузил,перепиновал-все запоказывало, спасио дорогой товарищ, буду дальше маяться на этапе экодер и далее квадрат/прямоугольник/ а потом синус

    • Что конкретно не работает? Может быть в соединениях где-нибудь ошибка? Если сразу весь проект не заработал, в этом случае целесообразно производить его отладку по частям чтобы найти в чем ошибка. Например, для этого проекта можно попробовать сначала реализовать только генератор прямоугольной волны - в этом случае проект значительно упростится. Возможно, у вас возникла проблема с прерываниями, а синусоидальный сигнал в этом проекте как раз формируется с помощью обработчика прерывания. Попробуйте отладку с помощью монитора последовательной связи.
      Посмотрите хотя бы комментарии пользователей к представленному видео на youtube - там пишут что прекрасный проект и все работает.

      • Посмотрите хотя бы комментарии пользователей к представленному видео на youtube - там пишут что прекрасный проект и все работает.
        Комментов не так много, интересно когда подцепил сигналы sqware прошивка стала тупить встает колом и кодер не меняет частоту странное дело, с дисплеем разобрался скорее всего сопли-что делать, вирус на улице, вирус на схеме, или тараканы в голове

        • Ну схемотехника весьма занятное дело, но не всегда все в ней получается с первого раза, к сожалению ))

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

            • Да, теоретически статья неплоха, поэтому и решил ее перевести для нашего сайта. Но на практике, к сожалению, не все так гладко как в теории. Ну у вас хоть получилось этот проект до конца доделать? Разобрались со всеми проблемами?

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *