LEDraw Project: платформа для светодиодной графики (Гирлянды и всё такое...)

Palpalych

★★★★★✩✩
24 Дек 2019
766
405
данная тема достаточна обширна, и сложно будет её за раз выложить в готовом виде. Подготовка и исправление материалов занимает очень много времени (которого свободного у меня нет в должном количестве), и поэтому прошу модераторов дать мне отсрочку, хотя бы в неделю, для последовательного пополнения. Желательно закрепить еще 2 первых поста для дополнительной сопутствующей информации. Спасибо.
В прошлом я был создателем одной из прошивок Лампы Гайвера и материалы выкладывал на страницах этого форума. В какой-то момент проект был полностью переработан и адаптирован для новых задач, о которых я хотел бы писать на этих страницах. Месяца 2 назад мне потребовалось сделать прошивку для управления светодиодной лентой. Используя старые наработки и желание сделать общий алгоритм работы и управления, полностью переделал код. На данный момент разработка представляет собой управление ёлочной гирляндой (как ни странно Новый Год на носу) - это была моя самая давняя мечта, и я планирую осуществить ее до конца этого года. А так как программа была "поломана", то восстановление функционала Лампы Гайвера на новом "движке" это уже следующий этап. Итак...

LEDraw Project: платформа для светодиодной графики / расширение возможностей FastLED

LEDraw Project - это платформа для светодиодной графики базирующаяся на популярной библиотеке управления адресными светодиодными лентами FastLED. Основное назначение этой платформы, как ни странно, это экономия ресурсов контроллера при повышении качества выводимой "картинки". На данный момент включает в себя набор объектов с оптимизированной структурой для иерархичного доступа к ресурсам котроллера, а также ряд высокопроизводительных графических функций для рисования эффектов. В дополнении, имеется еще ряд полезных и совместимых модулей расширяющих функционал этой платформы, таких как управление кнопкой, полноцветные индикаторы (адресные светодиоды находящиеся в цепочке, но не участвующие в прорисовке основного эффекта, служащие, например, для индикации режима, уровня сигнала и пр.), управление питанием и яркостью...

Примеры реализации проекта LEDraw:
LEDraw stripe - 144LEDs, 1D-graphix, faders, 1D-OSD

LEDraw garland (гирдянда) - 249LEDs, 1D-graphix, faders, 1 inLED-indicator
LEDraw Disco-Lamp - 32LEDs, 1D-graphix, faders, 1 LED-indicator, 1 Aux driver (motor)

Схема подключения:
Base.png
Замечено, что такая схема выдерживает подключение 100-150 стандартных адресных светодиодов без проблем от стандартной USB зарядки на 2А (при условии выставления соответствующего тока в конфигурации)! Резистор 150 Ом желателен, но не обязателен в случае если лента не работает.

Схема подключения дополнительного исполнительного устройства (моторчик, или бэкграунд подсветка):
AuxDrive.png

Рабочие конфигурации:
№9 - полоска из светодиодов ws2012b
№10 - дисколампа на ws2012b
№11 - гирлянда на ws2011

При работе над эффектами было замечено, что многие из них начинали вести себя совершенно другим образом, когда менялось, например, количество светодиодов. Либо появлялась дискретность изображения, либо эффект замедлялся(ускорялся) до нежелательных скоростей, а иногда картинка переворачивалась, и приходилось лезть в код, чтобы разобраться с неведомыми параметрами, чтобы привести все в норму. А иногда эффект сильно тормозил весь процесс, пересчитывая "тяжелые" или излишние кадры. В данной платформе появился некий интерфейс между процедурой отрисовки эффекта и программой управления (менеджером), что позволило сократить количество ресурсов занимаемых у контролера без потери качества самой отрисовки. Более того, повысилась плавность и четкость отрисовки благодаря использованию легких и понятных графических функций (словно как в Бэйсике - Draw, Line, Plot...)

