Что такое шим в ардуино
Перейти к содержимому

Что такое шим в ардуино

  • автор:

Широтно-импульсная модуляция (ШИМ или PWM) в Arduino

Для вывода данных с Arduino традиционно применяется двоичная система с применением логических значений 0 и 1. С этой задачей превосходно справляется управление портами вывода, имеющееся у большинства микроконтроллеров от производителей микросхем. Но не всегда схемотехнику необходимо значение нуля или единицы.

Возможно ли получить промежуточное значение с помощью Arduino?

С помощью широтно-импульсной модуляции, реализованной на некоторых портах микросхемы, это возможно. Так, Arduino Uno поддерживает ШИМ на следующих своих портах: 3,5,6, 9, 10 и 11.

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

Микроконтроллер Arduino поддерживает восьмибитную ШИМ, что позволяет выбрать переменную в широком диапазоне значений от 0 до 256.

В качестве примера использования ШИМ можно использовать плавное включение и выключение светодиода, подключенному к 3 пину. При этом постепенно подается напряжение от 0 до 5В. Как видно на картинке ниже, при разном значении переменной мы получаем разное напряжение для светодиода: 5V, 2.5V, 1,25V, 3.75V.

Так же с помощью пьезоизлучателя и ШИМ можно воспроизводить звуки неплохого качества.

Урок №04. Работа с ШИМ-портами. Циклы.

Теоретическая справка о ШИМ (широтно-импульная модуляция)

ШИМ (широтно-импульсная модуляция) — процесс управления мощностью, подводимой к нагрузке, путём изменения скважности импульсов, при постоянной частоте. Простыми словами — это способ задавать произвольное напряжение на выходе, переключаясь между LOW и HIGH сигналами тысячи раз в секунду.

Под скважностью понимается временной промежуток между LOW и HIGH сигналами.

Для более ясного понимания ШИМ приведем пример. Предположим, что у нас есть светодиод, который соединен с кнопкой таким образом, что когда ее зажимают, светодиод излучает свет, а когда кнопка отпущена, то он гаснет. И так, если мы зажмем кнопку и практически сразу его отпустим, то светодиод погаснет, не успев загореться на полную мощность. Теперь попробуем провести этот опыт несколько раз подряд. Мы увидим, что светодиод как будто бы не успевает получить полное напряжение и работает лишь на 50 %. По такому принципу работает ШИМ. Она подает максимальное напряжение, но благодаря тому как долго держит «нажатой» кнопку, «отпускает», ждет и потом снова «нажимает» кнопку, рождается вот такой сигнал с уменьшенным значением напряжения. Ниже приведено несколько графиков с примерами:

P019-pwm-duty-50

P019-pwm-duty-10

P019-pwm-duty-90

Шим порты

На платах Arduino UNO специальные ШИМ-порты обозначают волнистой чертой «~».

На большинстве плат Arduino Uno, Nano, Micro режим работы с ШИМ поддерживают порты 3, 5, 6, 9, 10 и 11. На плате Arduino Mega порты с 2 по 13.

Теоретическая справка о цикле FOR

Опишем работу цикла FOR:

Оператор for требует на вход 3 параметра for (выражение 1; выражение 2; выражение 3), которые определяют количество раз, которое будет выполнен цикл.

  • Сначала определяется переменная счетчик (выражение 1).
  • Проверяется условие выполнение цикла (выражение 2)
  • Если условие ложно, то программа выходит из цикл for и продолжает свое выполнение. Т.е. если в самом начале условие будет ложно, то тело цикла не выполнится ни одного раза.
  • Если условие истинно, то начинает выполняться тело цикла.
  • После того как тело цикла выполнится, программа возвращается к заголовку и выполняет изменение значение переменной-счетчика (выражение 3).
  • После этого возвращаемся к пункту два, и все действия повторяются до тех пор, пока условие не станет ложным.

Пример формата цикла FOR:

