Raspberry Pi Pico: ШИМ (PWM) — плавное затухание светодиода (MicroPython)
Узнайте, как генерировать ШИМ-сигналы (PWM) на Raspberry Pi Pico с использованием прошивки MicroPython. В качестве примера мы покажем, как плавно изменять яркость светодиода, меняя скважность (duty cycle) со временем.
Установка и запуск MicroPython на Raspberry Pi Pico
Для выполнения этого руководства вам необходимо установить прошивку MicroPython на плату Raspberry Pi Pico. Также вам понадобится IDE для написания и загрузки кода на плату.
Рекомендуемая IDE для работы с MicroPython на Raspberry Pi Pico — Thonny IDE. Следуйте следующему руководству, чтобы узнать, как установить Thonny IDE, прошить MicroPython и загрузить код на плату.
Знакомство с ШИМ (широтно-импульсная модуляция)
ШИМ (широтно-импульсная модуляция), или PWM (Pulse Width Modulation), — это метод управления мощностью, подаваемой на устройства. Он работает за счёт очень быстрого включения и выключения питания.
Например, если чередовать напряжение на светодиоде между HIGH и LOW очень быстро, ваши глаза не успеют уловить скорость, с которой светодиод включается и выключается; вы просто увидите различные градации яркости.
Именно так работает ШИМ — генерируя выходной сигнал, который переключается между HIGH и LOW с очень высокой частотой.
Скважность (duty cycle) определяет процент времени, в течение которого питание включено, по сравнению с общим временем цикла включения-выключения — посмотрите на следующую диаграмму.
Регулируя скважность, мы можем управлять средней мощностью, подаваемой на устройство. Например, более высокая скважность означает, что устройство получает больше мощности, а более низкая скважность приводит к уменьшению мощности. Это позволяет нам управлять такими параметрами, как яркость светодиодов, скорость моторов или громкость динамиков.
Например, скважность 50 процентов даёт 50 процентов яркости светодиода, скважность 0 означает, что светодиод полностью выключен, а скважность 100 означает, что светодиод горит на полную мощность. Изменение скважности — это способ получения различных уровней яркости.
GPIO Raspberry Pi Pico
Raspberry Pi Pico имеет 40 выводов, 26 из которых — программируемые GPIO, которые можно использовать для подключения периферийных устройств. Все GPIO Raspberry Pi Pico могут выводить ШИМ-сигналы — они отмечены на диаграммах светло-зелёным цветом.
Вы можете использовать следующие распиновки в качестве справочника для определения и нахождения каждого GPIO на вашей плате. Распиновка немного отличается для Pico и Pico W.
На следующем изображении показана распиновка Raspberry Pi Pico (какие функции поддерживает каждый вывод).
Источник изображения: raspberrypi.com
Выводы, отмеченные красным — это выводы питания, выдающие 3.3 В. Чёрные выводы — это выводы GND. Все выводы, отмеченные светло-зелёным, можно использовать как «обычные» GPIO (вход и выход).
Raspberry Pi Pico — каналы ШИМ
Raspberry Pi Pico имеет 8 независимых ШИМ-генераторов, называемых срезами (slices). Каждый срез имеет два канала, что в сумме даёт 16 каналов ШИМ.
Частота ШИМ-сигнала может варьироваться от 8 Гц до 62,5 МГц, при этом микроконтроллер работает на частоте 125 МГц.
Два канала одного среза работают на одной частоте, но могут иметь разную скважность.
Класс machine.PWM
Для работы с ШИМ-сигналами на Raspberry Pi Pico с использованием MicroPython применяется класс machine.PWM. После создания объекта PWM, например с именем led_pwm:
led_pwm = PWM(Pin(20))
Вы можете использовать следующие методы:
led_pwm.freq(FREQUENCY)— для установки частоты ШИМ-сигнала.led_pwm.duty_u16(DUTY_CYCLE)— для установки скважности. Значение должно быть от 0 до 65535 (16 бит).led_pwm.deinit()— для выключения ШИМ на срезе ШИМ, используемом светодиодом (в данном примере это GPIO 20, поэтому ШИМ также будет остановлен на GPIO 21, так как они принадлежат одному и тому же срезу ШИМ).
Схема подключения
Теперь давайте создадим пример, чтобы лучше понять концепции ШИМ. Мы создадим простой пример плавного затухания светодиода (плавное увеличение и уменьшение яркости).
Перед тем как продолжить, подключите светодиод к Raspberry Pi Pico. Мы подключаем к GPIO 20, но вы можете использовать любой другой GPIO.
Необходимые компоненты
Вот список компонентов, необходимых для сборки схемы:
Raspberry Pi Pico
Светодиод 5 мм
Резистор 330 Ом
Макетная плата
Соединительные провода
Схема — Raspberry Pi Pico
Вы можете использовать следующую диаграмму в качестве справочника для подключения светодиода к плате Raspberry Pi Pico.
Скрипт — плавное затухание светодиода на RPi Pico
Следующий код создаёт ШИМ-сигнал на GPIO 20 и увеличивает и уменьшает скважность со временем для плавного затухания светодиода.
from machine import Pin, PWM
from time import sleep
# Set up PWM Pin
led = machine.Pin(20)
led_pwm = PWM(led)
duty_step = 129 # Step size for changing the duty cycle
#Set PWM frequency
frequency = 5000
led_pwm.freq (frequency)
try:
while True:
# Increase the duty cycle gradually
for duty_cycle in range(0, 65536, duty_step):
led_pwm.duty_u16(duty_cycle)
sleep(0.005)
# Decrease the duty cycle gradually
for duty_cycle in range(65536, 0, -duty_step):
led_pwm.duty_u16(duty_cycle)
sleep(0.005)
except KeyboardInterrupt:
print("Keyboard interrupt")
led_pwm.duty_u16(0)
print(led_pwm)
led_pwm.deinit()
Как работает код
Для создания ШИМ-вывода импортируйте класс PWM в дополнение к классу Pin из модуля machine.
from machine import Pin, PWM
Вам также нужно импортировать функцию sleep из модуля time для добавления задержек в код.
from time import sleep
Сначала создайте объект Pin на GPIO по вашему выбору. В данном случае мы используем GPIO 20.
led = machine.Pin(20)
Затем создайте объект PWM на этом выводе, с именем led_pwm, следующим образом:
led_pwm = PWM(led)
Установите шаг скважности — меньшие значения приводят к более плавным и медленным переходам, а большие значения — к более резким и быстрым изменениям. Мы используем значение 129, потому что это целочисленный делитель числа 65535.
duty_step = 129 # Step size for changing the duty cycle
Примечание
Скважность может принимать значения от 0 до 65535 (16 бит). При этом 65535 соответствует 100% скважности (полная яркость), а 0 соответствует 0% скважности (светодиод выключен).
Установите частоту сигнала. Мы используем частоту 5000 Гц, но вы можете выбрать другое значение. Частота может принимать значения от 0 до 62500.
#Set PWM frequency
frequency = 5000
led_pwm.freq (frequency)
Для установки скважности используйте метод duty_u16() объекта PWM и передайте скважность в качестве аргумента:
led.duty(duty_cycle)
Внутри цикла while мы создаём цикл for, который увеличивает скважность на 129 на каждой итерации с интервалом 5 мс между каждым изменением.
for duty_cycle in range(0, 65536, duty_step):
led_pwm.duty_u16(duty_cycle)
sleep(0.005)
Функция range() имеет следующий синтаксис:
range(start, stop, step)
Start: число, указывающее, с какой позиции начинать. Мы хотим начать со скважности 0;
Stop: число, указывающее, на какой позиции остановиться, не включая это значение. Максимальная скважность — 65535. Поэтому мы используем 65535 + 1, то есть 65536.
Step: целое число, указывающее шаг приращения. По умолчанию приращение равно 1.
В каждом цикле for мы устанавливаем скважность светодиода равной текущему значению duty_cycle:
led_pwm.duty_u16(duty_cycle)
После этого переменная duty_cycle увеличивается на указанный вами шаг.
Когда скважность достигает полной яркости, мы аналогичным образом плавно уменьшаем яркость.
# Decrease the duty cycle gradually
for duty_cycle in range(65536, 0, -duty_step):
led_pwm.duty_u16(duty_cycle)
sleep(0.005)
Обратите внимание, что в этом примере мы используем операторы try и except.
Блок try содержит код, который мы хотим выполнить.
Блок except выполняется, если в блоке try возникает определённая ошибка. В данном случае он перехватывает ошибку KeyboardInterrupt, которая возникает, когда пользователь прерывает программу, нажав Ctrl+C в терминале или остановив программу в IDE. Когда эта ошибка обнаруживается, выполняется код внутри блока except.
В блоке except мы устанавливаем скважность светодиода в 0 (полностью выключен) с помощью led.duty_u16(0) и вызываем led.deinit() для выключения ШИМ.
except KeyboardInterrupt:
print("Keyboard interrupt")
led_pwm.duty_u16(0)
print(led_pwm)
led_pwm.deinit()
Это гарантирует, что светодиод будет правильно выключен и выполнена необходимая очистка, даже если программа была прервана пользователем.
Демонстрация
Сохраните код на плату Raspberry Pi Pico с помощью Thonny IDE или любой другой MicroPython IDE по вашему выбору.
Следуйте приведённым ниже инструкциям, если вы используете Thonny IDE.
Скопируйте предоставленный код в безымянный файл Thonny IDE.
После того как код скопирован в файл, нажмите на иконку Save (Сохранить). Затем выберите Raspberry Pi Pico.
Сохраните файл с именем: main.py. Перезапишите все существующие файлы с таким же именем.
Примечание
Когда вы называете файл main.py, Raspberry Pi Pico будет запускать этот файл автоматически при загрузке. Если вы назовёте его по-другому, он всё равно будет сохранён в файловой системе платы, но не будет запускаться автоматически при загрузке.
Перезагрузите плату (отключите и снова подключите её к компьютеру). Нажмите маленькую зелёную кнопку «Run Current Script» (Запустить текущий скрипт) или нажмите F5.
Обратите внимание, что светодиод, подключённый к GPIO 20, начнёт «дышать» — его яркость будет плавно увеличиваться и уменьшаться со временем.
Вы можете остановить выполнение программы, нажав CTRL + C или нажав кнопку STOP. Обратите внимание, что светодиод выключится, и в терминале будет выведено сообщение.
Заключение
Подведём итог: для вывода ШИМ-сигналов на GPIO Raspberry Pi Pico мы можем использовать класс machine.PWM. Сначала вы создаёте объект PWM на выбранном GPIO. После этого вы можете использовать методы freq(), duty_u16() и deinit() объекта PWM для установки частоты ШИМ, скважности и остановки ШИМ соответственно.