Объекты LEDraw - функционально законченные и оптимизированные модули, позволяющие удобно их использовать в своих разработках. Написаны в виде структур, а не классов, что позволяет более рационально использовать ресурсы контроллеров. В частности, все методы в структурах единожды описываются в памяти при компиляции (являются общими), а не дублируются как в классах без усложнения кода.
Статический объект effect описывает все для необходимого для отображения эффекта.
  • Переменные и свойства:
    • *current - указатель на свойства текущего эффекта
    • uint8_t speed - полное значение регулятора скорости
    • uint8_t scale - полное значение регулятора скорости
    • timer - объект внутреннего счетчика времени. Используется для отсчета скорости смены кадров, или таймер смены эффектов
    • *leds - указатель на массив памяти (светодиоды), с которым работает данный эффект
    • int8_t/int16_t i - универсальная переменная, индекс используемый текущим эффектом для внутренних целей
    • int8_t/int16_t indexes[ ] - универсальная масштабируемая переменная используемая текущим эффектом для внутренних целей
    • CRGB colors[ ] - универсальная масштабируемая переменная используемая текущим эффектом для внутренних целей
    • A, B, C, D - универсальные переменные используемые текущим эффектом для внутренних целей. Каждая занимает всего лишь 4 байта, но может использоваться как 4 однобайтные переменные, 2 - двухбайтные, как 1 четырехбайтная, или быть представлена как RGB цвет
    • rgb16_palette/g_palette - универсальная переменная для описания текущей палитры
  • Методы:
    • bool hasChangedEffect() - возвращает сбрасываемый признак смененного эффекта
    • bool hasChangedParams() - возвращает сбрасываемый признак изменённых параметров Speed, Scale, Bright
    • bool hasChangedSpeed() - возвращает сбрасываемый признак изменённого параметра Speed (Скорость)
    • bool hasChangedScale() - возвращает сбрасываемый признак изменённого параметра Scale (Масштаб)
    • bool set(effect)- устанавливает эффект текущим. Возвращает признак успешного выполнения операции
      • effect - индекс (uint8_t) эффекта из списка effects_array[ ]
    • void setPalette(&palette)- установка текущей (рабочей) палитры эффекта
      • &palette - адрес обычной RGB16(TProgmemRGBPalette16Ptr), или градиентной палитры (TProgmemRGBGradientPalettePtr)
    • bool tick() - прорисовка "кадра" эффекта. Возвращает true, если кадр изменился
    • CRGB ColorFromPalette(index, brightness, blendType) - локальная реализация функции для работы с текущей палитрой
    • void fill_palette(N, startIndex, incIndex, brightness, blendType) - локальная реализация функции для работы с текущей палитрой

  • Переменные и свойства описания эффекта:
    • uint8_t id - индекс текущего эффекта
    • bool *action(&effect)- указатель на процедуру прорисовки кадра. Возвращает признак непустого кадра
      • &effect - ссылка на параметры передаваемые в процедуру эффекта

LEDraw позволяет с легкостью конфигурировать несколько родственных проектов со своими настройками. Осные настройки находятся в файле config.h. Дополнительные кастомные настройки в своем конфигурационном файле находящимся в корне проекта. Смысл заключается в том, что кастомный конфигурационный файл переписывает необходимые установки define под конкретную реализацию проекта.

Первоначально эффекты работали с 8 палитрами, но в процессе адаптации появилась возможность работать с градиентными(!) палитрами, коих в коллекции насчитывается уже 34 шт.

  • Кнопка - Да
  • Демо-режим - Да (в минимальной конфигурации)
  • Индикаторы - Частично
  • Регуляторы (интеллектуальное управление кнопкой + визуализация) - Частично
  • AuxDrive (моторчик, одноцветная LED лента...) - Да
  • Дизеринг - Да
  • Фаворитные списки - Нет
  • Пульт - не отлажен
  • Фэйдеры эффектов - Да
  • Анимационные фэйдеры - Да
  • WiFi - не отлажен
...
Button: --- v.2.0.01γ (01.12.2020)
Алгоритм управления кнопкой

Действие по умолчению (если не выполнено другое):
- / удержание - регулировка глобальной яркости
*- / 1 + удержание - ... скорости эффекта
**- / 2 + удержание - ... масштаба эффекта
***- / 3 + удержание - регулировка яркости эффекта (для проектов с моторчиком - скоростьего вращения)

