Общие сведения
В этом уроке мы разберёмся что такое ШИМ.
Каждый вывод Raspberry Pi Pico в режиме Pin.OUT
может
принимать значение логического нуля или логической единицы. Полного
напряжения питания (+3.3 вольта относительно GND) или отсутствие этого
напряжения (ноль вольт относительно GND). Соответственно мы можем зажечь
светодиод или выключить светодиод, если он подключён к выводу Pi Pico.
Но что если нам надо получить среднюю яркость светодиода? У данной
проблемы есть не один способ решения (источник постоянного тока, ЦАП),
но мы рассмотрим самый простой - ШИМ.
ШИМ - Широтно-Импульсная Модуляция.
Для управления яркостью светодиода мы можем включать и выключать его так быстро, что для человеческого глаза это будет выглядеть как изменение яркости. По своей сути быстрое включение и выключение (изменение логического уровня вывода) и есть ШИМ, но помимо изменения уровня у ШИМ есть ещё два важных параметра:
- Частота импульса (frequency) - как быстро мы переключаем уровни
- Широта импульса (duty) - процентное отношение уровней (в каком состоянии вывод проводит большую часть времени)
Собственно при помощи широты импульса мы и будем менять яркость светодиода. Широта импульса в MicroPython задаётся следующим образом:
pwm.duty_u16( ШЕСТНАДЦАТИБИТНОЕ_ЧИСЛО_БЕЗ_ЗНАКА )
ШЕСТНАДЦАТИБИТНОЕ_ЧИСЛО_БЕЗ_ЗНАКА - число с максимальным значением 65535 и минимальным - 0.
Если задать широту числом 65535 - это будет всё равно что отключить ШИМ и подать логическую единицу на вывод, светодиод будет гореть с максимальной яркостью. Ноль, соответственно, выключит светодиод.
Для этого урока нам понадобится:
Подключение
Подключим Trema-модуль Светодиод согласно таблице
Вывод модуля | Вывод Pi Pico |
---|---|
Vcc | 3V3(OUT) |
GND | GND |
S | GP15 |
Подключим Trema-модуль Кнопку согласно таблице
Вывод модуля | Вывод Pi Pico |
---|---|
Vcc | 3V3(OUT) |
GND | GND |
S | GP2 |
Управляем яркостью
Попробуем создать объект ШИМ и вручную управлять яркостью.
Во вкладке интерактивной оболочки введём:
>>> from machine import Pin, PWM
Затем создадим объект ШИМ:
>>> pwm = PWM(Pin("GP15"))
Зададим широту импульса в 50% (65535/2 ≈ 32000)
>>> pwm.duty_u16(32000)
Установим частоту ШИМ. Начиная с 200 Гц - мерцание будет незаметно для глаза, но мы выберем частоту ещё выше:
>>> pwm.freq(1000)
После последней команды светодиод должен загореться в половину яркости относительно того, если бы мы включили вывод при помощи Pin.on()
Попробуйте управлять яркостью и частотой из оболочки при помощи
команд pwm.freq()
и pwm.duty_u16()
...
Диммер
При нажатии и удержании кнопки светодиод начнёт менять свою яркость. Если отпустить кнопку и зажать снова - направление изменения яркости поменяется (нажали и удерживаем первый раз - светодиод становится ярче, отпустили и нажали снова - светодиод начинает гаснуть).
Обратите внимание на директиву global
в функции
fadeLED()
. Если её не поставить, то переменная будет
локальная для этой функции.
# Подключаем модуль для работы с выводами from machine import Pin, PWM, Timer # Подключаем функцию сна (задержки) from time import sleep # Создаём объект кнопки, передавая в конструктор номер вывода и режим работы button = Pin("GP2", Pin.IN) # Создаём объект ШИМ, передавая в конструктор объект вывода, к которому подключён светодиод led = PWM(Pin("GP15")) # Указываем частоту ШИМ led.freq(1000) # Инициируем ШИМ led.init() # Сохраняем состояние кнопки last_state = button.value() # Указываем среднюю точку ШИМ (для 16-битного ШИМ это примерно 65535/2) duty = 32000 # Создаём переменную направления изменения яркости светодиода direction = True # Функция изменения яркости светодиода def fadeLED(): global duty global direction # True направление - увеличиваем ШИМ if direction: duty += 1000 else: duty -= 1000 # Удерживаем ШИМ на максимальном или минимальном уровне (при переполнении переменной) if duty > 65000: duty = 65000 if duty < 1000: duty = 0 # Устанавливаем ШИМ на выводе светодиода led.duty_u16(duty) # Бесконечный цикл while True: # Записываем состояние кнопки button_state = button.value() # Если состояние изменилось и кнопка зажата - меняем направление диммера if button_state != last_state: last_state = button_state if button_state: direction = not direction # Если кнопка зажата - меняем яркость светодиода if button_state: fadeLED() sleep(.05)
Обсуждение