Ambient Light помогает работать ночью. Когда вокруг темно и светит только монитор, то глаза сильно напрягаются. Лично мне приятно работать без верхнего света, и данное решение помогает мне это делать.
Возникла у меня эта идея, когда я переехал на новое место с большим столом. Я вспомнил ролик AlexGyver и решил сделать себе такое же. Но в отличие от Гавера, Я делаю устройство на основе Corsair Lightning Protocol, что позволяет ему быть более универсальным в настройке эффектов и выборе платформы.
Проблемы решения AlexGyver
Только Windows
Трудности с поиском Arduino и его ценой (на момент января 2023)
Нет других эффектов
Проблема решения Giant4 [ссылка удалена мод.]
Только Windows или Android
Нет других эффектов
Есть так же решение с Aliexpress, но они тоже используют проприетарную программу под Windows.
Что такое Ambient Light?
Это динамическая подсветка монитора, которая как бы продолжает его. Светодиоды выводят края экрана тем самым делают иллюзию увеличения размера.
ВАЖНО!
Ambient Light только для компьютера. То есть мы делаем без Hdmi Splitter.
Комплектующие
Выбрал я rpi pico, потому что он был дешевле Arduino (в последствии из за этого нужно было немного помучиться, но все работает). Брал я все в разных магазинах, поэтому посоветовать ничего не могу.
Нам понадобится:
Паяльник
Катушка припоя
Адресная светодиодная лента (зависит от периметра вашего монитора, нужно посчитать рулеткой, мне хватило 4 метра, брал на 5v)
Активный флюс
Штука для чистки флюса (можно взять спирт или ацетон)
300-500 Ом резистор (без него светодиоды будут перегорать)
Блок питания для вашей ленты (лучше брать с запасом, мне хватило 20w)
Коннектор для питания (нужен чтобы поддерживал ваше напряжение)
Красивая коробочка
Клей пистолет, чтобы это все держалось
Провода которые бы выдерживали ваше напряжение (взял 10 метров)
Сама rpi pico
Кабель usb для rpi pico
Макетная плата для пайки
Прямые руки (необязательно)
Цена вышла под 6-8 тысяч рублей, так как многих элементов не было (паяльник, припой и другое для пайки)
Как мы будем выводить с экрана на светодиодную ленту?
Для этого мы воспользуемся Corsair Lightning Protocol, который совместим с множеством программ. Нас интересует OpenRGB (есть на Mac os, Windows, Linux). С помощью нее мы будем и задавать цвета на светодиоды.
ВАЖНО! x2
Я случайно спалил целых 4 светодиода, так как запускал без резистора. Не повторяйте моих ошибок.
Собираем!
Решаем проблему с прошивкой
Есть маленькая особенность. Библиотека FastLed не имеет поддержку процессора rp2040 (rpi pico) в основной ветке. Поэтому нужно ручками скачать неофициальную библиотеку https://github.com/Zitt/FastLED/tree/rp2040
Установка
Ссылка на дополнительный список устройств: https://github.com/earlephilhower/arduino-pico/releases/download/global/package_rp2040_index.json
Прошиваем
Скачиваем arduino ide. Затем ставим драйвера для rpi pico и прошиваем изменяя количество светодиодов и порт ленты.
Прошиваем
Настройка ленты через iCUE
iCUE (программа для управления corsair node) рассчитана на проприетарные ленты, но туда можно добавить свои, что и нужно сделать.
Настройки
OpenRgb и его особенности
В OpenRgb не хватало настроек для достижение эффекта, которого я хотел. Мне также не понравились режимы работы Ambient Light: только среднее значение всего экрана или вывод экрана полностью без сглаживания, из за чего лента резко меняет цвета и глазам становится больно. А еще Ambient Light фотографирует через Qt в 60 кадров в секунду. Из за этого fps экрана проседает в два раза!! Это не дело, и я решил изменить код, который должен был бы решать эти две проблемы.
У OpenRgb также есть api, но он не подходит для потоковой передачи видео. Он очень медленно меняет и имеет большую задержку.
Делаем свой эффект
Для адекватной работы эффекта пришлось изменить часть кода плагина Effects OpenRgb и добавить новый функционал. За два дня я:
Улучшил работу ScreenRecorder
Сделал дополнительное меню с глобальными настройками
Добавил параметр smoothness который отвечает за сглаживание
Сделал функцию SmoothMatrix для работы для матрицы
Код
ScreenRecorder
Изначально в коде Screen Recorder не было instance. Так, при каждом новом эффекте с использованием записи экрана нужно было создавать еще один, тем самым увеличивая нагрузку на компьютер.
ScreenRecorder* ScreenRecorder::Get()
{
if(!instance) // Проверяем что instance еще нет
{
instance = new ScreenRecorder(); // Создаем если нет
}
return instance;
}
Теперь все эффекты могут использовать один экземпляр ScreenRecorder
Глобальные настройки
Для начало нужно сделать в qtcreator эти самые настройки
Так она выглядит в редакторе
За основу я взял уже существующее окно About. Скопировал его и написал свою логику
GlobalSettings::GlobalSettings(QWidget *parent) :
QWidget(parent),
ui(new Ui::GlobalSettings)
{
ui->setupUi(this); // подключаемся к qt
int fpscapture = ScreenRecorder::Get()->GetFpsCapture(); // получаем скорость захвата кадров
ui->fpscapture->setValue(fpscapture); // ставим ползунок на нужное место
}
Код инициализации виджета
void GlobalSettings::on_fpscapture_valueChanged(int value)
{
ScreenRecorder::Get()->SetFpsCapture(value); // устанвлиавем кадры
ui->fpscapture->setValue(value); // меняем значение позунка
}
Код, который при изменении значения ползунка меняет значение скорости захвата кадров
Параметр smoothness
SmoothMatrix
Основной эффект в Ambient я считаю Screen Copy. Поэтому объяснять принцип работы SmoothMatrix я буду на нем.
for(unsigned int h = 0; h < height; h++) // перебираем экран по высоте
{
for(unsigned int w = 0; w < width; w++) // перебираем экран по ширине
{
// получаем цвет пикселя
QColor color = scaled.pixelColor(reverse ? width - w - 1: w, h);
unsigned int led_num = map[h * width + w];
// изменяем цвет на ленте
controller_zone->SetLED(led_num, SmoothMatrix(ColorUtils::fromQColor(color), w, h), Brightness);
}
}
Тут я добавил только использование функции SmoothMatrix
RGBColor Ambient::SmoothMatrix(RGBColor color, int w, int h)
{
if(color != previous[w][h]) // проверяем что цвет не равен предыдущему
{
// QToolTipedSlider не можете перебирать в нецелых числах
// поэтому нам нужно превратить переменную в float
float smoothness_f = smoothness;
// используем интерполяцию
color = ColorUtils::Interpolate(previous[w][h], color, smoothness_f / 1000);
// записываем его как предыдущий цвет
previous[w][h] = color;
}
return color;
}
Сама функция
Результат
Видео с работой
Весь код выложен в открытый доступ. Чтобы установить этот плагин, нужно:
Установить последнюю openrgb версию из pipeline
Скачать плагин из моего репозитория (UPDATE: патч был добавлен в master. Теперь его можно скачать из pipeline плагина)
Импортировать расширение в разделе settings
Инструкция с картинками
Будет ругаться Windows, но только потому, что у софта нет подписи из-за того, что мы используем версию pipeline
Настройки
Для нормальной работы нужно еще скачать плагин для создания матрицы, чтобы экран корректно отображался.
Итог
Я сделал себе подсветку, именно которую я хотел. Мне очень понравилось делать руками и разбираться как в сишном коде, так и в пайке. Для меня это был отличный опыт на новогодние праздники. Я испытывал множество эмоций от этого процесса, когда что то шло не так, когда что то не получалось, но в итоге все заработало!
Эта реализация работает на любой платформе (Windows, Linux, Mac os). Кроме эффекта Ambient Light, можно настроить и другие в плагине Effects.
P.S
Думаю еще рассказать про перерождение моего Openwrt роутера, который я угробил. Для починки мне пришлось подключаться по UART с помощью ???? Flipper Zero и модифицировать прошивку Openwrt.
Комментарии (24)
GennPen
09.04.2023 18:30+1У адресной ленты 5-вольтовая логика, у RP2040 - 3-вольтовая. Поэтому нужен преобразователь уровня, если не хотите сюрпризов с глюками ленты.
user18383 Автор
09.04.2023 18:30Хорошие замечание, лично сам не проверил. Посмотрел datasheet ws2812B где написано, что должно быть от 3.5V до 5.3V. Но логические пины от -0.5V до 0.5V.
Запитка же самой ленты идёт от блока питания на 20w, 5V.
Serge78rus
09.04.2023 18:30+1Но логические пины от -0.5V до 0.5V.
Вообще то там написано не «от -0.5V до 0.5V», а "-0.5~VDD+0.5"
Но пороги надо смотреть не в таблице «Absolute Maximum Ratings», а в таблице «Electrical Characteristics» и еще не забыть про гистерезис. Так что GennPen прав насчет преобразователя уровня.
ПС: роль резистора 0.5 кОм, без которого сгорают светодиоды, не вполне ясна.user18383 Автор
09.04.2023 18:30Резистор нужен чтобы при отключённом питание 5V светодиодная лента не питалась от платы и не сгорела. Поправлюсь в том что у меня не 5V а 4.5V. Поэтому все работает вроде стабильно.
Serge78rus
09.04.2023 18:30+14.5 * 0.7 = 3.15 — так себе запас для 3.3 В логики, да и напряжения 3.3 и 4.5 берутся явно не с прецизионных источников. Но тут уже зависит от подхода: если для себя и по принципу "работает и ладно" — то почему бы и нет.
GennPen
09.04.2023 18:30Это защита не только от пропадания питания на ленту. А еще чтобы защитить выходы МК, если вдруг вход первого светодиода пробьет на землю или питание. Но т.к. используется 5-вольтовое питание, то по уму нужно бы еще стабилитрон на 3.3В поставить. От этого всего обычно избавляет преобразователь уровня.
CyberBot
09.04.2023 18:30Тогда уж лучше установить оптрон PC817
Serge78rus
09.04.2023 18:30Тогда уж лучше что-нибудь вроде 6N135, 6N136, или даже 6N137. PC817 слишком тормозной для таких скоростей.
solfir
09.04.2023 18:30Не нужен, проверено на ESP8266, там тоже3.3 вольта. Питание на матрицу 5 вольт, а уровня логики хватает. Резистор нужен. И в даташите указано, что ток 20мА на светодиод - вранье. 256 светодиодов сжирают чуть больше 2А при белом цвете всех пикселей.
N-Cube
09.04.2023 18:30У вас или слишком тонкие питающие провода до ленты или в самой ленте или слабый источник питания. Обычно визуально видно, что на ленте из 100 светодиодов первые светятся ярче последних, если не подавать питание с обеих сторон (как и указано в спецификации).
solfir
09.04.2023 18:30Провода на момент теста 1.5 кв.мм, источник питания - лабораторный БП до 5А, но столько и не понадобилось. Питание, правда рриходило в центр матрицы, но визуально ничего не заметно.
nafikovr
09.04.2023 18:30+1И в даташите указано, что ток 20мА на светодиод - вранье
в даташите на что?
user18383 Автор
09.04.2023 18:30На чипы ws2812B которые указаны на схеме и использовались в проекте
nafikovr
09.04.2023 18:30Я даташитов на нечто с названием ws2812b видел штук 10. Иногда попадались с указанием тока в пункте "test condition" для светодиодов. Но это маркетинговый ход. Типа при 20мА у нас 600мК, но чип выдает 3мА. В общем типичный китайский даташит, который лучше чем ничего, но не более. Ну и то что вы покупали может быть чем угодно, яркость разных ws2812b встречавшихся мне отличалась чуть ли не на порядки
N-Cube
09.04.2023 18:30Есть ленты с 3.3-5V уровнем сигнала, стоят столько же, преобразователь не нужен при условии достаточно короткого и не слишком тонкого сигнального провода (иначе лучше повышать напряжение до 5V). Я публиковал на хабре статью с примерами.
Arhammon
09.04.2023 18:30+1Как то побаловался Адалайтом, демо ролик конечно выглядит здорово. Но на том чтоб записать видос, как работает деморолик и похвастаться перед друзьями польза этой системы заканчивается.
А вот пяток обычных светодиодов, прицепленных сзади монитора, подключенных в USB через резистор и залитых эпоксилином реально решают задачу комфортного света ночью.
mgis
09.04.2023 18:30-1А надо было всего то не РАБотать ночью. Против биологии не попрешь. Но вам наверное еще предстоит пройти к пониманию этого.
user18383 Автор
09.04.2023 18:30Полностью согласен. Но я больше не про ночь говорил, а про поздний вечер. А ещё люблю закрывать окна и сидеть без освещения).
Klukonin
Судя по видео задержка ощущается как пара сотен мс и для фильмов такое явно не пойдет.
user18383 Автор
Параметр smooth отвечает за сглаживание. Его можно установить на 0 и тогда будет полная копия экрана сразу
UPDATE
Лично я использую тайлинговый менеджер и из за слишком быстрого переключение между экранами у меня и возникла потребность сделать патч для openrgb
Klukonin
Тогда вопрос, зачем перебирать весь экран?
Функциональность подразумевает размытие только на основе окантовки некоторой толщины с целью виртуально "расширить" экран. Обработка всего кадра целиком это не только увеличение нагрузки на CPU, но и ухудшение точности итогового результата.
user18383 Автор
На фоне того сколько qt5 жрет на создание скриншотов, перебор всего экрана становиться пустяком.
Так же openrgb это софт не только для создание ambient light, но и для разных других эффектов. В теории можно собрать полную матрицу светодиодов и использовать для чего нибудь ещё. В этом и прелесть openrgb. В нем куча эффектов, поддерживаемых устройств и плагинов.
Klukonin
Пустяк или нет, но сама логика перебора целого кадра выглядит странно.
А есть более быстрые методы захвата изображения?
user18383 Автор
Да конечно, но они не кроссплатформенные.