Из профиля OFF/SLEEP:
* / 1 кратное нажатие - показ часов (если установлена соответствующая настройка, и при работе в режиме клиента). Повторное нажатие во время показа - переход в режим ON
** / 2 кратное нажатие - переход в режим LAMP
*** / 3 кратное нажатие - смена бэкграунда режима OFF
**** / 4 кратное нажатие - переход в режим DEMO
***** / 5 кратное нажатие - вывод интернет имени лампы и текущего IP (если поддерживается)
****** x2 / 6 кратное нажатие - прошивка по OTA (после 2-кратного входа в этот режим. Переключится на эффект Матрица) (если поддерживается)
******* / 7 кратное нажатие - смена режима ESP - точка доступа/клиент (если поддерживается)
******** / 8 кратное нажатие - сброс настроек эффектов

Из профиля ON:
* / 1 кратное нажатие - показ часов (при работе в режиме клиента). Повторное нажатие во время показа - переход в режим OFF
** / 2 кратное нажатие - смена эффекта вперед
*** / 3 кратное нажатие - смена эффекта назад
**** / 4 кратное нажатие - переход в режим PAINT >> ON >> PAINT... (если поддерживается)
***** / 5 кратное нажатие - вывод FPS - количества кадров в секунду (если поддерживается)
******** / 8 кратное нажатие - сброс настроек текущего эффекта

Из профиля LAMP:
* / 1 кратное нажатие - выключение лампы
** / 2 кратное нажатие - переход в режим ON
*** / 3 кратное нажатие - смена эффекта лампы

Из профиля DEMO:
* / 1 кратное нажатие - переход в режим OFF
** / 2 кратное нажатие - переход в режим ON
*** / 3 кратное нажатие - смена режима демо (Последовательное/Случайное/просмотр градиентов)
***** / 5 кратное нажатие - вывод текущего периода смены эффектов (в секундах)
*- / 1 + удержание - ... периода смены эффектов (10сек - 2 минуты)

Режим удержания работает по такому принципу:
Для регулировки соответствующего параметра нужно удерживать кнопку на определенное время, пока не отобразится соответствующий индикатор.
Когда регулируемое значение дойдет до своего минимального значения, то при дальнейшем удерживании кнопки через 1,5с оно будет изменяться в обратную сторону. Если при отпускании кнопки быстро нажать ее повторно, то произойдет вход в предыдущий режим установки.
Если в течении 0,75с произойдет повторное нажатие, то "разворота" приращения регулировки не произойдет, тем самым можно будет легко сделать точную подстройку регулируемого параметра.

Код проекта: (на данный момент доступен как готовое решение для платформы Wemos D1 mini)


= перелопачен принцип управления графикой. Введен новый модель graphix, который объединяет параметры вывода на ленту и быстрые функции прорисовки графики.
Теперь можно определить отдельные пространства на ленте, и с каждым независимо работать не прибегая к чрезмерному описанию параметров.
Доступны такие функции одномерной графики:
- inRange(*) - проверка адреса пикселя на нахождения в своих границах
- wrap(*) - функции "оборачивания" координаты относительно границ
- crop(*) - функции "обрезания" координаты относительно границ
- mirror(*) - функции "отражения" координаты относительно границ
- getPixelValue(*) - функция получения цвета пикселя по его номеру
- getPixelBright(*) - функция получения яркости пикселя по его номеру
- getColor(*) - получение цвета пикселя по его номеру
- blurAll(*) - размытие всего диапазона пикселей
- blend_fast(*) - получение промежуточного цвета относительно двух заданных
- drawPixel() / drawPixel_safe() - прорисовка пикселя (+безопасная)
- dimRange() / dimRange_safe() - затемнение отрезка (+безопасная)
- fillRange() / fillRange_safe() - прорисовка отрезка (+безопасная)
- fillSegment() / fillSegment_safe() - прорисовка отрезка простым градиентом
- noiseAll(*) - заполнение дискретным шумом всего диапазона
- fillAll(*) - заполнить цветом весь диапазон
- dimAll(*) - затемнить весь диапазон
- clearAll(*) - очистить всё
прорисовка графических примитивов (1d):
- drawSparkler(*) - прорисовка "бенгальского огня"
- drawComet(*) - прорисовка кометы

v2.2.15β (30.12.2022) Скачать/Download


