Let it Glow: адвент-календарь, день #6 — знакомимся с RGB!

Let it Glow адвент-календарь день 6 — RGB светодиоды

Это день #6 адвент-календаря «Let it Glow»!

Сегодня снова день мигающих огней — пора переходить к многоцветию с адресными RGB-светодиодами! Увесистые светодиоды из сегодняшней коробочки умеют показывать разные цвета в зависимости от кода — это безумно весело!

Нужно уделить особое внимание подключению: у них четыре ножки разной длины, а способ программирования отличается от предыдущих дней. Но сейчас у нас уже шестой день, и вы к этому готовы!

Поехали!


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


Содержимое коробки #6

В этой коробке вы найдёте:

  • 2x RGB-адресных светодиода диаметром 10 мм

  • 6x соединительных провода «папа–папа»

Содержимое адвент-календаря Let it Glow, день 6

Задания дня

Сегодня мы научимся работать с адресными RGB-светодиодами: как их подключать, программировать и отображать разные цвета.

Но сначала поговорим подробнее о том, что это за особые светодиоды…

Что такое адресные RGB-светодиоды

Светодиоды из вашего набора — это адресные светодиоды. Это особый вид светодиодов, внутри каждого из которых спрятаны три маленьких светодиода: один красный, один зелёный и один синий. Мы смешиваем их в коде, чтобы получать самые разные цвета.

Именно поэтому они называются RGB-светодиодами: R — красный (Red), G — зелёный (Green), B — синий (Blue). Мы поговорим об этом подробнее чуть позже.

Внутри каждого светодиода есть крошечный контроллер, который позволяет нам адресоваться (обращаться) к ним по отдельности в коде. Однако из-за этого им нужен микроконтроллер, который будет отдавать команды.

При работе с большим количеством таких светодиодов (или, например, с очень длинными лентами) обычно приходится беспокоиться о внешнем питании, резисторах и прочих техническихтонкостях. Однако при подключении всего двух штук всё это нас не касается. При этом питать их мы будем с другого вывода — VBUS (физический пин 40), поскольку он обеспечивает полные 5 В, которые нужны этим светодиодам, а не 3,3 В, как у пина, который мы использовали раньше с обычными светодиодами.

Собираем схему

Как всегда, убедитесь, что Pico отключён от USB-кабеля, прежде чем работать со схемой.

Подготовка макетной платы

Очистите плату! Сегодня мы начинаем с чистого листа — убираем все компоненты и провода, чтобы ничто не мешало. Сегодняшний день полностью посвящён освоению управления RGB-светодиодами.

Мы также будем использовать соединительные провода из предыдущих дней.

Установка первого светодиода

У каждого RGB-светодиода 4 ножки. Вы заметите, что они разной длины — это сделано специально, чтобы помочь нам их различать.

Вот схема ножек:

Схема ножек RGB светодиода
  • Ножка 1 = 5 В

  • Ножка 2 = Data OUT (самая длинная ножка)

  • Ножка 3 = земля (GND)

  • Ножка 4 = Data IN

Для начала мы установим один светодиод, а второй добавим позже.

Вставьте светодиод в макетную плату так, чтобы ножки шли от 1 до 4 (слева направо). Это может быть немного непросто из-за разной длины ножек — просто не торопитесь и не давите слишком сильно.

Ваша макетная плата должна выглядеть примерно так:

День 6 — один светодиод на макетной плате

Создаём шины питания

Создаём шину 5 В

Перед подключением светодиодов создадим новую шину питания для 5 В (VBUS), так как на Pico только один такой вывод (нам понадобится два подключения к нему, когда мы добавим второй светодиод).

Возьмите провод и вставьте один конец в VBUS на Pico (физический пин 40), а другой — в красную шину питания, как показано на рисунке ниже.

Создаём шину GND

Заодно создадим шину GND. Соедините вывод GND (физический пин 3) с синей шиной. Ваши шины должны выглядеть вот так:

День 6 — шины питания на макетной плате

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

Время подключить наш светодиод:

  • Соедините ножку #1 (крайняя слева) с красной шиной 5 В

  • Ножку #2 не подключайте ни к чему

  • Соедините ножку #3 с шиной GND

  • Соедините ножку #4 с GPIO2 (физический пин 4)

Ваша макетная плата должна выглядеть примерно так:

День 6 — полное подключение первого светодиода

