Как управлять адресной светодиодной лентой через компьютер

Обновлено: 02.07.2024


О чем это я и для кого?
Я хочу рассказать как быстро и просто можно оживить ленту на базе "умных" светодиодов типа WS2811(12), SK6812, INK1003 и других без лишних затрат, имея только ардуино, библиотеку Adafruit NeoPixel, кусок ленты и час свободного времени, чтобы получить подобную занятную иллюминацию или что то еще в соответствии с вашей целью. Моя цель — не эта гирлянда или готовый скетч. Весь код в тексте и в прилагаемом скетче служит только для того, чтобы показать возможности сторонней библиотеки от компании Adafruit, накидан на скорую руку, и никак не является образцом для подражания или пособием по программированию. Он всего лишь работает с кусочком ленты и демонстрирует несложные эффекты. Вам не нужно ничего тупо повторять. Считайте это подробным справочником по нескольким функциям NeoPixel с примерами их использования в коде СИ. Посему просьба оставить мокрые тапки для своих котов)
Для кого обзор? Конечно для тех, кто только начинает знакомство со смарт-лентами и имеет представление о том, как работает ардуино и как пишется под него код.

Теперь поехали)
Достаточно популярными "умные ленты" стали уже давно. Среди них существует множество китайских клонов, собранных как на обычных диодах RGB и внешними управляющими регистрами, так и "полноценные", с использованием ws2812 со встроенным в корпус 5050 контроллером. Принцип работы практически одинаков для всех лент и матриц с SPI (последовательным) интерфейсом. Это относится к WS2811(12), SK6812, INK1003 и другим подобным драйверам. На вход первого контроллера ленты передается непрерывный поток данных, в каждом пакете которого содержится 3 или 4 (для RGBW пикселей)байта со значением цвета для каждого из 3 или 4 светодиодов в пикселе. Контроллер первого пикселя "откусывает" себе первые 3(4) байта, устанавливает свой цвет в соответствии с содержимым, а остальной поток пропускает к следующим пикселям, где происходит аналогичное "откусывание" и дальнейшая передача "из рук в руки" до тех пор, пока в потоке не возникнет пауза в 50 мкс, означающая что пора принимать данные с начала)В зависимости от типа контроллера, тактовая частота может составлять 400 или 800 кГц. Это позволяет не видеть глазу переходных процессов при реализации достаточно сложных световых эффектов. В различных контроллерах может быть разной тактовая частота, разное кодирование 0 и 1 Lo-Hi уровнями и наоборот, разное следование цвета в пакете и другие мелочи, значительно усложняющие жизнь нормальным людям при выборе средств реализации задуманной елочной гирлянды или пересвета днища в 14-ке) Ленты могут иметь и 4 вывода — два питающих, один управляющий, и один тактируемый. В моем примере лента имеет три вывода — питание 12В и управление. Так же есть моменты, связанные с питанием ленты — это опять же напряжение — 5 или 12В и ток потребления на метр. Я использовал отдельный блок питания 12В. При этом нужно учитывать, что питание ленты и ардуино никак не должны между собой быть связаны, если у вас разные напряжения питания! Только по общему проводу для передачи данных. С ардуинки нужно подключить вывод GND к минусовому проводу ленты и управляющий пин 6 (или какой назначите) ко входу ленты D in. +12В подается на ленту от своего
источника питания, ардуинка питается от своего (либо от USB).


