В предыдущей статье мы с вами обсуждалли АЦП. На этот раз мы займемся генерацией специфического сигнала.
Мы говорим о ШИМ (PWM) — широтно-импульсной модуляции. Этот вопрос может показаться сложным, но несколько практических примеров наверняка развеют любые сомнения!
Что такое сигнал ШИМ?
Допустим, мы подключили к микроконтроллеру светодиод и запрограммировали его на поочередное мигание. Светодиод горит одну секунду, следующую секунду гаснет и так далее:
1 2 3 4 5 6 7 8 9 10 |
void setup() { pinMode(3, OUTPUT); //Контакт 3 как выход } void loop() { digitalWrite(3, HIGH); //Включение светодиода delay(1000); //Ожидание 1 секунда digitalWrite(3, LOW); //Выключение светодиода delay(1000); } |
Если бы мы нарисовали график изменения напряжения на третьем выводе Arduino, мы получили бы прямоугольную волну:
Значение, отмеченное как x, — это время, в течение которого горит светодиод. Тогда как T — это период работы (свечения) светодиода. В свою очередь, его обратное значение, то есть 1 / T, означает частоту. Соотношение времени, когда светодиод горит, и время, когда он выключен 1:1. Другими словами, он остается включенным только 50% работы программы. Профессионально этот параметр называется сигнальным заполнением.
Обобщая информацию о нашем сигнале:
- Амплитуда (максимальное значение): 5 В
- Период сигнала: 2 секунды
- Частота сигнала: 1/2 = 0,5 Гц
- Заполнение сигнала: 50%
Пришло время аналогичного эксперимента. Однако с измененным заполнением с сохранением предыдущего периода. Как это сделать? Достаточно продлить время работы светодиода и сократить время его выключения. Например:
1 2 3 4 5 6 7 8 9 10 |
void setup() { pinMode(3, OUTPUT); //Контакт 3 как выход } void loop() { digitalWrite(3, HIGH); //Включение светодиода delay(1667); digitalWrite(3, LOW); //Выключение светодиода delay(333); } |
На этот раз светодиод горит примерно 5/6 времени. Таким образом, заполнение составляет около 83%. Изобразив ситуацию на графике, аналогичном предыдущему, мы получаем:
Если мы заменим задержки местами, то получим обратную ситуацию, т.е. сигнал с скважностью 17%. Последний график:
Взгляните еще раз на приведенные выше примеры. Какой параметр менялся каждый раз? Ответ прост: заполнение. Частота сигналов оставалась неизменной.
Говоря более практическим языком, менялся только «процент времени, в течение которого сигнал имеет высокий потенциал». |
Теперь представьте, что задержки, вставленные в вышеуказанные программы, намного меньше, что делает частоту сигнала намного выше…
Поздравляем! Вы только что, на практике, поняли принцип работы ШИМ. То есть метод модуляции прямоугольного сигнала путем регулировки ширины импульса.
Вы, наверное, сейчас думаете про себя: отлично, но для чего вам это нужно?
Представьте себе двигатель, управляемый переключателем. При включении питания двигатель сразу достигает своих максимальных оборотов? Нет, сначала он должен разогнаться. То же самое относится и к постепенной остановке. Что происходит, когда мы включаем и выключаем питание на таком двигателе? Если операция будет достаточно быстрой, то мы сможем достичь промежуточных скоростей между остановкой и полными оборотами. Полученная скорость будет зависеть от времени, в течение которого мы подавали питание на двигатель.
Если такое включение и выключение происходит намного быстрее, то описанный эффект мы сможем использовать даже с, казалось бы, очень «быстрыми» элементами — светодиодами.
Каково применение сигнала ШИМ?
Что ж, в цифровой технике этот сигнал используется очень часто. С его помощью вы сможете контролировать яркость диода, положение сервопривода и скорость вращения двигателя!
Регулировка яркости светодиода
Пришло время для первого практического примера использования ШИМ. На этот раз мы будем иметь дело с простой программой, которая будет управлять миганием светодиода.
Arduino имеет 6 аппаратных каналов ШИМ. Каждый выход, на котором мы можем получить сигнал ШИМ, отмечен на плате тильдой «~», а на нашей графике, рядом с ним, есть дополнительное примечание ШИМ:
Аппаратно генерируемая ШИМ означает, что генерация этого сигнала не влияет на программу (не задерживает ее). Нам также не нужно самостоятельно писать функции, генерирующие такой сигнал. |
Каждый канал ШИМ, доступный на плате Arduino UNO, является 8-битным. Это означает, что мы можем определить рабочий цикл сигнала, который мы хотим получить на его выходе, с помощью числа от 0 до 255, где 255 означает 100% рабочий цикл.
Для того, чтобы провести первое упражнение, необходимо подключить светодиод к выводу 3. У вас не должно возникнуть с этим проблем:
Пришло время написать программу. Наша цель — написать несколько строк, при которых светодиод будет медленно мигать. Другими словами, мы будем изменять рабочий цикл сигнала ШИМ.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
#define diodPIN 3 int completion = 0; int change = 5; void setup() { pinMode(diodPIN, OUTPUT);//Контакт как выход } void loop() { analogWrite(diodPIN, completion); //Генерируем сигнал о заданном заполнении if (completion < 255) { //Если заполнение меньше 100% completion = completion + change; //Увеличиваем заполнение } else { completion = 0; //Если заполнение больше 100%, то возвращаемся к началу } delay(50); //Небольшая задержка, чтобы сделать эффект видимым } |
Надеемся, что вам все ясно, и мы можем рассказать только об одной новой функции. Конечно, это analogWrite (пин, заполнение). Его задача — сформировать сигнал ШИМ с выбранным рабочим циклом на выбранном выводе.
Задача вышеуказанной программы — циклически увеличивать заполнение от нуля до значения ниже 255 (100%).
Домашнее задание 4.1
Попытайтесь упростить приведенную выше программу, чтобы вам не приходилось использовать оператор if. Подсказка: подумайте о влиянии типа заполнения переменной на работу программы.
Домашнее задание 4.2
Напишите программу, которая после увеличения заполнения до 255 будет постепенно уменьшать ее до нуля (снова и снова). Проверьте, при какой задержке, в каждом цикле, может наблюдаться пульсирующий эффект.
Использование сервопривода
Наверное, вы уже давно ждете момента, когда мы начнем обсуждать и применять сервопривод на практике. Наконец, этот момент настал, найдите в своем наборе (или купите) элемент, идентичный (или похожий) на этот:
Это один из самых маленьких сервоприводов, что вы сможете найтив продаже. Однако, его размер не влияет на способ управления. Как только вы поймете принцип работы сервопривода, вы сможете использовать в своих проектах более крупные, мощные и быстрые сервоприводы.
Что такое сервопривод?
Сервопривод — это двигатель, редуктор и специальный контроллер, заключенные в один корпус. Однако эти приводы не предназначены для полного вращения. Чаще всего сервоприводы могут поворачиваться на угол 0–180 °. Важно отметить, что они запоминают свое текущее положение, поэтому нам не нужно бояться, например, увеличения количества ошибок положения.
Сервомеханизмы в основном используются при моделировании различных шаговых роботов в робототехнике. |
Два самых важных правила использования сервоприводов:
- Нельзя поворачивать вручную положение вала без необходимости. Это может повредить относительно хрупкие пластмассовые шестерни внутри корпуса.
- Нельзя подключать сервоприводы напрямую к источнику питания. Это может привести к их повреждению. Каждый сервопривод потребляет относительно большой ток, особенно в начале хода.
Как работает сервопривод?
Откуда сервопривод знает, в какую позицию повернуть? Все благодаря встроенному драйверу. Именно он, на основе подаваемого ШИМ-сигнала, управляет двигателем. Принятый стандарт заключается в том, что на сервоприводы подается сигнал с периодом 20 мс. С другой стороны, рабочий цикл интерпретируется как положение, в которое следует переместить сервомеханизм.
Рабочий цикл генерируемого сигнала должен быть в пределах 5-10%. Эти значения будут преобразованы в два крайних положения сервопривода (крайнее левое и крайнее правое).
Каждый сервопривод имеет 3 провода:
- Масса (черный, темно-коричневый)
- Питание (красный)
- Управляющий сигнал (желтый / оранжевый)
В зависимости от производителя, цвета проводов могут отличаться. Однако два точно будут близки к черному и красному цветам. Оставшийся, третий, будет сигнальным проводом.
Электропитание сервопривода
Как было сказано ранее, вы не должны запитывать сервопривод напрямую от того же напряжения, которое питает микроконтроллер. Из-за того, что двигатель может потреблять много тока, нам необходимо подключить к схеме эффективный источник.
К сожалению, порт USB, от которого мы до сих пор питали нашу плату, может оказаться слишком слабым! |
Поэтому, впервые, мы будем питать Arduino через батарею 9 В с зажимом, который заканчивается вилкой, которая соответствует розетке питания в Arduino. Точная схема подключения приведена ниже.
Сервомеханизм на практике
Пришло время для первой программы, которая будет поворачивать сервомеханизм. Для этого подключите сервопривод в соответствии со схемой сборки ниже. Сначала необходимо подключить аккумулятор. А потом, нам нужно будет использовать стабилизатор LM7805.
Если вы не знаете, что это за элемент, обязательно ознакомьтесь со статьями из раздела электроники! |
Подключаем вход стабилизатора к выводу Vin Arduino, землю к GND, а красный провод сервопривода подключаем к выходу. Разумеется, конденсаторы фильтра также необходимы. Остальное уже должно быть понятно:
Пришло время для программы, которая будет управлять сервоприводом. Чтобы начать работу с готовой программой, ниже найдете объяснение:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
#include <Servo.h> //Библиотека, ответственная за сервоприводы Servo servomechanism; //Создаем объект, с помощью которого можем ссылаться на сервопривод int situation = 0; //Текущее положение сервопривода 0-180 int change = 6; //Сколько должно меняться положение сервопривода? void setup() { servomechanism.attach(9); //Сервопривод подключен к пину 9 } void loop() { if (situation < 180) { //Если находится в диапазоне servomechanism.write(situation); //Повернуть } else { //Если нет, то вернемся к началу situation = 0; } situation = situation + change; //Увеличение поворота текущего положения сервопривода delay(200); //Задержка для лучшего эффекта } |
На этот раз нам нужно добавить новую библиотеку, которая расширит возможности нашей программы с помощью наших функций. Для этого используется команда:
1 |
#include Servo.h |
В этом случае мы добавили файл Servo.h, который содержит дополнительные инструкции сервопривода. Благодаря этому нам не придется самостоятельно контролировать сгенерированный сигнал ШИМ. Достаточно ввести положение (угол), в которое сервопривод должен повернуться.
Если мы хотим управлять сервоприводом, мы должны создать для него объект:
1 |
Servo servomechanism; |
Функция attach (Pin) — для объекта Servo — работает аналогично pinMode — аргумент — это контакт, к которому подключен элемент. С этого момента сигнал ШИМ будет генерироваться на данном пине (выводе), в данном случае 9.
После запуска программы сервопривод должен плавно перемещаться из одного крайнего положения в другое, а затем вернуться в начало. Ключевое направление:
1 |
servomechanism.write(situation); |
Где мы должны ввести угол в диапазоне 0-180º в качестве позиции.
Домашнее задание 4.3
На основе приведенной выше программы, напишите свою собственную, которая будет выполнять каждый последующий переход на новую позицию через более длительное время (200 мс, 250 мс и т.д.).
Домашнее задание 4.4
Напишите программу, которая поворачивает сервопривод в положение, отправленное в Arduino через UART. Передаваемые числа должны находиться в диапазоне 0–180, в противном случае должно отображаться соответствующее сообщение.
Домашнее задание 4.5
Подключите к схеме потенциометр в качестве делителя напряжения. Затем используйте АЦП для измерения напряжения, установленного на потенциометре. Чем он больше, тем ближе сервопривод должен находиться к крайнему правому положению.
Не подключайте моторы самостоятельно!
В этой части стать мы подключили сервопривод напрямую к Arduino. Это стало возможным, потому что у этих приводов есть внутренние драйверы, которые контролируют его работу без оборудования.
Следовательно, вывод Arduino, который контролирует положение (отклонение) сервопривода, не потребляет много тока. |
Если вы подключите «голый мотор» к Arduino самостоятельно, потребляемый ток (> 20 мА), то это приведет к повреждению схемы! Помните, что электромоторам (даже маленьким) для работы может потребоваться в 10 или даже в 100 раз больший ток, чем на выводах микроконтроллера!
Для прямого подключения мотора (двигателя) требуется промежуточный контур, h-мост! Об этом мы вам расскажем в другой раз.
Вывод
Мы надеемся, что эта статья позволила вам понять, что такое ШИМ-сигнал и как его можно использовать в ваших проектах.
В следующих ствтьях обсудим несколько полезных приемов, связанных с передачей через UART. Мы также покажем, как на практике можно использовать сервопривод в качестве аналогового индикатора, и продемонстрируем, как использовать Arduino и систему L293D для управления двигателем постоянного тока!
С Уважением, МониторБанк