Задание 1: тест одного цвета

Начнём с простого теста, чтобы убедиться, что всё подключено и работает, заодно познакомимся с библиотекой для этих светодиодов. Просто заставим светодиод загореться синим, а затем погаснуть.

Эти светодиоды умеют показывать множество цветов, поскольку являются RGB-светодиодами. Давайте сначала разберёмся с этим…

Что такое RGB?

RGB расшифровывается как R ed (красный), G reen (зелёный), B lue (синий) — это цветовая система, используемая в вычислительной технике для отображения цветов на экране.

Три цвета можно комбинировать, получая огромный диапазон оттенков. В RGB каждый из трёх цветов задаётся значением интенсивности от 0 до 255. Поскольку каждый из трёх цветов имеет 255 возможных значений интенсивности, технически существует 16 777 216 возможных комбинаций цветов (хотя ваши глаза, скорее всего, не заметят разницы между многими из них при работе со светодиодами).

RGB и светодиоды

Как это соотносится с нашим RGB-светодиодом? Как мы уже упоминали, внутри каждого из этих умных светодиодов — три маленьких: один красный, один зелёный и один синий.

Мы отправляем светодиоду код, задающий значение интенсивности RGB для каждого внутреннего светодиода, и тот смешивает и показывает нужный цвет. Круто, правда?!

Мы используем GRB!

Хотя RGB — это общий термин для таких многоцветных светодиодов, они могут выпускаться в разных форматах, и один из них — GRB.

Вы, наверное, уже догадались, что это значит: порядок цветов наших светодиодовG reen (зелёный), R ed (красный), B lue (синий), то есть GRB!

Что это для нас означает? Просто то, что позиции цветов в коде другие. Например, красный цвет, который обычно записывается как 255,0,0 (потому что это чистый R без других цветов), нужно записать, поменяв местами первые два числа:

  • R GB красный — это 255,0,0

  • GRB красный — это 0,255,0

Наши светодиоды тоже немного странные!

Несмотря на то что образцы тестировались перед заказом тысяч этих светодиодов для наших календарей, поставщик, похоже, прислал другие светодиоды, которые ведут себя… ну… иначе!

Они работают в схеме, и мы можем заставить их показывать основные цвета G, R и B как ожидается, однако при попытке задать цветовые коды, использующие несколько светодиодов одновременно, стандартные цвета отображаются некорректно (мы до сих пор ломаем над этим голову!).

Чтобы обойти это, мы протестировали и перечислили цветовые коды для вас в примере кода ниже, так что у вас будет масса цветов для игры — и никакой лишней головной боли!

Код

В нашем примере кода импортируется «neopixel» — это название библиотеки, включённой в MicroPython для управления такими адресными светодиодами.

Чтобы настроить светодиод, мы задаём номер вывода (GPIO2) и количество светодиодов, подключённых к этому выводу — просто 1. Теперь мы можем обращаться к нему через «GRBled» в нашем коде.

Чтобы отправить инструкцию/данные на светодиод, мы используем GRBled .write(). Это важная часть — ничего не произойдёт, пока мы не запишем данные!

В примере ниже мы используем GRBled.fill((0,0,255)) для задания цвета. Числа в круглых скобках — это значение GRB. Мы используем 0,0,255 — это синий на максимальной яркости.

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

  • Попробуйте заменить 255 на 10 — что произойдёт? Яркость должна снизиться

  • Попробуйте задать значение GRB 150,0,0 — что произойдёт? Цвет должен измениться на зелёный примерно средней яркости

# Импорты
import time
from machine import Pin
from neopixel import NeoPixel

# Задаём номер вывода для светодиода (2) и количество светодиодов (1)
GRBled = NeoPixel(Pin(2), 1)

# Заполняем светодиод синим цветом (GRB)
GRBled.fill((0,0,255))

# Записываем данные на светодиод
GRBled.write()

Задание 2: несколько цветов

Покажем несколько приёмов, которые помогут управлять цветами удобнее, а потом перейдём к по-настоящему интересным вещам!

Сейчас в программе GRB-значения задают цвет напрямую, но когда вы будете перечитывать код, будет сложно вспомнить, какой набор чисел за какой цвет отвечает. Лучший способ — создать переменные цвета с понятными именами.

Переменные цвета

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