Установка:
  • PlatformIO, все как обычно - распаковываем архив в новую папку, открываем, компилируем...
  • Arduino IDE: требуется перенести библиотеки из /lib в C:\Users\*******\Documents\Arduino\libraries. По крайней мере папочку /LEDraw если там уже есть последние GButton и FastLED. Для установки - кликаем файл src\src.ino и только на этой вкладке запускаем сборку.
 
Изменено:

Palpalych

★★★★★✩✩
24 Дек 2019
766
405
Обновил до версии LEDraw 2.2.05 beta (в шапке)
 

veuz

✩✩✩✩✩✩✩
15 Сен 2019
2
0
А можно поподробнее про дисколампу (для не продвинутых :)), что означает одноцветная лента-RGB, не адресная?
А вообще было бы замечательно отдельный скетч и схему подключения .
С уважением , Сергей.
 

Palpalych

★★★★★✩✩
24 Дек 2019
766
405
Избыточное цитирование
Пожалуйста! Хотел написать еще в том году нормальную статью по этому проекту, но не успел. А после НГ уже было не актуально.
Проект собран на основе дешманской китайской лампы о 3-х светодиодах.

IMG_20211205_163315.jpg
Сразу предупреждаю - проект пока представляет макетку и собран на "соплях", опять же китайских.
От донора были взяты корпус, моторчик и призматический купол. Был внедрен кусок адресной светодиодной ленты 144/метр - получилось 32 светодиода. Прилажена кнопка, повышающий модуль 5DС/12DC для питания моторчика (правда, напряжение было повышено до 7Вольт, так как при стандартных 5 моторчик крутился очень вяло), фильтр питания моторчика (банальный встречно-параллельный дроссель о 3-х витках на ферритовом кольце). Драйвер двигателя сделал на микросхеме FAN8082. Основное достоинство - DIP-корпус без обвеса. По идее можно использовать модуль LM298 или аналогичные, но он очень габаритный. По идее, за место моторчика можно использовать кусок одноцветной светодиодной ленты на 12В предварительно настроив в скетче использование драйвера без реверса. Этим хочу сделать дополнительный эффект для новогодней гирлянды подсветке ствола у ёлки... Блок питания - обычная разобранная зарядка для сотового на 5В/2А. На плате Wemos закоротил входной диод чтобы он не просаживал напряжение.

Фото кишок:
IMG_20211205_163500.jpg IMG_20211205_163619.jpg IMG_20211205_163704.jpg IMG_20211205_164002.jpg
Фото в работе:
IMG_20211205_164340.jpg IMG_20211205_164354.jpg IMG_20211205_164359.jpg IMG_20211205_164401.jpg
Схема подключения моторчика
AuxDrive.png
Для большей надежности можно зашунтировать вход и выход дросселя конденсаторами на 0,1мкФ.
контакты моторчика можно перекидывать местами - от этого будет зависеть направление вращения.
Заместо моторчика можно использовать светодиодную ленту на 12В. В таком случае контакт D6 (GPIO12) можно не задействовать, а 5 вывод микросхемы соединить с 1. Соответственно блок фильтра в таком случае не нужен.
Смотрите, чтобы ток не превышал 2A (для модуля MT3608) или 1.6А (для драйвера FAN8082), и по мощности все потребители не превышали мощность блока питания.
Скетч в шапке. Он универсальный. Распиновку пока можно вычитать из конфига.

Видео будет попозже.
 
Изменено:

Palpalych

★★★★★✩✩
24 Дек 2019
766
405
... так же были заказаны такие вот колечки на Али 8, 16, и 24...
1638713675594.png 1638713712157.png
буду пробовать делать вариант дисколампы, но это уже будет в следующем году ))
 

Palpalych

★★★★★✩✩
24 Дек 2019
766
405
Добавил видео с дисколампой

... чуть позже поделюсь еще одной забавной штукой из этого проекта.
 
Изменено:
  • Лойс +1
Реакции: Divin

Palpalych

★★★★★✩✩
24 Дек 2019
766
405
Версия 2.2.07b


v2.2.06β (24.12.2021) - by PalPalych
+ перелопачена библиотека ledraw_indicators теперь есть возможность организовать индикаторную лампочку на самой ленте - удобно, к примеру, в проекте гирлянда, где ао время работы один светодиод выступает в качестве индикатора
+ добавлены 2 палитры
= поправлены режимы регулировок, и смены эффектов (для гирлянд желательно включать режим auxdrive чтобы работать на максимальной яркости)
v2.2.07β (26.12.2021) - by PalPalych
+ добавлен эффект CHINA.PAL - аналог классической китайской гирлянды (4 канала, 8 режимов)
= поправлены тайминги эффекта DEMO
 