for (int i=0; i 

Написание программного кода

Для того чтобы послать ШИМ-сигнал с цифрового пина нам нужна функция analogWrite(). Эта функция посылает значения от 0 до 255 на заданный ШИМ-пин, где 0 соответствует 0V, а 255 — 5V. Таким образом, организуя цикл, который будет отправлять ШИМ-сигнал, увеличивая его значение на единицу каждые 10 миллисекунд, мы получим плавно загорающийся светодиод.

int PWMpin=10; //объявляем переменную пина void setup() < pinMode(PWMpin, OUTPUT); //выставляем режим работы 10-ого пина как выход. >void loop() < for (int i=0; i>

ШИМ (PWM) В Arduino

Широтно-импульсная модуляция ( PWM или ШИМ ) — с помощью этого метода можно изменять ширину импульса при сохранении постоянной частоты волны. При данном методе используется цифрой источник сигнала, из которого получают аналоговый сигнал.

Сигнал ШИМ состоит из двух основных составляющих, которые влияют на его работу. Одним из них является коэффициент заполнения (рабочий цикл), вторым — частота сигнала.

Коэффициент заполнения сигнала

Период импульса состоит из цикла включения +5В и цикла выключения . Величина, в течение которого сигнал находится в высоком уровне (включен) во время одного периода, известна как коэффициент заполнения (выраженная в процентах).

\[ DutyCircle=\frac\times100 \]Например. Импульс с периодом 20 мс будет оставаться включенным (высоким) в течение 4 мс. Следовательно, рабочий цикл будет:

D = 4ms / 20ms × 100 = 20%

Применяя метод широтно-импульсной модуляции мы можем управлять регулировкой мощности, которую подают на нагрузку. Изменение мощности происходит за счет увеличения или уменьшения значения рабочего цикла. Сигналы ШИМ применяются для управления скоростью двигателей DC (постоянного тока) или для управления интенсивностью свечения светодиода.

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

Примеры сигналов ШИМ с разным коэффициентом заполнения

Частота сигнала

Частота сигнала определяет, как быстро ШИМ завершает цикл. То есть 2000 Герц будет 2000 циклов за одну секунду). Это означает, как быстро сигнал переходит из высокого уровня в низкий. Повторяя эту последовательность высокого и низкого уровня сигнала с высокой скоростью (частотой) и с определенным рабочим циклом(коэффициентом заполнения), выход ШИМ будет представлять из себя обычный аналоговый сигнал с постоянным напряжением.

Пример

Если мы хотим создать аналоговый сигнал +2В для данного цифрового источника, который может быть либо высоким (включен) при +5В , либо низким (выключен) при 0В , мы можем использовать ШИМ с рабочим циклом 40% . Он будет обеспечивать выход +5В в течение 40% времени.

Если цифровой сигнал циклически повторяется достаточно быстро, то напряжение на выходе оказывается средним напряжением. Если цифровое нижнее значение равно 0 В (что обычно и бывает), то среднее напряжение можно рассчитать, взяв цифровое высокое напряжение, умноженное на рабочий цикл:

Теперь давайте посмотрим на ШИМ в Arduino на примере Arduino Uno.

Контакты PWM (ШИМ) в Arduino

Arduino Uno имеет 6 8-битных каналов ШИМ. Эти контакты на плате обозначены символом «~». Эти выводы показаны на изображении ниже.

Контакты, которые поддерживают ШИМ, на плате ардуино уно

Функции Arduino для работы с ШИМ

AnalogWrite (Pin, Duty)

Эта функция применяется для генерации ШИМ или вывода аналогового значения на указанный канал. Подробнее о функции analogWrite.

Параметры

  • Pin — вывод, на котором мы хотим генерировать ШИМ или аналоговый сигнал.
  • Duty — рабочий цикл, лежит в пределах от 0 (0%, всегда выключен) – 255 (100%, всегда включен).

Пример

AnalogWrite (3, 127) // генерирует ШИМ с рабочим циклом 50%