Мы создадим переменные для множества разных цветов. Затем сможем использовать их в коде, задавая цвет просто по имени переменной, например GRBled.fill((red)).

Всё, что мы делаем здесь — «подставляем» GRB-код цвета из сохранённой переменной. Нам просто нужно создать переменные до того, как мы попытаемся их использовать.

Код

Попробуйте код ниже, а затем измените имя цвета в скобках на один из ваших вариантов. В примере ниже начинаем с „green“:

# Импорты
import time
from machine import Pin
from neopixel import NeoPixel

# Задаём номер вывода для светодиода (2) и количество светодиодов (1)
GRBled = NeoPixel(Pin(2), 1)

# Задаём переменные цветов в формате GRB
white = 240,140,255 #Почти белый!
red = 0,255,0
green = 255,0,0
blue = 0,0,255
yellow = 255,175,150
orange = 238, 223, 105
pink = 150,150,200
purple = 40,100,255
iceblue = 150,25,200
unicorn = 175,150,255
bogey = 215, 100, 0

# Заполняем светодиод переменной цвета
GRBled.fill((green))

# Записываем данные на светодиод
GRBled.write()

Задание 3: смена цветов по циклу

Теперь у нас есть набор цветов, но мы используем их не в полной мере… пока что!

Сделаем всё немного интереснее — создадим цикл, который будет перебирать все цвета по очереди. Мы воспользуемся тем, что уже знаем: списки, цикл while, переменные и функция range!

