Raspberry Pi: ШИМ-выходы с Python (плавное затухание светодиода)

В этом руководстве вы узнаете, как генерировать ШИМ-сигналы (PWM) на GPIO Raspberry Pi. В качестве примера мы покажем, как плавно изменять яркость светодиода, меняя коэффициент заполнения с течением времени. Генерация ШИМ-сигналов также полезна для управления другими периферийными устройствами, такими как сервоприводы.

Raspberry Pi ШИМ-выходы с Python — плавное затухание светодиода

Содержание

В ходе этого руководства мы рассмотрим следующие основные темы:

  1. Знакомство с GPIO Raspberry Pi

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

  3. Сборка схемы

  4. `Затухание светодиода с Raspberry Pi с использованием ШИМ`_

Предварительные требования

Прежде чем продолжить работу с этим руководством, ознакомьтесь со следующими предварительными требованиями.

  1. Ознакомьтесь с платой Raspberry Pi — если вы ещё не знакомы с Raspberry Pi, вы можете прочитать наше :doc:`Руководство по началу работы с Raspberry Pi </raspberry/rnt/getting-started-with-raspberry-pi/index>`_.

  2. Вы должны знать, как запускать и создавать файлы Python на Raspberry Pi. Нам нравится программировать Raspberry Pi через SSH с помощью расширения в VS Code. У нас есть подробное руководство на эту тему: :doc:`Программирование Raspberry Pi удалённо с помощью VS Code (Remote-SSH) </raspberry/rnt/raspberry-pi-remote-ssh-vs-code/index>`_.

Впервые управляете выходами Raspberry Pi? Начните с :doc:`управления цифровыми выходами Raspberry Pi </raspberry/rnt/raspberry-pi-digital-outputs-python/index>`_.

Знакомство с GPIO Raspberry Pi

GPIO расшифровывается как General Purpose Input Output (контакты общего назначения ввода-вывода), и они позволяют подключать и управлять электронным оборудованием, таким как светодиоды, моторы и датчики, к вашему Raspberry Pi.

Большинство моделей плат Raspberry Pi имеют двойной ряд из 40 контактов GPIO. Расположение контактов обычно одинаковое для большинства моделей Raspberry Pi.

Распиновка Raspberry Pi

Распиновка Raspberry Pi

Существует два разных способа обращения к контакту GPIO: его имя (которое известно как нумерация GPIO или нумерация Broadcom) или соответствующий физический номер контакта (который соответствует физическому расположению контакта на гребёнке).

Например, GPIO 25 соответствует контакту 22 (см. изображение выше). В этом руководстве мы будем обращаться к контактам GPIO по их нумерации GPIO (нумерация Broadcom).

Чтобы узнать больше о GPIO Raspberry Pi, ознакомьтесь с руководством по распиновке Raspberry Pi: :doc:`Руководство по распиновке Raspberry Pi: Как использовать GPIO Raspberry Pi? </raspberry/rnt/raspberry-pi-pinout-gpios/index>`_

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

GPIO Raspberry Pi можно настроить для вывода 0В или 3.3В (:doc:`ознакомьтесь с этим руководством по цифровым выходам Raspberry Pi </raspberry/rnt/raspberry-pi-digital-outputs-python/index>`_), но они не могут выводить промежуточные напряжения. Однако вы можете выводить «фальшивые» промежуточные уровни напряжения с помощью широтно-импульсной модуляции (ШИМ, PWM), и именно так вы будете получать различные уровни яркости светодиода в этом проекте. ШИМ также полезна для других применений, таких как изменение скорости двигателей постоянного тока, установка положения сервопривода и многого другого.

Если вы чередуете напряжение светодиода между HIGH и LOW очень быстро, ваши глаза не успевают за скоростью, с которой светодиод включается и выключается; вы просто увидите некоторые градации яркости.

Затухание светодиода с помощью широтно-импульсной модуляции (ШИМ)

Так в основном и работает ШИМ — создавая выходной сигнал, который переключается между HIGH и LOW с очень высокой частотой.

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

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

Как работает ШИМ

Коэффициент заполнения 50 процентов даёт 50 процентов яркости светодиода, коэффициент заполнения 0 означает, что светодиод полностью выключен, а коэффициент заполнения 100 означает, что светодиод полностью включён. Изменение коэффициента заполнения — это то, как вы получаете различные уровни яркости.

ШИМ-контакты на Raspberry Pi

Raspberry Pi имеет 4 аппаратных ШИМ-контакта: GPIO 12, GPIO 13, GPIO 18, GPIO 19.

Вы можете использовать программный ШИМ на всех контактах. Вы можете выбрать практически любой контакт (кроме GPIO 0 и 1) для вывода ШИМ-сигналов.

Сборка схемы

Подключите светодиод к одному из GPIO Raspberry Pi. Мы подключим один светодиод к GPIO 14 (контакт 8). Вы можете использовать любые другие контакты, кроме GPIO 0 и GPIO 1.