RusDyr

✩✩✩✩✩✩✩
29 Дек 2021
2
0
Поменьше сарказма! Человек же для всех старается.
Palpalych, серьёзно, делайте эти вещи в любой системе контроля версий, ну - gitlab, github, sourceforge...
Отдельно отмечу, что выкладывать в 2021 году архив в формате RAR анахронизм и даже издевательство. Вы бы ещё в ARJ выложили (мир его праху). Zip выкладывайте, из коробки есть на винде и в маке.
 

Palpalych

★★★★★✩✩
24 Дек 2019
766
405
@RusDyr, понимаю, но тут более серьезная проблема, чем просто GitHub.
Делаю. проект для себя, как правило в канун нового года в условиях жуткой нехватки времени. Причем начался после перелопачивания лампы Гайвера и написания собственных модулей. А так как модули были разношерстны, то работали только в строго "узкой" конфигурации - чуть тронь, и прошивка либо не собирается или виснет. Поэтому у проекта пока статус Бета, и до полного причесывания до единообразия выкладывать как открытый проект не имеет смысла.
 

RusDyr

✩✩✩✩✩✩✩
29 Дек 2021
2
0
Простите за сарказм.
Слушайте, ну это же совершенно не проблема. Во-первых, вы можете сделать свой git-проект закрытым ото всех.
Во-вторых, даже открытый проект совершенно не означает, что вы его позиционируете как готовый. Возможность любому сразу посмотреть в нём историю изменений, внести свои предложения и комментарии поистине бесценна и обычно очень помогает в разработке.
 

Palpalych