Затухание светодиода с помощью Arduino PWM

Давайте создадим небольшое приложение, в котором светодиод будет постоянно гаснуть. Это приложение по управлению яркостью светодиода можно использовать, например, для украшения светодиодами дома или фестивалей.

Схема подключения светодиода к ардуино уно

Скетч для затухания светодиода с помощью Arduino PWM

int led = 6; // контакт ШИМ, к которому подключен светодиод int brightness = 0; // яркость светодиода int fadeAmount = 5; шаг изменения яркости светодиоду void setup() < pinMode(led, OUTPUT); // объявляем вывод ШИМ как выход: >void loop() < analogWrite(led, brightness); // устанавливаем яркость светодиода // изменить яркость в следующий раз через цикл: brightness = brightness + fadeAmount; // изменить направление затухания на концах затухания: if (brightness = 255) < fadeAmount = -fadeAmount; >delay(30); // ждем 30 миллисекунд, чтобы увидеть эффект затемнения >

Управление яркостью светодиода с помощью потенциометра

Давайте создадим приложение, в котором мы будем управлять яркостью светодиода с помощью Arduino, изменяя ручку потенциометра. И так, когда мы вращаем ручку потенциометра, АЦП Arduino будет считывать этот аналоговый сигнал. Затем мы будем генерировать ШИМ-сигнал, пропорциональный аналоговому сигналу.

Схема подключения потенциометра и светодиода

Скетч для управления яркостью светодиодов

int ledPin = 6; // светодиод подключен к цифровому контакту 9 int analogPin = A0; // потенциометр подключен к аналоговому контакту 3 int val = 0; // переменная для хранения прочитанного значения void setup() < pinMode(ledPin, OUTPUT); // объявляем вывод ШИМ как выход: >void loop() < val = analogRead(analogPin); // чтения значения от потенциометра analogWrite(ledPin, val / 4);// Значения AnalogRead варьируются от 0 до 1023, значения AnalogWrite от 0 до 255. >

ШИМ сигнал

Очень часто в робототехнике возникает необходимость плавно управлять каким-то процессом, будь то яркость светодиода, мощность обогревателя или скорость вращения моторчика. Вполне очевидно, что управление напрямую связано с изменением напряжения на потребителе: и светодиод будет по-другому светить, и моторчик крутиться с другой скоростью. Но проблема в том, что управлять напряжением может только такая штука, как ЦАП – цифро-аналоговый преобразователь, а в нашем микроконтроллере встроенного ЦАПа нет, у нас есть только цифровой сигнал, т.е. либо вкл, либо выкл: Можно ли добиться плавного управления цифровым сигналом? Можно! Представьте себе вентилятор, вращающийся на полной мощности, напряжение постоянное. Представим теперь, что секунду напряжение подаётся, и секунду – нет, и так продолжается “по кругу”. Вентилятор начнёт крутиться в два раза медленнее, но мы скорее всего будем замечать моменты включения и выключения, особенно если вентилятор маленький и быстро останавливается. Теперь давайте включать напряжение на 0.5 секунды, а на остальные 1.5 секунды – выключать. Вентилятор будет крутиться со скоростью 25% от максимальной. Мы с вами смогли представить так называемый ШИМ сигнал, широтно-импульсную модуляцию:
С лампочкой накаливания оно тоже будет работать, она ведь весьма инертна, но вот со светодиодом мы будем видеть, как он включается и выключается, потому что он практически не имеет задержки включения/выключения. Что же делать? Всё очень просто, поднять частоту. В мысленном эксперименте у нас был период 2 секунды, что есть 0.5 Гц. А теперь представьте себе такой сигнал с частотой скажем 1000 Гц. Или 25’000 Гц (25 кГц). Теперь роль играет инертность глаза, он не заметит вспышек на такой частоте, для него это будет просто уменьшение яркости.

