Что такое ШИМ и как она используется в Arduino
Нам понадобится:
- Arduino UNO или иная совместимая плата;
- светодиод (вот из такого набора, например);
- резистор номиналом 190…240 Ом (вот отличный набор резисторов самых распространённых номиналов);
- макетная плата (breadboard);
- персональный компьютер со средой разработки Arduino IDE.
Инструкция по использованию ШИМ в Arduino
1Общие сведенияо широтно-импульсной модуляции
Цифровые выводы Arduino могут выдавать только два значения: логический 0 (LOW, низкий уровень) и логическую 1 (HIGH, высокий). На то они и цифровые. Но есть у Ардуино «особые» выводы, которые обозначаются PWM. Их иногда обозначают волнистой чертой "~" или обводят кружочками или ещё как-то выделяют среди прочих. PWM расшифровывается как Pulse-width modulation или широтно-импульсная модуляция, ШИМ.
Широтно-импульсно модулированный сигнал – это импульсный сигнал постоянной частоты, но переменной скважности (соотношение длительности импульса и периода его следования). Из-за того, что большинство физических процессов в природе имеют инерцию, то резкие перепады напряжения от 1 к 0 будут сглаживаться, принимая некоторое среднее значение. С помощью задания скважности можно менять среднее напряжение на выходе ШИМ.
Если скважность равняется 100%, то всё время на цифровом выходе Arduino будет напряжение логическая "1" или 5 вольт. Если задать скважность 50%, то половину времени на выходе будет логическая "1", а половину – логический "0", и среднее напряжение будет равняться 2,5 вольтам. Ну и так далее.
В программе скважность задаётся не в процентах, а числом от 0 до 255. Например, команда analogWrite(10, 64) скажет микроконтроллеру подать на цифровой PWM выход №10 сигнал со скважностью 25%.
Выводы Arduino с функцией широтно-импульсной модуляции работают на частоте около 500 Гц. Значит, период следования импульсов – около 2 миллисекунд, что и отмеряют зелёные вертикальные штрихи на рисунке. Получается, что мы можем сымитировать аналоговый сигнал на цифровом выходе! Интересно, правда?!
Как же мы можем использовать ШИМ? Применений масса! Например, управлять яркостью светодиода, скоростью вращения двигателя, током транзистора, звуком из пьезоизлучателя и т.д.…
2Схема для демонстрации широтно-импульсной модуляции в Arduino
Давайте рассмотрим самый базовый пример – управление яркостью светодиода с помощью ШИМ. Соберём классическую схему.
3Пример скетча с ШИМ
Откроем из примеров скетч "Fade": Файл Образцы 01.Basics Fade.
Немного изменим его и загрузим в память Arduino.
int ledPin = 3; // объявляем пин, управляющий светодиодом int brightness = 0; // переменная для задания яркости int fadeAmount = 5; // шаг изменения яркости void setup() { pinMode(ledPin, OUTPUT); } void loop() { analogWrite(ledPin, brightness); // устанавливаем яркость brightness на выводе ledPin brightness += fadeAmount; // изменяем значение яркости /* при достижении границ 0 или 255 меняем направление изменения яркости */ if (brightness == 0 || brightness == 255) { fadeAmount = -fadeAmount; // изменяем знак шага } delay(30); // задержка для большей видимости эффекта }
4Управление яркостью светодиода с помощью PWM и Arduino
Включаем питание. Светодиод плавно наращивает яркость, а затем плавно уменьшает. Мы сымитировали аналоговый сигнал на цифровом выходе с помощью широтно-импульсной модуляции.
Посмотрите приложенные видео, где на экране осциллографа DSO138 наглядно показано изменение яркости светодиода, и как при этом меняется сигнал с Arduino.
Ещё одно видео:
Поблагодарить автора:
Поделиться
Related items
2 comments
-
Алексей Суббота, 22 May 2021 05:43 Ссылка на комментарий
Уважаемый Андрей!
Подскажите, возможно ли внедрить в предложенный Вами скетч интервал - в цикл плавного включения и выключения светодиода по схеме:
0 - максимум свечения - 0 - интервал (например 5 секунд)- 0 - максимум свечения - 0 и так далее?
С уважением
Алексей -
aave1 Суббота, 22 May 2021 17:01 Ссылка на комментарий
Алексей! Ну разумеется, вы вольны делать задержки любой длительности. А если нужно только две яркости свечения - минимальная и максимальная - то и ШИМ вам не нужна. Достаточно записать analogWrite(ledPin, LOW) или analogWrite(ledPin, HIGH), соответственно.