★★★★★✩✩
24 Дек 2019
766
405
@RusDyr, ...да это не сарказм. просто нехватка времени. Тут день остался, потом проект будет опят отложен на год. А вчера столкнулся с проблемой - auxdrive совершенно коряво работает с адресной лентой, если использовать его для подключения на дополнительную светодиодную (я хотел сделать подсвечиваемый ствол елки, или на крайняк вспихивающую звезду на макушку), но этот драйвер только более менее сносно работает на моторчик... Дело в том, что шим у Wemosa программный, и использование команды analogWrite дает артефакты на адресной ленте. (((
Печаль, но пока только архивами... может на праздники оформлю красиво все модули и выложу на Github
 

NARCOZ

✩✩✩✩✩✩✩
1 Янв 2022
2
0
а с чем связана ошибка при компиляции
'button_t' has not been declared
 

Palpalych

★★★★★✩✩
24 Дек 2019
766
405
@NARCOZ, Сейчас сложно сказать - очередной раз разобрал прошивку для перелопачивания, но, попробуй вставить строчку:
extern button_t button;
после
#include "button.h"
в файле button.cpp
 

Lumenjer

★★★✩✩✩✩
10 Дек 2020
220
112
@Palpalych, Скорее всего это не поможет, т.к. не видит декларацию именно структуры, а не объекта структуры.
Под Arduino IDE собирается нормально у меня, под PlatformIO минут 5 по кругу варнинги крутились, надоело ждать)
 

Palpalych

★★★★★✩✩
24 Дек 2019
766
405
@Lumenjer, Да, по незнанию запутал код. Дело в том, что разделяя прошивку под библиотеки намудрил с конфигом, и он каждый раз считывается и обновляется - отсюда и варнинги. В новой прошивке это устранил, но столкнулся с тем что уже прописанные настройки не компилируются в библиотеках... в итоге решил опять переписать библиотеки под новую структуру вызовов. (((
 

Palpalych

★★★★★✩✩
24 Дек 2019
766
405
@Lumenjer, и тут не так все просто - помимо этих настроек меняется определение типа, который зависел от самих этих настроек. А это уже постоянна перекомпиляция библиотеки...
Думал написать ветвление библиотек где этот тип определяется, но так же от этого типа рекурсивно зависят другие библиотеки... ((( - опять засада.
Поэтому пока решил попробовать собрать все графические функции в отдельной структуре (можно и в классе, но не хочу загромождать код)
 

Palpalych

★★★★★✩✩
24 Дек 2019
766
405
Очередная прошивка (пока опять в архиве, но скоро, думаю, выложу на GitHub - тогда она уже обретет более-менее постоянную форсу)
= перелопачен принцип управления графикой. Введен новый модель graphix, который объединяет параметры вывода на ленту и быстрые функции прорисовки графики.
Теперь можно опрелелять отдельные пространства на ленте, и с каждым независимо работать не прибегая к чрезмерному описанию параметров.
Доступны такие функции одномерной графики:
- inRange(*) - проверка адреса пикселя на нахождения в своих границах
- wrap(*) - функции "оборачивания" координаты относительно границ
- crop(*) - функции "обрезания" координаты относительно границ
- mirror(*) - функции "отражения" координаты относительно границ
- getPixelValue(*) - функция получения цвета пикселя по его номеру
- getPixelBright(*) - функция получения яркости пикселя по его номеру
- getColor(*) - получение цвета пикселя по его номеру
- blurAll(*) - размытие всего диапазона пикселей
- blend_fast(*) - получение промежуточного цвета относительно двух заданных
- drawPixel() / drawPixel_safe() - прорисовка пикселя (+безопасная)
- dimRange() / dimRange_safe() - затемнение отрезка (+безопасная)
- fillRange() / fillRange_safe() - прорисовка отрезка (+безопасная)
- fillSegment() / fillSegment_safe() - прорисовка отрезка простым градиентом
- noiseAll(*) - заполнение дискретным шумом всего диапазона
- fillAll(*) - заполнить цветом весь диапазон
- dimAll(*) - затемнить весь диапазон
- clearAll(*) - очистить всё
прорисовка графических примитивов (1d):
- drawSparkler(*) - прорисовка "бенгальского огня"
- drawComet(*) - прорисовка кометы
 

Вложения

Palpalych

★★★★★✩✩
24 Дек 2019
766
405
Скоро Новый Год... и я решил продолжить со своим проектом.
До сих пор он складывается как универсальное решение для всяких там гирлянд, с непревзойденной графикой и управлением одной кнопкой! (Ну кому в голову придет тыкать в праздник в телефон выбирая режимы, когда стынут салаты и водка...)
На данном этапе собрал уже несколько экземпляров. Реализация самая простая - Wemos + кнопка (которая, по сути, тоже не нужна) + лента. Питание осуществляется через плату - через штатный разъем платы. Для питания 150-х светодиодов вполне подходит зарядка для телефона.

На данный момент только причесал последний работоспособный проект. В планах, до НГ дополнить несколькими эффектами и фейдерами.
Да, на данный момент устанавливается только через MSVS Code + PIO. Тестировалась работа только с ESP8266. Важно подключить присутствующие библиотеки в архиве (в частности FastLED). Они содержат вилки.


 

Вложения

Изменено:

Palpalych

★★★★★✩✩
24 Дек 2019
766
405
v2.2.10β (14.12.2022) - by PalPalych
+ введен буфер millis() - однократное обновление за цикл и использование одной переменной = сокращение ресурсов системы
+ введен модуль периодического обновления зерна генератора случайных чисел randomSeed - для увеличения случайности вычислений
+ введен модуль простого таймера / переписаны многие счетчики реального времени на него (заместо конструкции EVERY_N_SECONDS...)
= переделаны команды графики fillRange и fillSegment для более точного и быстрого пересчета
+ введен параметр LEDS_REVERSE для переворачивания эффектов на уровне системы
+ улучшена процедура загрузки
+ сделан модуль команд
 

Вложения

Palpalych

★★★★★✩✩
24 Дек 2019
766
405
Под arduino ide будут новые версии? Собрал прошлую версию, на елке смотрится обалденно!
По идее я изначально под IDE затачивал. Чтобы и там и там компилировалось. Но, глубина реализации проекта привела к тому что в IDE перестало компилироваться ((( Если точно, то const char PROGMEM... если кому получится решить проблему - хорошо, поделитесь плиз решением. Я не совладал. Без этого просто безбожно будет есть память.
А что VS Code не устраивает? Можно одновременно с IDE установить. Одно другому не помешает.