Задача решена! Изменяя так называемое “заполнение” ШИМ сигнала можно менять “суммарное” (интегрированное) напряжение за некоторый период. Чем больше заполнение ШИМ, тем выше напряжение. Но не выше напряжения, которое мы “ШИМим”: При помощи ШИМ сигнала можно даже модулировать сложные аналоговые сигналы, например – синусоиду. На картинке ниже показан ШИМ (снизу) и этот же ШИМ после фильтров: Вот таким образом кстати и работают инвертеры DC-AC. Возвращаясь к свойствам ШИМ сигнала, их всего два: частота (frequency) и заполнение (duty), с ними мы разобрались. Давайте перейдём к генерации ШИМ при помощи Arduino.

ШИМ пины

Взглянем на распиновку популярных плат Arduino Nano и Wemos Mini:

blank blank

Пины, на которых можно запустить ШИМ сигнал стандартными средствами Arduino, помечены как PWM:

  • На Arduino Nano есть 6 таких пинов. Дело в том, что ШИМ сигнал генерируется отдельными аппаратными блоками (таймерами), поэтому их количество ограничено. В то же время генерация ШИМ на повышенной частоте не нагружает микроконтроллер, сигнал генерируется самостоятельно.
  • На Wemos Mini можно запустить ШИМ на любом пине, кроме GPIO16. Здесь генерация ШИМ реализована программно, поэтому работает на любом пине, но использование одновременно нескольких пинов на повышенной частоте будет тормозить работу микроконтроллера.

Включаем ШИМ

Для генерации ШИМ у нас есть готовая функция analogWrite(pin, duty) :

  • pin – PWM пин (см. распиновку выше). Нумерация пинов такая же, как в уроке про цифровые пины.
  • duty – заполнение ШИМ сигнала. По умолчанию имеет разрядность 8 бит, то есть принимает значение 0.. 255. Примечание: у esp8266 на версии ядра до 3.0 разрядность была 10 бит, то есть 0.. 1023.

Совместим эти знания с прошлым уроком и попробуем менять яркость светодиода, подключенного через резистор к пину D3 (Arduino Nano). Потенциометр подключен к пину A0:

void setup() < >void loop() < // ШИМ на 3 пин, 1023/4 = 255 - перевели диапазон analogWrite(3, analogRead(0) / 4); >

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

Особенности Arduino Nano

Стандартные параметры ШИМ сигнала:

Таймер Пины Частота Разрядность
Timer 0 D5 и D6 976 Гц 8 бит (0.. 255)
Timer 1 D9 и D10 488 Гц 8 бит (0.. 255)
Timer 2 D3 и D11 488 Гц 8 бит (0.. 255)

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

Особенности Wemos Mini

Частота ШИМ по умолчанию 1 кГц.

  • Частоту можно настроить в analogWriteFreq(100.. 40000 Гц) .

Разрядность ШИМ по умолчанию 8 бит (0.. 255) на версиях ядра 3.x. На ранних версиях – 10 бит (0.. 1023). Скажем спасибо индусам за совместимость.

  • Разрядность можно настроить в analogWriteResolution(4. 16 бит) .

Программный ШИМ

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

Видео

Полезные страницы

  • Набор GyverKIT – большой стартовый набор Arduino моей разработки, продаётся в России
  • Каталог ссылок на дешёвые Ардуины, датчики, модули и прочие железки с AliExpress у проверенных продавцов
  • Подборка библиотек для Arduino, самых интересных и полезных, официальных и не очень
  • Полная документация по языку Ардуино, все встроенные функции и макросы, все доступные типы данных
  • Сборник полезных алгоритмов для написания скетчей: структура кода, таймеры, фильтры, парсинг данных
  • Видео уроки по программированию Arduino с канала “Заметки Ардуинщика” – одни из самых подробных в рунете
  • Поддержать автора за работу над уроками
  • Обратная связь – сообщить об ошибке в уроке или предложить дополнение по тексту ([email protected])

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

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