Капиталисты из Adafruit рекомендуют сигнальный провод подключать через резистор порядка нескольких сот Ом, а на саму ленту перед первым контроллером вешать по питанию электролит 1000-2000uF, но у меня все прекрасно работает и напрямую, и через килоОмный резистор при длине шлейфа около 0,5 метра и без каких либо кондеров на ленте. Все страхи актуальны имхо при гораздо бОльших отрезках ленты, чем мой)
С подключением в общем то ничего хитрого нет. Рассмотрим программную часть.
Для управления ws2812 настоящие true-программисты напишут true-код на ассемблере и прошьют true-контроллер от фирмы майкрочип, но для простых смертных выход тоже есть! Добрые дяди из Adafruit написали замечательную библиотеку, заточенную под ардуино, при помощи которой можно на простом cи из г.на и костылей (как в моем случае) соорудить вполне себе работающий г.но код и не заботиться об организации интерфейса и не заглядывать в даташиты контроллеров лент. Об этом уже позаботились авторы библиотеки и нам не нужно ничего знать, кроме ее функций и конфигурирования двух строк в привычной среде.
Что еще следует понимать — каждый пиксель — это память. И она не бесконечна. Например ардуинка uno R3 потянет не более 500 пикселей.


uint32_t HEX_Math(uint32_t SummColor, uint32_t HEX_R, uint32_t HEX_G, uint32_t HEX_B)
SummColor+=((HEX_R << 16)|(HEX_G << 8)|(HEX_B));
return SummColor;
>

Если мы имели 0x9000FE и 0x03, 0x02, 0x01, функция вернет значение 9302FF.
Следующая "штатная" функция — uint16_t n = strip.numPixels(); — возвращает задекларированное количество пикселей в ленте. Полезна в тех случаях, когда у вас гора кода и своих функций, а применяться код будет к разным лентам с разным количеством пикселей в них. Чтобы не перебивать все в коде, следует заранее использовать в счетчиках этот вызов.
strip.setBrightness(100); — устанавливает яркость всей ленты, вызывается в setup() единожды. В коде использовать нельзя, для этого задавайте параметры яркости значениями RGB. (55,0,0) — тоже красный, но не такой яркий как (255,0,0). Полезность этого для себя нашел в том, что неудобно отлаживать код, когда рядом на столе бьет в глаз в разнобой разный злой колор с уровнями 200-255). А так — установил временно strip.setBrightness(30) и работай себе спокойно. Выше этого значения ни один диод не прыгнет, как бы вы не задавали уровень в коде. Просто все итоговые цвета пикселей будут пропорционально пересчитаны для этого значения, как самого яркого.
Подключение нескольких лент к разным выходам ардуины — тоже не вопрос. Пишем в заголовке еще одну ленту с нужным количеством пикселей и пин управления.
Adafruit_NeoPixel strip_a = Adafruit_NeoPixel(24, 5);
Adafruit_NeoPixel strip_b = Adafruit_NeoPixel(45, 6);

Я этим не пользовался, но сложного в этом ничего не вижу.
Остается файл Adafruit_NeoPixel.h — заголовок библиотеки, но в нем нам искать нечего. Там прописаны конфигурации пинов, смещения цветов для RGB и RGBW, частоты для разных типов лент, объявлены уже рассмотренные нами функции а так же различные типы и константы.
keywords.txt содержит перечень имен функций и констант.
Это собственно все, что нам дает библиотека Adafruit NeoPixel — вполне достаточно для написания чего нибудь светящегося, мерцающего и переливающегося)
Теперь, имея некий "справочник" можно прописать параметры и начать кодить что нибудь свое, родное)

