Подсветка монитора на arduino

DIY: Универсальный Ambilight для домашней мультимедиа системы — Атмосвет

Для своей первой статьи я выбрал одну из самых успешных своих поделок: HDMI-passthrough аналог Ambilight от Philips, далее я будут называть эту композицию «Атмосвет».

Введение

В интернетах не очень сложно найти готовые/открытые решения и статьи как сделать Амбилайт для монитора/телевизора, если ты выводишь картинку с ПК. Но в моей мультимедиа системе вывод картинки на телевизор c ПК занимает только 5% времени использования, большее кол-во времени я играю с игровых консолей, а значит нужно было придумать что-то свое.

Исходные данные:
  • 60″ Плазменный телевизор
  • HTPC на базе Asrock Vision 3D 137B
  • Xbox 360
  • PS3
  • PS4
  • WiiU
Требование:

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

Реализация

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

Единственный нюанс:
Я заметил, что внизу экрана идут странные мерцания, сначала погрешил на сигнал, перековырял дефликер, изменил ресазинг картинки и еще кучу всего перекопал, стало лучше, но от мерцания не помогло. Стал наблюдать. Оказалось, что мерцание было только в конце ленты и то при ярких сценах. Взяв мультиметр, я замерил напряжение на начале, середине и конце ленты и угадал с причиной мерцаний: в начале ленты было 4.9В( да китайский БП дает напряжение с отклонением, это не существенно), в середине 4.5 в конце 4.22 — Падение напряжение слишком существенно, пришлось решить проблему просто — к середине ленты я подвел питание от бп, провод пустил за телевизором. Помогло мгновенно, какие либо мерцания прекратились вообще.

Захватываем картинку вебкамерой

image

Первая тестовая версия для обкатки идеи и её визуализации была выбрана через захват картинки через вебкамеру) выглядело это как-то так:

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

Захват картинки через HDMI
  • Сигнал со всех устройств подается на 5in-1out HDMI свитч, который поддерживает HDCP
  • Выходной сигнал подается на 1in-2out HDMI splitter, который мало того, что поддерживает HDCP, так еще отключайте его на выходе(слава китайцам).
  • Один из выходных сигналов идет на телевизор
  • Другой выходной сигнал идет на HDMI to AV конвертер
  • S-Video сигнал идет на коробочку захвата от ICONBIT
  • Коробочка захвата подключается к вечно работающему HTCP по USB, который подключен к Arduino контроллеру ленте на телевизоре.
  • Это работает.
  • Сумарно все это дело, заказывая из китая, мне обошлось тысяч в 3-4 тыс. рублей.

Почему я не использовал плату для HDMI захвата? Все просто: самый дешевый вариант и доступный — это Blackmagic Intensity Shuttle, но она не может работать с сигналом 1080p/60fps, только с 1080p/30fps — что не приемлемо, т.к. я не хотел понижать фреймрейт, чтобы можно было захватывать картинку. + это дело стоило в районе 10 тыc. рублей. — что не дешево при неизвестном результате.

Потери на конвертации HDMI to S-video несущественны для захвата цвета в разрешении 46х26 светодиодной подсветки.

Изначально для захвата S-video я пробовал использовать EasyCap( у него много китайских вариаций), но суть в том, что используемый там чип крайне убог, и с ним нельзя работать при помощи openCV.

Единственный минус — выходной сигнал S-Video содержал черные полосы по краям срезающий реальный контент(около 2-5%), выходную картинку с платы захвата я обрезал, чтобы удалить эти полосы, сама потеря изображения в тех областях на практике не сказалась на результате.

Для меня это была самая интересная часть, т.к. с железками я не очень люблю ковыряться.

Для захвата картинки я использовал openCV и в частности его .NET враппер emgu CV.

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

Процесс обработки фрейма
1. Получение захваченного фрейма
2. Кроп фрейма, для исключения черных полос

Обрезаем 8 пикселей сверху, 8 справа и 18 снизу.(слева полосы нет)

3. Ресайзим фрейм в разрешение подсветки, незачем нам таскать с собой здоровую картинку

Тоже ничего сложного, делаем это средствами openCV:
frame.Resize(LedWidth — 2*LedSideOverEdge,
LedHeight — LedBottomOverEdge — LedTopOverEdge,
INTER.CV_INTER_LINEAR);
Внимательный читатель заметит, обилие переменных. Дело в том, что у меня рамка телевизора достаточно большая, занимая 1 светодиод по бокам, 1 сверху и 3 снизу, поэтому ресайз делается на светодиоды, которые находятся непосредственно напротив дисплея, а углы мы уже дополняем потом. При ресайзинге мы как раз получаем усредненные цвета, которые должны будут иметь пиксели светодиодов.

4. Выполняем мапинг светодиодов с отреcайзенного фрейма

Ну тут тоже все просто, тупо проходим по каждой стороне и последовательно заполняем массив из 136 значений цветом светодиодов. Так вышло, что на текущий момент все остальные операции проще выполнять с массивом светодиодов, чем с фреймом, который тяжелее в обработке. Также на будущее я добавил параметр «глубины» захвата(кол-во пикселей от границы экрана, для усреднения цвета светодиода), но в конечном сетапе, оказалось лучше без неё.