Вот список необходимых компонентов:

Вы можете использовать ссылки выше или перейти непосредственно на MakerAdvisor.com/tools чтобы найти все детали для ваших проектов по лучшей цене!

Светодиод, подключённый к GPIO14 Raspberry Pi — схема соединений

Затухание светодиода с Python на Raspberry Pi

Библиотека gpiozero предоставляет набор интерфейсов для повседневных компонентов, таких как светодиоды, кнопки, потенциометры, датчики и многое другое.

Поэтому, вместо того чтобы настраивать свойства GPIO для затухания светодиода, gpiozero предоставляет интерфейс под названием PWMLED с методами, которые полезны для управления светодиодами, включая метод для генерации ШИМ-сигналов для изменения яркости светодиода.

Кроме того, вы можете использовать интерфейс PWMOutputDevice, который может использоваться для управления другими цифровыми выходами с ШИМ. Давайте посмотрим, как это работает.

Библиотека gpiozero уже должна быть установлена, если вы используете Raspberry Pi OS — если нет, вы можете выполнить:

python3 -m pip install gpiozero

Python-скрипт — ШИМ на GPIO Raspberry Pi

Создайте новый файл Python на вашем Raspberry Pi с именем fade_led.py и скопируйте следующий код.

# Полное описание проекта: https://RandomNerdTutorials.com/raspberry-pi-pwm-python/

from gpiozero import PWMLED
from time import sleep

led = PWMLED(14)

led.value = 1   #LED fully on
sleep(1)
led.value = 0.5  #LED half-brightness
sleep(1)
led.value = 0    #LED fully off
sleep(1)

try:
  # fade in and out forever
  while True:
    #fade in
    for duty_cycle in range(0, 100, 1):
      led.value = duty_cycle/100.0
      sleep(0.05)

    #fade out
    for duty_cycle in range(100, 0, -1):
      led.value = duty_cycle/100.0
      sleep(0.05)

except KeyboardInterrupt:
  print("Stop the program and turning off the LED")
  led.value = 0
  pass

Посмотреть исходный код

Как работает код

Продолжайте читать, чтобы узнать, как работает код.

Импорт библиотек

Сначала вы импортируете компонент PWMLED из библиотеки gpiozero для управления GPIO, к которому подключён светодиод. Затем вам также нужно импортировать функцию sleep() из модуля time для создания задержек в коде.

from gpiozero import LED
from time import sleep

Вместо компонента PWMLED вы можете использовать компонент PWMOutputDevice, который работает точно так же.

from gpiozero import PWMOutputDevice

Объявление ШИМ-светодиода

Далее вы создаёте объект PWMLED с именем led, который ссылается на GPIO 14 — тот самый GPIO, к которому подключён светодиод. Измените номер, если вы используете другой GPIO.

led = LED(14)

Когда вы создаёте и используете этот объект PWMLED, ваша программа знает, что GPIO 14 является ШИМ-выходом, который может генерировать ШИМ-сигналы с различными значениями коэффициента заполнения. После этого объявления вы можете использовать led для обращения к вашему GPIO 14.

Примечание: если вы хотите использовать вместо этого компонент PWMOutputDevice, объявление будет следующим:

led = PWMOutputDevice(14)

Примечание: если вы хотите использовать ШИМ-сигналы для управления двигателями постоянного тока и сервоприводами, gpiozero предоставляет классы Motor, Servo и AngularServo.

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

Вы можете назначить определённый уровень яркости светодиоду, установив определённое число в свойство value следующим образом:

led.value = 1   #LED fully on

Установка led.value в 1 соответствует 100% коэффициенту заполнения, и поэтому светодиод будет полностью включён.

Чтобы полностью выключить светодиод, установите значение 0 (0% коэффициент заполнения).

led.value = 0    #LED fully off

Для различных уровней коэффициента заполнения и, соответственно, различных уровней яркости, установите значение между 0 и 1.

led.value = 0.5  #LED half-brightness

Плавное включение светодиода

Затем код входит в цикл, в котором он постепенно увеличивает коэффициент заполнения от 0% до 100% с шагом 1% с задержкой 0.05 секунд между каждым шагом. Это заставляет светодиод плавно включаться.

for duty_cycle in range(0, 100, 1):
      led.value = duty_cycle/100.0
      sleep(0.05)

Функция range() принимает только целые числа, поэтому мы делим переменную duty_cycle на 100, чтобы получить значение от 0 до 1.

Функция range(start, stop, increment) в Python генерирует последовательность чисел. Она принимает в качестве аргументов следующее:

  • start: начальное значение последовательности (включительно)

  • stop: последнее значение последовательности (не включительно)

  • step: приращение между каждым значением, по умолчанию равно 1

Плавное выключение светодиода

