3.14. Регулирование яркости светодиода с помощью ШИМ¶
На странице Генерация аналогового сигнала с помощью PWM и RC-фильтра использовался RC-фильтр нижних частот для извлечения постоянного напряжения из сигнала ШИМ. Для светодиода фильтр не нужен – усреднение выполняет сам человеческий глаз.
Когда светодиод включается и выключается быстрее примерно 60 Гц, зрительная система перестаёт различать отдельные импульсы и воспринимает постоянную яркость, равную среднему световому потоку. Коэффициент заполнения 50 % воспринимается примерно как половина яркости; 25 % – как четверть; 10 % – как тусклый.
Подключение такое же, как для статичного внешнего светодиода на Вывод GPIO – токоограничивающий резистор последовательно со светодиодом, рассчитанный по правилам из Основы электроники. Изменение только в программе: вывод работает как выход PWM вместо обычного Pin.OUT.
3.14.1. Выбор частоты¶
Для регулирования яркости светодиода частота ШИМ должна лишь преодолеть порог мерцания глаза:
Ниже ~60 Гц глаз видит импульсы напрямую.
Ниже ~200 Гц периферийное зрение и быстрые движения глаз всё ещё могут выявить мерцание.
1 кГц комфортно выше всего этого и является типичным значением по умолчанию.
Для маленького светодиода на GPIO нет значимой верхней границы; что угодно от 1 кГц до 10 кГц ведёт себя для глаза одинаково.
3.14.2. Затухание¶
Цикл нарастания / затухания изменяет коэффициент заполнения от выключенного состояния до полностью включённого и обратно, ненадолго задерживаясь на каждом шаге:
import time
from machine import PWM, Pin
led = PWM(Pin("P7"), freq=1000, duty_u16=0)
while True:
for d in range(0, 65535, 256):
led.duty_u16(d)
time.sleep_ms(5)
for d in range(65535, 0, -256):
led.duty_u16(d)
time.sleep_ms(5)
При ШИМ 1 кГц и шагах по 5 мс глаз видит плавное затухание в обоих направлениях, при этом видимая яркость следует за значением коэффициента заполнения.
Воспринимаемая яркость не строго линейна по коэффициенту заполнения – отклик глаза следует примерно квадратичному или кубическому закону – поэтому линейное изменение duty_u16 не выглядит как линейное изменение яркости. Для перцептивно более плавного затухания изменяйте коэффициент заполнения по кривой.
Удобный приём, работающий только с целыми числами, – изменять 8-битный счётчик и использовать его квадрат в качестве коэффициента заполнения. 255 × 255 = 65025 с точностью до округления соответствует полной шкале, так что развёртка охватывает весь диапазон:
import time
from machine import PWM, Pin
led = PWM(Pin("P7"), freq=1000, duty_u16=0)
while True:
for step in range(256):
led.duty_u16(step * step) # 0..65025, roughly quadratic
time.sleep_ms(5)
for step in range(255, -1, -1):
led.duty_u16(step * step)
time.sleep_ms(5)
Теперь затухание ощущается примерно равномерным по видимой яркости от выключенного состояния до максимума.