5. Выполняем коррекцию цвета (баланс белого/цветовой баланс)

Стены за телевизором у меня из бруса, брус желтый, поэтому нужно компенсировать желтизну.
var blue = 255.0f/(255.0f + blueLevelFloat)*pixelBuffer[k];
var green = 255.0f/(255.0f + greenLevelFloat)*pixelBuffer[k + 1];
var red = 255.0f/(255.0f + redLevelFloat)*pixelBuffer[k + 2];
Вообще я изначально из исходников какого-то опенсорс редактора взял цветовой баланс, но он не менял белый(белый оставался белым), я поменял формулы немного, опечатался, и получил прям то, что нужно: если level компонента цвета отрицательный(я поинмаю как — этого цвета не хватает), то мы добавляем его интенсивность и наоборот. Для моих стен это получилось: RGB(-30,5,85).

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

6. Выполняем десатурацию (уменьшение насыщенности изображения)

В конечном сетапе, я не использую десатурацию, но может в определенный момент понадобится, фактически это делает цвета более «пастельными», как у Филипсовского амбилайта. Код приводить не буду, мы просто конвертим из RGB -> HSL, уменьшаем компоненту Saturation(насыщенность) и возвращаемся обратно уже в RGB.

7. Дефликер

Так уж выходит, что входное изображение «дрожит» — это следствие конвертации в аналоговый сигнал, как я полагаю. Я сначала пытался решить по своему, потом подсмотрел в исходники Defliker фильтра, используемом в VirtualDub, переписал его на C#(он был на С++), понял, что он не работает, ибо он такое впечталение, что борется с мерцаниями между кадрами, в итоге я совместил свое решение и этот дефликер получив что-то странное, но работающее лучше чем ожидалось. Изначальный дефликер работал только с интенсивностью всего фрейма, мне нужно по каждому светодиоду отдельно. Изначальный дефликер сравнивал изменение интенсивности как суммы, мне больше нравится сравнение длинны вектора цвета, Изначальный дефликер сравнивал дельту изменения интенсивности по сравнению с предыдущим кадром, это не подходит, и я переделал на среднюю величину интенсивности в пределах окна предыдущих кадров. И еще много других мелочей, в результате чего от начального дефликера мало что осталось.
Основная идея: исходя из средней интенсивности предыдущих кадров, выполнять модификацию текущего кадра, если его интенсивность не выше определенного порога (у меня этот порог в конечном сетапе 25), если порог преодолевается, то производится сброс окна, без модификации.
Немного модифицированный (для читаемости вне контекста) код моего дефликера:

Пусть _leds — массив светодиодов класса Color, _ledsOld — значения кадра до конвертации, LedLumWindow — ширина окна предыдущих кадров, для оценки среднего изменения интенсивности, в конечном сетапе окно у меня было 100, что примерно при 30кад/с равняется 3-секундам. _lumData — массив значения интенсивности предыдущих кадров.

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

8. Сглаживание светодиодов по соседям.

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

9. Сохраняем текущий стейт, чтобы тред отправки пакетов схватил и отправил его на контроллер подсветки.

Я умышленно разделил процесс обработки кадров и отправки пакетов на контроллер: пакеты отправляются раз в определенный интервал(у меня это 40мс), чтобы ардуино спела обработать предыдущий, ибо чаще чем 30мс она захлебывается, таким образом выходит, что мы не зависим напрямую от частоты кадров захвата и не мешаем тому процессу(а ведь отправка пакета тоже тратит время).

Немного про ардуино

Нельзя просто так взять и отправить по сериалу здоровенный пакет на ардуино, ибо онв ыйдет за пределы дефолтного буфера HardwareSerial и ты потеряешь его конец.
Решается это довольно просто: выставляем значение размера буфера HardwareSerial достаточного размера, чтобы влезал весь отправляемый пакет с массивом цветов, для меня это 410.

image

Сам софт был реализован в виде win службы, чтобы настраивать все параметры + включать/отключать я сделал Web UI, который связывался с службой через WebService на службе. Итоговый интерфейс на экране мобильника выглядит так:

Сейчас планирую прикрутить голосовое управление через Kinect for Windows подключенном к HTCP.

Результат

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

Как общий результат работы я записал видео с работой атмосвета по моей схеме:

Испытуемый образец 1: Pacific Rim, сцена битвы в Шанхае, этот фильм хорошо подходит для тестирования и демонстрации, много ярких сцен и вспышек, ударов молнии и т.д.:

Испытуемый образец 2: Какой-то ролик из MLP, слитый с ютуба, очень хорошо подходит для теста сцен с яркими цветами(мне понравились полосы), а также быстро сменяющихся сцен(под конец виде можно разглядеть последствия задержки, видных только на видео, при реальном просмотре этого не заметно, пробовал измерить задержку по видео — получилось 10-20мс):

И на последок стоит заметить про потребление ресурсов от HTPC:
HTPC у меня ASRock Vision 3D на i3, служба атмосвета отжирает 5-10% CPU и 32MB RAM.