//***********************************************************************************************
void setup() //Это мы уже рассмотрели выше, забежав малость вперед, зато теперь все ясно и понятно —
strip.begin();
strip.show();
strip.setBrightness(55); // Выше писал для чего и как)
// В процессе кодинга-отладки полезными окажутся:
Serial.begin(9600); // Это для вывода значений переменных в порт. Интерфейс тут — "Инструменты" --> "Монитор порта".
// Пишем в коде Serial.print(Count);, ставим код на паузу delay(5000), и 5 секунд зрим значение
// переменной Count и осознаем почему у нас она не считает что либо или считает не так)
randomSeed(analogRead(0)); // инициализация аналогового входа для получения с него псевдослучайных значений.
// Тоже может пригодиться
>
//***********************************************************************************************
void loop() // Здесь непосредственно будет выполняться код и вызываться функции, код которых вы напишите за пределами петли
SetMyColor(0, 0, 155); // Давай покрасим эту ленту в синий цвет) — вызываем функцию 1
delay(3000);
TurnOffSecondPixel(); // И погасим каждый второй) — вызываем функцию 2
delay(3000);
>
//***********************************************************************************************
void SetMyColor(uint8_t r, uint8_t g, uint8_t b) //Тело функции 1
for(uint8_t i=0; i<strip.numPixels(); i++) //В цикле считаем пиксели
strip.setPixelColor(i, r, g, b); //И красим их
strip.show(); //За циклом включаем цвета
>
//***********************************************************************************************
void TurnOffSecondPixel() //Тело функции 2
for(uint8_t i=0; i<strip.numPixels(); i++) //В цикле считаем пиксели
if(i%2)strip.setPixelColor(i, 0, 0, 0); //И тушим каждый второй (0,0,0)
>
strip.show(); //За циклом включаем что осталось
>

//***********************************************************************************************
По ссылке под видео скетч содержит больше десятка функций, реализованных с помощью библиотеки Adafruit NeoPixel. Кроме этого в примерах к библиотеке так же есть несколько интересных реализаций, на основе которых можно строить свои занятные вещи.

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

К таким лентам можно купить источник питания, диммер, диммер с пультом управления. Это позволит вам использовать светодиодную ленту для посветки. Однако если вы захотите запрограммировать алгоритм изменения цвета, или сделать управление из компьютера — то тут начинается разочарование. Вы в продаже не найдете диммеров с управлением через COM-порт или Ethernet.

Я решил эту проблему с помощью Arduino, и хочу поделиться своим вариантом решения с Вами.


Теоретическая часть

Для реализации плавного изменения свечения всех 3 каналов нам потребуется сделать собственный димер. Сделать его очень просто, для этого требуется взять силовые ключи и управлять ими с помощью ШИМ сигнала. Также наш диммер должен быть программируемым и/или управляемым из вне.

В качестве мозгов идеально подходит Arduino. В её программу можно записать любой алгоритм изменения цветов, а также её можно управлять как с помощью модулей Arduino, так и удаленно по Ethernet, Ик-порту, Bluetooth, используя соответствующие модули.

Arduino Leonardo

Для реализации задуманного я выбрал Arduino Leonardo. Она одна из самых дешевых плат Arduino, и она имеет много выводов с поддержкой ШИМ.

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

Однако есть способ проще! Нас выручит модуль Arduino для управления двигателями. Этот модуль имеет все необходимое для нас — на нем установлены мощные ключи на 12В.


Пример такого модуля является «L298N Module Dual H Bridge Stepper Motor Driver Board Modules for Arduino Smart Car FZ0407». Такой модуль основан на микросхеме L298N, которая представляет из себя 2 моста. Однако мостовое включение полезно для двигателя (от этого он может менять направление вращения), а в случае RGB ленты, оно бесполезное.

Мы будем использовать не весь функционал этой микросхемы, а только 3 её нижних ключа, подключив ленту как показано на рисунке.


Практическая часть часть

Для реализации потребуется Arduino Leonardo, Модуль управления двигателями L298N, Источник 12В (для запитки ленты), сама RGB лента, соединительные провода.
Для удобства подключения я еще использовал Fundruino IO Expansion, но он никакой функциональной нагрузки не несет.

Схема подключения показана на рисунке.


Хочу дополнительно описать питание системы. В данной схеме питание подается на модуль управления двигателями, в нем стоит понижающий источник питания на 5В, и эти 5В я подаю на вход Vin питания Arduino. Если разорвать эту связь (естественно земли оставив соединенными), то запитывать Arduino и силовые ключи можно от разных источников питания. Это может быть полезно когда к Arduino много всего подключено, и источник в модуле управления двигателями не справляется (выключается по перегреву).