Мы делаем то же самое для плавного выключения светодиода, но меняем аргументы функции range() так, чтобы она начинала со 100 и уменьшала коэффициент заполнения на 1 в каждом цикле.

#fade out
for duty_cycle in range(100, 0, -1):
  led.value = duty_cycle/100.0
  sleep(0.05)

Try и Except с прерыванием клавиатуры

Чтобы предотвратить ситуацию, когда светодиод остаётся включённым при остановке выполнения программы, мы добавили оператор Try и Except. Это перехватит исключение KeyboardInterrupt, которое возникает при нажатии Ctrl + C для остановки программы. Когда это происходит, мы выключаем светодиод перед выходом из программы.

except KeyboardInterrupt:
  print("Stop the program and turning off the LED")
  led.value = 0
  pass

Итого…

1) Для вывода ШИМ-сигналов на GPIO Raspberry Pi вы можете использовать интерфейс PWMLED или PWMOutputDevice библиотеки gpiozero. Сначала вам нужно импортировать его следующим образом:

from gpiozero import PWMLED

или так:

from gpiozero import PWMOutputDevice

2) Определите GPIO, которым вы хотите управлять. С помощью интерфейса LED:

led = PWMLED(GPIO_NUMBER_OF_YOUR_CHOICE)

Или если вы используете интерфейс DigitalOutputDevice:

led = PWMOutputDevice(GPIO_NUMBER_OF_YOUR_CHOICE)

3) Установите коэффициент заполнения (измените яркость светодиода) с помощью свойства value:

led.value = 1   #LED fully on
led.value = 0.5  #LED half-brightness
led.value = 0    #LED fully off

Демонстрация

Сохраните ваш файл Python. Затем запустите его на вашем Raspberry Pi. Выполните следующую команду в каталоге вашего файла проекта (используйте имя вашего файла):

python fade_led.py

Светодиод, подключённый к GPIO 14, сначала включится, затем будет светить с 50% яркости, а затем выключится.

Наконец, он начнёт плавно включаться и выключаться непрерывно, пока вы не остановите выполнение программы.

Raspberry Pi — светодиод с низкой яркостью Raspberry Pi — светодиод с половинной яркостью Raspberry Pi — светодиод с полной яркостью

Мы добавили условие, что при остановке программы светодиод выключается.

Вы можете остановить выполнение программы, нажав CTRL + C. Обратите внимание, что светодиод выключится, и в терминале будет выведено сообщение.

Универсальное ШИМ-устройство вывода

Если вы используете универсальное ШИМ-устройство вывода, вот пример с использованием класса PWMOutputDevice.

# Полное описание проекта: https://RandomNerdTutorials.com/raspberry-pi-pwm-python/

from gpiozero import PWMOutputDevice
from time import sleep

led = PWMOutputDevice(14)

led.value = 1   #LED fully on
sleep(1)
led.value = 0.5  #LED half-brightness
sleep(1)
led.value = 0    #LED fully off
sleep(1)

try:
  # Fade in and out forever
  while True:
    #fade in
    for duty_cycle in range(0, 100, 1):
      led.value = duty_cycle/100.0
      sleep(0.05)

    #fade out
    for duty_cycle in range(100, 0, -1):
      led.value = duty_cycle/100.0
      sleep(0.05)

except KeyboardInterrupt:
  print("Stop the program and turning off the LED")
  led.value = 0
  pass

Посмотреть исходный код

Другие полезные методы

Интерфейсы PWMLED и DigitalOutputDevice предоставляют другие полезные дополнительные методы.

pulse()

Метод pulse() плавно включает и выключает светодиод многократно. Вот пример использования метода pulse().

# Полное описание проекта: https://RandomNerdTutorials.com/raspberry-pi-pwm-python/

from gpiozero import PWMLED
from signal import pause

led = PWMLED(14)

# pulse an LED forever
led.pulse()
pause()

Посмотреть исходный код

Вы можете передать следующие параметры в метод pulse():

pulse(fade_in_time=1, fade_out_time=1, n=None, background=True)
  • fade_in_time: количество секунд для плавного включения. По умолчанию — одна секунда.

  • fade_out_time: количество секунд для плавного выключения. По умолчанию — одна секунда.

  • n: количество циклов пульсации. Установите None для бесконечного выполнения. None — значение по умолчанию.

  • background: если True (по умолчанию), запускает фоновый поток для продолжения пульсации и немедленно возвращает управление.

Заключение

В этом руководстве вы узнали, как выводить ШИМ-сигналы на GPIO Raspberry Pi с помощью интерфейсов PWMLED и PWMOutputDevice библиотеки gpiozero. Мы также рассмотрели три различных способа плавного включения и выключения светодиода.

Мы надеемся, что это руководство было вам полезно. Если вы новичок в Raspberry Pi, мы уверены, что следующие руководства будут вам полезны:

Вы можете ознакомиться со всеми нашими проектами для Raspberry Pi по следующей ссылке:

Спасибо за чтение.