Фоновая подсветка монитора и захват экрана

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

Фоновая подсветка монитора

Подключаем

И так, тут нам нужно выполнить два шага. Для начала — разместить и прикрепить светодиодную ленту к задней части монитора, после чего — всё подключить. Давайте с этого и начнём.

Обратите внимание, что ленту разлаживать и разрезать нужно тоже правильно! Положите монитор «лицом вниз» и в таком положении лента должна начинаться в нижнем левом углу. И от его должна идти против часовой стрелки.

как разложить ленту для подсветки

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

Обратите внимание на ещё одно важное правило! Вам необходимо разложить ленту на нижней и правой стороне, после чего сосчитать количество светодиодов и отрезать для верхней и левой стороны полоски с точно таким же количеством светодиодов. К примеру у меня в нижней и верхней полосках получилось по 29 светоиодов. А на боковых стенках — по 16. Конечно же у вас наверняка получатся другие цифры. Но не забудьте их записать, чтоб потом ещё раз не пересчитывать, эти цифры нам в дальнейшем понадобятся!

Теперь пришло время «окончательной сборки». Схему подключения я оставил на картинке правее. Как видите — в схеме нет ничего сложного. Управляющий провод подключаем к 13 ножке, выход — заземляем, а саму ленту подключаем к плюсу и минусу блока питания. К слову говоря, если провод получается довольно длинным — желательно сигнальный (на схеме — зелёный) провод и провоз заземления обмотать между собой. Таким образом он экранируется и не так сильно подвергается помехам.

У меня есть блок питания с USB и достаточным выходным током. По этому я «ампутировал» USB провод и подпаял к ему все необходимые провода. Все их припаял к разъёму, который шёл в коплекте с лентой и отдельно вывел провод для платы, которая находится в сторонке, чтоб не мешала. На фото ниже можете видеть получившуюся «косу» и то, как к ней припаяна плата Arduino.

Спаянная схема

Осталось только подключить USB провод от компьютера к плате и работа по части «железа» завершена. Осталось только всё это собрать по части софта.

Рамка для светодиодов

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

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

Проверка

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

Ну вот, всё работает, можно переворачивать монитор и заливать скетч для работы по протоклу Adalight!

Установка Ambilight на телевизор

Частично процесс монтажа фоновой подсветки для телевизора уже был затронут ранее. Рассмотрим несколько альтернативных способов фиксации ленты, о которых ещё не было сказано. Специалисты отмечают, что ни в коем случае нельзя использовать клей, поскольку он может негативно отразиться на работоспособности телевизора. К тому же, приклеенную ленту будет очень непросто снять в случае перегорания светодиодов.

Фиксировать самодельную подсветку можно даже с помощью обычного двустороннего скотча. Обязательно удостоверьтесь в том, что стрелки светодиодной ленты направлены вокруг монитора, в противном случае вам придётся всё переделывать. Если вы используете контроллер Arduino Nano, то расположите его рядом c USB портом, поскольку он будет подключаться к ТВ через этот интерфейс.

Несколько полезных дополнительных рекомендаций от профессионалов:

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

Если вы поняли, что самостоятельно не сможете собрать подсветку, то тогда купите для телевизора или компьютера Paintpack. Это готовый аналог Ambilight.

Статичная LED-подсветка

Первыми шагами к покорению технологии Ambilight на китайском рынке стали различные варианты LED лент, которые работают без привязки к происходящему на экране (т.е. по сути являются статичными). Иначе говоря, это некий аналог новогодней гирлянды, которая приклеивается по принципу пластыря к обратной кромке Вашего телевизора, монитора или проекционного экрана.

пример крепления лед-ленты

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

Светильник ные ленты статичная

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

Инструкция по установке

При установке любой LED-подсветки, самое важное определиться с её длиной. Примерное соотношение будет таковым:

Экран (в дюймах) Длина светодиодной ленты
22″ и менее 1 метр
22″ — 32″ до 2-х метров
32″ — 43″ до 3-х метров
43″ — 60″ до 4-х метров
60″ — 70″ до 5-х метров
70″ — 85″ до 5-7 метров
85″ — 100″ до 7-10 метров
100″ и более около 10 метров

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

Как обрезать LED ленту

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

Схема установки статичной подсветки.

Статичная LED-подсветка не требует какой-либо точечной настройки, всё управление осуществляется при помощи ИК-пульта, либо приложения эмулятора. Пользователь может переключить цвет подсветки, настроить порядок цветов и скорость их переключения.

ОШИБКИ И FAQ

Может случиться так, что при работе от USB компьютер не выключается, пока не будет извлечён штекер, ведущий к Arduino

Ответы на большинство вопросов можно найти здесь: https://alexgyver.ru/ws2812_guide/

В: Я купил ленту, на ней контакты G R B 12V. Как подключить?
О: Молодец, можешь кинуть ей в собаку. Это не та лента.

В: Не работает! Какие есть типичные ошибки?
О: Скорее всего в подключении. В основном забывают объединить GND ленты и GND Ардуины.

Оцените статью
Fobosworld.ru
Добавить комментарий

Adblock
detector