Управляется RGB лента с помощью команд analogWrite, которая настраивает выход для формирования ШИМ сигнала.

В настоящее время адресные светодиодной ленты (NeoPixel LEDs) на базе светодиодов WS2812 находят широкое применение в различных областях. В данной статье мы рассмотрим подключение подобной ленты к плате Arduino и научимся управлять ею в различных режимах.

Внешний вид адресной светодиодной ленты

Ранее на нашем сайте применение адресной светодиодной ленты (NeoPixel LEDs) рассматривалось в следующих проектах:

Необходимые компоненты

  1. Плата Arduino Uno (купить на AliExpress).
  2. Адресная светодиодная лента (WS2812 RGB LED Ring Module) (купить на AliExpress).
  3. Макетная плата.
  4. Соединительные провода.

Внешний вид необходимых для проекта компонентов
Что такое NeoPixel?

После своего изобретения в 1962 году светодиоды стали неотъемлемой частью нашей жизни. В большинстве электронных проектов используются светодиоды одного цвета, но использование светодиодов разных цветов выглядело настолько привлекательно, что следом за обычными светодиодами появились трехцветные светодиоды (RGB LEDs) – их еще называют полноцветными или многоцветными светодиодами. На нашем сайте можно прочитать статью о подключении подобного светодиода к плате Arduino.

RGB модель цветов

Для управления RGB светодиодом необходимо 3 цифровых контакта микроконтроллера (платы Arduino). То есть, к примеру, если мы хотим управлять 60 RGB светодиодами (причем цвет каждого из них настраивать независимо от других), то нам для этой цели понадобится 180 цифровых контактов. Естественно, подобный подход очень неудобен, поэтому для управления большой совокупностью RGB светодиодов, объединенных, к примеру, в ленту, стали использовать адресацию.

Внутреннее устройство RGB адресного светодиода

Адресуемые (адресные) светодиоды (addressable LEDs) – это новое поколение светодиодов, включающих помимо RGB светодиоды также микросхему (контроллер) управления им. В настоящее время для управления подобными светодиодами наиболее часто используется контроллер WS2812, который позволяет получить доступ к множеству светодиодов с помощью одного цифрового контакта по интерфейсу one wire (1-wire), используя адреса светодиодов.

Схема подключения адресуемых светодиодов

Но в отличие от обычных светодиодов данные светодиоды не включаются просто при подаче на них напряжения, для управления ими необходим микроконтроллер. NeoPixel – это марка (наименование) компании Adafruit для адресуемых светодиодов.

Почему NeoPixel?

Способность управлять отдельно каждым светодиодом в адресной светодиодной ленте дает вам возможность создать уникальные визуальный эффекты для своих проектов. Но помните о том, что если вам требуются очень высокие скорости переключения светодиодов, то использование подобной адресной светодиодной ленты нежелательно. Еще одним достоинством адресной светодиодной ленты NeoPixel является ее низкая цена по сравнению с другими типами адресуемых светодиодов. Светодиоды NeoPixel доступны в форме колец, лент, прямоугольников и поверхностей круглой формы – вы можете выбрать любой ее тип для своих проектов.

Внешний вид RGB модуля круглой формы

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

Схема проекта

Схема подключения адресной светодиодной ленты WS2812 к плате Arduino представлена на следующем рисунке.

Схема подключения адресной светодиодной ленты WS2812 к плате Arduino

Резистор в схеме необходим для защиты от повреждений светодиодов NeoPixel и для корректной передачи данных. Наилучшее расстояние для связи между модулем светодиодов NeoPixel и микроконтроллерной платой составляет от 1 до 2 метров.

Примечание : если вы используете адресную светодиодную ленту с большим количеством светодиодов, то в этом случае рекомендуется подключать конденсатор большой емкости (приблизительно 1000 мкФ) параллельно + и – источника питающего напряжения.

Объяснение программы Arduino для работы с адресной светодиодной лентой