Мы просто запускаем цикл while, а внутри него — цикл for (помните функцию range из дня #2?).

Цикл for говорит: «для каждого цвета в списке делай следующее». Код внутри этого цикла просто заполняет светодиод каждым цветом из списка по очереди.

Мы используем for colour in colours:, но помните из дня #2, что здесь не важно, что именно написать — можно написать for i in colours:, for c in colours: или даже for teddybear in colours:!

Ладно, скопируйте код ниже и попробуйте. Немного праздничная атмосфера!

# Импорты
import time
from machine import Pin
from neopixel import NeoPixel

# Задаём номер вывода для светодиода (2) и количество светодиодов (1)
GRBled = NeoPixel(Pin(2), 1)

# Задаём переменные цветов в формате GRB
white = 240,140,255 #Почти белый!
red = 0,255,0
green = 255,0,0
blue = 0,0,255
yellow = 255,175,150
orange = 238, 223, 105
pink = 150,150,200
purple = 40,100,255
iceblue = 150,25,200
unicorn = 175,150,255
bogey = 215, 100, 0

# Задаём список цветов
colours = [white, red, green, blue, yellow, orange, pink, purple, iceblue, unicorn, bogey]

while True:

    for colour in colours:

        GRBled.fill((colour))

        GRBled.write()

        time.sleep(0.1)

Задание 4: диапазон значений GRB

Ещё один способ играть с цветом — перебирать значения GRB в цикле. Каждое значение GRB меняется от 0 до 255, и мы можем использовать это в цикле for, чтобы создавать классные эффекты!

Популярный вариант — плавное затухание. Мы можем заставить код перебирать значения от 0 (ВЫКЛ) до 255 (максимальная яркость) с очень коротким временем задержки, создавая эффект плавного нарастания и угасания.

В нашем коде есть цикл for с for i in range(255):, который будет выполняться от 0 до 255 каждый раз при прохождении цикла. Когда он достигнет конца диапазона (255), код выйдет из цикла for, и поскольку всё это находится внутри цикла while True, начнётся снова.

Затем мы используем i как одно из значений цвета GRB, чтобы при задании цвета использовалось это постоянно меняющееся значение. Попробуйте!

# Импорты
import time
from machine import Pin
from neopixel import NeoPixel

# Задаём номер вывода для ленты (2) и количество светодиодов (1)
GRBled = NeoPixel(Pin(2), 1)

while True:

    for i in range(255):

        GRBled.fill((i,0,0))

        GRBled.write()

        time.sleep(0.005)

В обратном направлении!

А что, если мы хотим, чтобы светодиод плавно угасал, а не резко перепрыгивал с 255 обратно на 0?

Нам просто нужно запустить ещё один цикл for после первого, но указать ему перебирать числа в обратном порядке. Помните функцию reversed, которую мы использовали ещё в коробке #2? Мы снова её применяем, и также меняем цвет при угасании, чтобы оно шло от зелёного к красному.

Код цикла for почти идентичен, мы просто меняем первую строку на for i in reversed (range(255)): — вот так:

# Импорты
import time
from machine import Pin
from neopixel import NeoPixel

# Задаём номер вывода для ленты (2) и количество светодиодов (1)
GRBled = NeoPixel(Pin(2), 1)

while True:

    for i in range(255): # Увеличиваем i на 1 каждый цикл, от 0 до 255

        GRBled.fill((i,0,0)) # Используем значение i как G в GRB

        GRBled.write()

        time.sleep(0.005) # Очень короткая задержка

    for i in reversed (range(255)): # Уменьшаем i на 1 каждый цикл, от 255 до 0

        GRBled.fill((0,i,0)) # Используем значение i как R в GRB

        GRBled.write()

        time.sleep(0.005) # Очень короткая задержка

Задание 5: второй светодиод и «передача света»

Теперь, когда вы умеете работать с RGB-светодиодами, подключим второй — чтобы одновременно отображать два цвета (и любую последовательность, которую захотите придумать).

Вставьте второй светодиод в свободное место на макетной плате (желательно рядом с первым, оставив между ними небольшой зазор), а затем подключите его по той же схеме, что описана выше, но с другим выводом GPIO для линии Data IN.

Примечание: мы не будем соединять эти светодиоды в цепочку через ножки Data IN/OUT — у нас их всего два (и эти конкретные светодиоды не очень хорошо дружат с таким подключением).

После добавления и подключения второго светодиода ваша макетная плата должна выглядеть вот так. Мы использовали GPIO5 (физический пин 7) для линии данных:

День 6 — схема с двумя светодиодами

Передача света!

Заставим наши светодиоды передавать свет друг другу! Мы используем код, похожий на предыдущее задание, с несколькими изменениями и доработками.

Во-первых, чтобы использовать оба RGB-светодиода одновременно, нам нужно настроить каждый из них отдельно с разным номером вывода GPIO (как вы это делали ранее с матрицей из светодиодов).

Затем, аналогично работе с матрицей, нам просто нужно обращаться к разным именам светодиодов в коде. Для этого мы используем GRBled1 и GRBled2.

Ещё одно важное отличие: между циклами for мы задаём первому светодиоду цвет 0,0,0, что гасит его. Это создаёт иллюзию того, что свет «перепрыгнул» на второй светодиод.

Скопируйте в Thonny и попробуйте сами:

# Импорты
import time
from machine import Pin
from neopixel import NeoPixel

# Задаём RGB-светодиоды
GRBled1 = NeoPixel(Pin(2), 1)
GRBled2 = NeoPixel(Pin(5), 1)

while True:

    # Первый светодиод плавно загорается
    for i in range(255):

        GRBled1.fill((i,0,0))

        GRBled1.write()

        time.sleep(0.005)

    #Гасим первый светодиод
    GRBled1.fill((0,0,0)) # Все нули = нет света!
    GRBled1.write()

    # Второй светодиод плавно угасает (с использованием reversed)
    for i in reversed (range(255)):

        GRBled2.fill((i,0,0))

        GRBled2.write()

        time.sleep(0.005)

День #6 завершён!

Теперь у вас есть забавные RGB-светодиоды, с которыми можно играть, и множество инструментов, чтобы заставить их мигать и танцевать как угодно. Мы настоятельно рекомендуем просто поиграть, если у вас есть свободное время сегодня вечером — посмотрите, какие последовательности и цветовые паттерны вы сможете придумать.

Об адресных светодиодах ещё есть что рассказать… следите за обновлениями…

Итоги дня — сегодня вы:

  • Узнали о цветовой системе RGB: что она означает и как работает с электроникой и кодом

  • Узнали об RGB-светодиодах (и о том, что некоторые из них — GRB!)

  • Собрали схему с GRB-светодиодами

  • Научились использовать популярную библиотеку «neopixel»

  • Применили навыки из предыдущих дней:

    • Списки

    • Функция range / циклы for

    • Переменные

    • Циклы while

    • Функция reversed

Завтра мы вернёмся к компоненту управления — чему-то такому, что можно использовать в сочетании с нашими мигающими элементами для создания классного проекта. Узнаем, что это такое, уже ранним утром…

Хорошего вечера, увидимся завтра!


Для создания изображений схем подключения использовался Fritzing.