Прежде чем начинать работу с адресной светодиодной лентой в Arduino необходимо скачать и установить библиотеку для нее - NeoPixel Adafruit library.

Инструкция по подключению Arduino к адресной светодиодной ленте

На сегодня это наша третья статья. В прошлых статьях мы уже разобрали, что из себя представляет адресная лента и примерно поняли, как она устроена. А также поговорили о плате Arduino Nano , по средствам которой мы буем управлять лентой, установили необходимое программное обеспечения и даже написали свою первую программу. Теперь же пришло время подключить все вместе и сделать простую световую анимацию.

Для начала необходимо разобраться с потреблением светодиодной ленты. Дело в том, что каждый светодиод в пикселе потребляет до 20 мА, в зависимости от яркости его свечения. Напомню, что яркость свечения задаем мы сами из программы. Итого получается, что каждый пиксель может потреблять до 60 мА. Это довольно много, если учитывать, что мы можем использовать несколько метров ленты. Но в рамках данной статьи я буду экспериментировать с отрезком на 5 пикселей. И по этой причине запитаю адресную ленту прямо от Arduino Nano . Хотя я бы сам не рекомендовал так делать, лучше всего ставить отдельный блок питания и подключить ленту к нему, а с МК реализовать только управление.

Как мы помним из прошлых статей, управление будет осуществлено любым из цифровых выходов с D 2 по D 13. В данном случае я решил использовать D 5 (просто для примера, Вы можете использовать любой). Итак, подключаем ленту к Arduino Nano . GND к GND , +5 V к +5 V и D - input к D 5 на плате Nano . Я не стал ничего придумывать и просто припаял. Визуально выглядит адресная лента подключенная к Ардуино:

3_01.JPG

А вот схема подключения адресной ленты к Arduino:

3_01_02.jpg

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

Следующим действием предлагаю подключить плату Адруино к компьютеру и уже заняться написанием нашей первой программы под адресную светодиодную ленту.

3_02.JPG

Пишем программу для управления адресной светодиодной лентой через Arduino. Установка библиотеки

Первый раз – это всегда очень волнительно. В первый раз можно наделать кучу ошибок, причем в последствии понимаешь, что данные ошибки и нарочно придумать сложно, не то, чтобы их случайно допустить, и это касается не только программирования. Но для того я и пишу данную статью, чтобы максимально облегчить путь от идеи до результата. Сейчас я достаточно подробно опишу все, что буду делать. Это поможет сформировать в голове новичка четкое представление о подключении Arduino.

Для начала давайте откроем IDE Arduino . Это программа, которую мы установили в одной из прошлых статей.

3_03.PNG

Получилось? Отлично! Далее нам необходимо установить библиотеку. Это нужно, чтобы управлять адресной лентой. Дело в том, что лента принимает определенный набор команд, но нам, как молодым разработчикам, пока не интересно, что это за команды и как они устроены. Мы просто хотим управлять цветами. И библиотека управления адресной лентой поможет нам сделать это максимально просто и быстро. Мы будем сообщать программе, где какой цвет хотим видеть, а программа, с помощью библиотеки, будет формировать наборы команд, понятные для микросхем адресной ленты. На самом деле все достаточно просто и очевидно, нужно только привыкнуть. Поэтому нажимаем «Скетч» -> «Подключить библиотеку» - > «Управлять библиотеками».

3_04.jpg

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

3_05.PNG

На данный момент мы будем использовать библиотеку « Adafruit NeoPixel ». Проще всего будет воспользоваться поиском. Как видно, в списке есть похожие название, нужно быть внимательным и не перепутать.

3_06.jpg

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

3_07.jpg

Пишем программу для управления лентой через Ардуино

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

3_08.PNG

Adafruit_NeoPixel strip = Adafruit_NeoPixel(LED_COUNT, LED_PIN, NEO_GRB + NEO_KHZ800);

strip.begin(); //Инициализируем ленту.

for (int i = 0; i < LED_COUNT; i++)

strip.setPixelColor(i, strip.Color(255, 0, 0)); // Красный цвет.

for (int i = 0; i < LED_COUNT; i++)

strip.setPixelColor(i, strip.Color(0, 0, 0)); // null

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

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

Обратите внимание: речь идет именно о количестве пикселей, то есть чипов в ленте, а не о количестве светодиодов. В некоторых адресных лентах, например с чипом ws2811 и ws2818 управление происходит кратно 3 диодам, поэтому лента с 60 диодами на метр будет управляться всего 20 пикселями. Если у вас адресная лента ws2812b, ws2813 или ws2815, то управление происходит кратно одному диоду, то есть количество пикселей = количество светодиодов.

В пятой строке мы объявляем экземпляр класса Adafruit_NeoPixel и передаем его конструктору значения о длине ленты, выводе управления и типу адресной ленты. В данной статье мы не будем разбирать само понятие классов, поэтому предлагаю просто принять данную строчку как должное, где в скобках мы передаем необходимые параметры. Скажу только одно: тут мы создали объект под именем « strip ». И этот объект полностью отвечает за работу подключенной ленты.

В теле функции setup () мы сообщаем компилятору, что данный объект « strip » у нас будет использован. По сути, эту команду инициализации пока тоже нужно принять как необходимый минимум.

А дальше у нас уже идет самое интересное - основная часть программы, в которой и происходит волшебство, она находится в теле функции loop (). Но перед этим необходимо ввести новое понятие – цикл.

Цикл — это определенный блок программы, выполняющийся по кругу. Даже сама функция loop () является циклом. Циклы бывают конечными и бесконечными и у циклов так же, как и у функций, есть тело, где написаны повторяющиеся команды. В данной программе мы использовали цикл – for . Если данный цикл описан правильно, то он, как правило, конечен. Цикл for имеет 3 параметра «for(int i = 0; i < LED_COUNT; i++)< >». Первый параметр задает начальное значение для переменной i . Кстати, в данном случае переменная i инициализируется при начале работы цикла и забывается при окончании работы цикла. Второй параметр – это условие, при котором цикл продолжает выполняться. В нашем случае цикл выполняется до тех пор, пока i меньше 5. И третий параметр прибавляет единицу к i , при каждом повторе цикла. Сейчас ограничимся этим коротким объяснением. В дальнейшем у меня выйдет короткая статья, посвящённая программированию.

Итак, вернемся к программе. С 13-ой по 17-ую строку у нас расположен цикл, цикл на 5 повторений, где i меняется от 0 до 4 включительно.

В 14-ой строке мы вызываем метод setPixel , объекта strip и передаем ему два параметра. Где i это номер пикселя на адресной ленте, а « s trip.Color(255, 0, 0)» его цвет. Про то, как задается цвет по системе RGB мы уже говорили ранее. Скажу только очевидную вещь, «255, 0, 0» - это максимально красный цвет.

Получается, когда мы объявили объект strip и передали ему, что в нашей адресной ленте будет 5 пикселей, то в памяти было зарезервировано 5 ячеек, предназначенные для хранения цвета. И теперь в данном цикле мы их заполняем.

В 15-ой строке расположена команда, которая выводит на ленту цвета из памяти в МК (микроконтроллер). То есть последовательность такая: сначала пишем цвета в память, потом разом выводим их на адресную ленту. Изначально пока мы еще не успели заполнить память, там хранятся нулевые цвета «0, 0, 0».

И в 16-ой строке у нас стоит задержка в 300 млс.

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

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

В данной статье мы написали свою первую программу для управления адресной лентой. Теперь Вы сами можете повторить это. Также Вы можете использовать не только красный цвет, но и самостоятельно поэкспериментировать с палитрой и более сложными цветами. А уже в следующих статьях мы постепенно усложним задачу.

Читайте также: