Динамическая подсветка тв

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

Если вы давно хотели прикрутить подсветку к своему неPhilips телевизору, но боялись попробовать- пробуйте. это проще чем кажется.

Для затравки небольшое видео результата.


В данный момент - подсветка работает еще прикльнее- в настройках выставил большую яркость и выше скорость обновления, теперь в боевиках или сценах в клубе (когда в кадре вспышки стробоскопа) - вся стена просто взрывается светом

Как делалось- достаточно просто:
+
+
+
Немного отваги=
Ambilight

Более подробно по пунктам:
1 Малинка у меня на тот момент уже была. Покупал там же на амазоне, но думаю тут происхождение роли не играет- плата унифицирована и покупать можно совершенно в любом месте- главное не советую брать БУ. у меня после некоторого количества времени работы на максимальной частоте без дополнительных радиаторов начала подглючивать. списываю на перегрев, но может быть и тупо брак производства. Малина крайне чувствительна к источнику питания- так что сразу запасайтесь нормальным БП с невысоким уровнем пульсаций… (и чтоб не просаживался под нагрузкой)
2 Собственно лента. Как работает думаю достаточно неплохо видно на видео. в самой ленте ничего особенного нет- отрезал куски чтоб хватило ровно на 3 грани телевизора. подпаял кусочками провода места сгиба (изначально делал соединение коннекторами, но быстро взбесило что торчат куски провода длиннющие- все порезал и спаял маленькими отрезками)
3 Гениальная программа гиперион. Устанавливается на малину (у меня в качестве ОС стоит мультимедийный OpenElec) по инструкции для идиотов. получилось даже у меня с первого раза. В процессе работы - тупо захватывает цветовые данные краев экрана, усредняет и шлет управляющие сигналы на светодиодную ленту. Лента перемигивается всеми цветами радуги, зрители в восторге. В процессе работы при проигрывании fullHD весом гигов в 30 дополнительная нагрузка на проц составляет 5-10 %. НА скорость не влияет никак.

Результат- превосходит самые смелые ожидания:
при плотности светодиодов 30т на метр- все стенка за телевиззором (удаление около 10-15 сантиметров) расцвечена в цвета экрана. визуально сцена раздвигается… ну на столько сколько есть этой самой стены. задержки в передаче -нет. по крайней мере невозможно отследить глазом. все плавно и четко. Для смартфона есть прикольная программа с помощью которой можно перевести подсветку в лаундж режим- выставить желаемый цвет\яркость, либо запустить один из предлагаемых паттернов (типа бегающего красного огонька, или просто радуги, или например цветовые переходы).
При отключении подсветки во время просмотра мультиков доча возмущается и требует вернуть все взад.)))

Ну и дабы соответствовать политике MySKU -отзыв собственно о детальках:
светодиодная лента - обозревалась много раз. мне досталась точно такая же. Очень хорошая. качество отличное. отображает если не изменяет память - 16 миллионов оттенков. точно не подсчитывал. требует дополнительного питания - повесил плюс минус на блок 5в 2А -на 2 метра хватает лихвой. думаю хватит и на 3 но гарантировать не буду. Управляющие контакты завел на GPIO малинки.

Малинка- одноплатный компьютер. Не обозревался только ленивым. Великолепная вещь как для освоения азов линукса, так и для постройки минималистичного и гибкого медиацентра. Для меня оказался идеальным вариантом: прокручивает любой доступный мне контент, работает в качестве приемника- показываетеля интернет ТВ, прикидывается получателем AirPlay сигнала когда хочется запустить что-то с телефона или ноутбука. Отличная вещь- 3 ватта и море удовольствия + поддержка HDMI CEC из коробки- управляется все с родного пульта телевизора.

Ну и напоследок еще видос вдогонку:

Пару дней назад решил поделать еще демовидосов- уже в новой квартире.

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

Планирую купить +69 Добавить в избранное Обзор понравился +16 +48

В этом уроке мы научимся создавать свою собственную подсветку ambilight для телевизора своими руками с помощью Arduino Nano.

Имейте в виду, что Эмбилайт Ардуино будет работать только на ПК с программным обеспечением Bambilight (скачать библиотеку на GitHub).

Вам понадобятся следующие компоненты:

  • Индивидуально адресуемая светодиодная лента RGB
  • Макетная плата небольшого размера
  • Несколько кабелей
  • 12V DC адаптер питания
  • Двусторонний скотч
  • 4-5 Скрепки
  • Затяжки (стяжки) пластиковые для проводов

Шаг 2. Тестирование светодиодной ленты

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

Поэтому неплохо припаять временные провода к вашей светодиодной ленте и протестировать ее с помощью Arduino, адаптера питания и файла.ino (можно загрузить на следующих шагах). Загрузите.ino в свой Arduino. Здесь вам пока еще ничего не нужно настраивать. Вы должны увидеть несколько меняющихся цветов светодиодной ленты.

Шаг 3. Схема подключения

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

Наша светодиодная лента использует IC WS2811 для управления 3 светодиодами в отдельности.

Шаг 4. Установка ambilight на монитор/телевизор

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

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

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

Важно!

Убедитесь, что стрелки на светодиодных полосах направлены вокруг вашего монитора! Если нет вам придется начать все заново!

Как только ленты на месте, вы сможете установить на тыльную сторону монитора. Не забудьте установить её в удобное место, потому что вам нужно будет подключить USB-кабель к компьютеру позже.

Шаг 5. Пайка всей электроники

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

Теперь подключите светодиодную ленту к Arduino, используя ту же схему, что и на шаге выше. Подключите USB-кабель, установите библиотеку FastLED (скачать на GitHub) и загрузите код, указанный на следующем шаге, в ваш Arduino. А далее вам останется только подключить адаптер питания, так как мы сделали всю проводку.

Шаг 6. Скетч Arduino Ambilight

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

#include "FastLED.h" #define NUM_LEDS 38 #define LED_DATA_PIN 3 #define NUM_BYTES (NUM_LEDS*3) // 3 colors #define BRIGHTNESS 100 #define UPDATES_PER_SECOND 100 #define TIMEOUT 3000 #define MODE_ANIMATION 0 #define MODE_AMBILIGHT 1 uint8_t mode = MODE_ANIMATION; byte MESSAGE_PREAMBLE = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09 }; uint8_t PREAMBLE_LENGTH = 10; uint8_t current_preamble_position = 0; unsigned long last_serial_available = -1L; uint8_t led_counter = 0; uint8_t byte_counter = 0; CRGB leds; byte buffer; // Filler animation attributes CRGBPalette16 currentPalette = RainbowColors_p; TBlendType currentBlending = LINEARBLEND; uint8_t startIndex = 0; void setup() { Serial.begin(115200); FastLED.clear(true); FastLED.addLeds(leds, NUM_LEDS); FastLED.setBrightness(BRIGHTNESS); } void loop() { switch (mode) { case MODE_ANIMATION: fillLEDsFromPaletteColors(); break; case MODE_AMBILIGHT: processIncomingData(); break; } } void processIncomingData() { if (waitForPreamble(TIMEOUT)) { Serial.readBytes(buffer, NUM_BYTES); /* DEBUG for (int i = 0; i < NUM_BYTES; i++) { Serial.write((char)buffer[i]); } */ while (byte_counter < NUM_BYTES) { byte green = buffer; byte blue = buffer; byte red = buffer; leds = CRGB(red, green, blue); } FastLED.show(); byte_counter = 0; led_counter = 0; } else { mode = MODE_ANIMATION; } } bool waitForPreamble(int timeout) { last_serial_available = millis(); while (current_preamble_position < PREAMBLE_LENGTH) { if (Serial.available() > 0) { last_serial_available = millis(); if (Serial.read() == MESSAGE_PREAMBLE) { current_preamble_position++; } else { current_preamble_position = 0; } } if (millis() - last_serial_available > timeout) { return false; } } current_preamble_position = 0; return true; } void fillLEDsFromPaletteColors() { startIndex++; // speed uint8_t colorIndex = startIndex; for(int i = 0; i < NUM_LEDS; i++) { leds[i] = ColorFromPalette(currentPalette, colorIndex, BRIGHTNESS, currentBlending); colorIndex += 3; } FastLED.delay(1000 / UPDATES_PER_SECOND); if (Serial.available() > 0) { mode = MODE_AMBILIGHT; } }

Шаг 7. Настройка программного обеспечения

Откройте файл.ino и отредактируйте следующие строки, чтобы они соответствовали вашей ситуации:

#define NUM_LEDS 38 // количество светодиодов #define BRIGHTNESS 100 // яркость

Теперь загрузите скетч в Arduino. Ранее вы должны были скачать библиотеку Bambilight, но если вы этого не сделали вы можете скачать библиотеку на GitHub сейчас.

Откройте Bambilight.exe, расположенную в:

[Местоположение, где вы сохранили папку Bambilight] \ Bambilight-master \ Bambilight-master \ Binary

Теперь настройте всё по своему усмотрению и протестируйте, используя тестовое видео, например, такое:

Как только вы будете удовлетворены результатом, вы можете минимизировать программу Bambilight.

В целом у вас должен быть такой результат работы подсветки ambilight для телевизора, которую вы сделали своими руками с помощью Arduino. Возьмите попкорн, пепси и наслаждайтесь результатом.

Телевизоры с динамической подсветкой вокруг рамки дисплея - одна из фирменных фишек компании Philips. И в отличие от многих других она работает. Однако за всё приходится платить, и телевизоры с Ambilight и повышенным эффектом присутствия стоят дороже многих других моделей.

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

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

Предлагается две основные модели: версия для монитора (30 светодиодов) и версия для телевизора (60 светодиодов). Есть и совсем простая - на 10 светодиодов, но она подходит только для самых маленьких мониторов.

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

mindrunway.ru

PaintPack, по сути, представляет собой небольшой корпус, к которому с двух сторон подключаются съёмные светодиодные ленты. Коробочка с начинкой несёт на себе индикаторы и разъём питания, а также microUSB для соединения с ПК. Есть ещё мастер-разъём (проприетарный) для последовательного подключения двух устройств.

Корпус устройства размещается на задней панели телевизора или монитора. Затем прокладываются LED-ленты в соответствии с инструкцией, подключается питание и начинается колдовство. При соединении PaintPack с компьютером через USB-разъём необходимо установить драйверы и произвести настройку устройства в комплектной программе.


mysku.ru

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

  1. Статический фон - устанавливается любой цвет, регулируется свечение светодиодов.
  2. Цветомузыка - подсветка будет мигать в такт звучанию музыки. Цвет подсветки устанавливается на зелёно-жёлтый.
  3. Динамический фон - плавное перетекание одного цвета в другой.
  4. Захват экрана - основной режим работы.

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

Работает PaintPack немного медленнее, чем официальный аналог от Philips. Но с учётом разницы в стоимости и возможности модернизации любого устройства выбор очевиден.

Добрый день.

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

Введение
В интернетах не очень сложно найти готовые/открытые решения и статьи как сделать Амбилайт для монитора/телевизора, если ты выводишь картинку с ПК. Но в моей мультимедиа системе вывод картинки на телевизор c ПК занимает только 5% времени использования, большее кол-во времени я играю с игровых консолей, а значит нужно было придумать что-то свое.
Исходные данные:
  • 60" Плазменный телевизор
  • HTPC на базе Asrock Vision 3D 137B
  • Xbox 360
Большинство устройств используют HDCP для воспроизведения контента даже во время игры.
Требование:
Необходимо обеспечить централизованную поддержку Атмосвета для всех устройств подключенных к телевизору.
Реализация
Я не буду рассказывать, как я прикреплял 4.5м светодиодную ленту к телевизору и что нужно сделать с Arduino, в качестве базы можно использовать .

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

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

Низкая цветопередача и высокий 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. Кроп фрейма, для исключения черных полос
Тут все просто:
frame.ROI = new Rectangle(8, 8, frame.Width - 8, frame.Height - 18 - 8);
Обрезаем 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;
var red = 255.0f/(255.0f + redLevelFloat)*pixelBuffer;
Вообще я изначально из исходников какого-то опенсорс редактора взял цветовой баланс, но он не менял белый(белый оставался белым), я поменял формулы немного, опечатался, и получил прям то, что нужно: если level компонента цвета отрицательный(я поинмаю как - этого цвета не хватает), то мы добавляем его интенсивность и наоборот. Для моих стен это получилось: RGB(-30,5,85).

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

6. Выполняем десатурацию (уменьшение насыщенности изображения)
В конечном сетапе, я не использую десатурацию, но может в определенный момент понадобится, фактически это делает цвета более «пастельными», как у Филипсовского амбилайта. Код приводить не буду, мы просто конвертим из RGB -> HSL, уменьшаем компоненту Saturation(насыщенность) и возвращаемся обратно уже в RGB.
7. Дефликер
Так уж выходит, что входное изображение «дрожит» - это следствие конвертации в аналоговый сигнал, как я полагаю. Я сначала пытался решить по своему, потом подсмотрел в исходники Defliker фильтра, используемом в VirtualDub, переписал его на C#(он был на С++), понял, что он не работает, ибо он такое впечталение, что борется с мерцаниями между кадрами, в итоге я совместил свое решение и этот дефликер получив что-то странное, но работающее лучше чем ожидалось. Изначальный дефликер работал только с интенсивностью всего фрейма, мне нужно по каждому светодиоду отдельно. Изначальный дефликер сравнивал изменение интенсивности как суммы, мне больше нравится сравнение длинны вектора цвета, Изначальный дефликер сравнивал дельту изменения интенсивности по сравнению с предыдущим кадром, это не подходит, и я переделал на среднюю величину интенсивности в пределах окна предыдущих кадров. И еще много других мелочей, в результате чего от начального дефликера мало что осталось.
Основная идея: исходя из средней интенсивности предыдущих кадров, выполнять модификацию текущего кадра, если его интенсивность не выше определенного порога (у меня этот порог в конечном сетапе 25), если порог преодолевается, то производится сброс окна, без модификации.
Немного модифицированный (для читаемости вне контекста) код моего дефликера:
Array.Copy(_leds, _ledsOld, _leds.Length); for (var i = 0; i < _leds.Length; i++) { double lumSum = 0; // Calculate the luminance of the current led. lumSum += _leds[i].R*_leds[i].R; lumSum += _leds[i].G*_leds[i].G; lumSum += _leds[i].B*_leds[i].B; lumSum = Math.Sqrt(lumSum); // Do led processing var avgLum = 0.0; for (var j = 0; j < LedLumWindow; j++) { avgLum += _lumData; } var avg = avgLum/LedLumWindow; var ledChange = false; if (_strengthcutoff < 256 && _lumData != 256 && Math.Abs((int) lumSum - avg) >= _strengthcutoff) { _lumData = 256; ledChange = true; } // Calculate the adjustment factor for the current led. var scale = 1.0; int r, g, b; if (ledChange) { for (var j = 0; j < LedLumWindow; j++) { _lumData = (int) lumSum; } } else { for (var j = 0; j < LedLumWindow - 1; j++) { _lumData = _lumData; } _lumData = (int) lumSum; if (lumSum > 0) { scale = 1.0f/((avg+lumSum)/2); var filt = 0.0f; for (var j = 0; j < LedLumWindow; j++) { filt += (float) _lumData/LedLumWindow; } scale *= filt; } // Adjust the current Led. r = _leds[i].R; g = _leds[i].G; b = _leds[i].B; // save source values var sr = r; var sg = g; var sb = b; var max = r; if (g > max) max = g; if (b > max) max = b; double s; if (scale*max > 255) s = 255.0/max; else s = scale; r = (int) (s*r); g = (int) (s*g); b = (int) (s*b); // keep highlight double k; if (sr > _lv) { k = (sr - _lv)/(double) (255 - _lv); r = (int) ((k*sr) + ((1.0 - k)*r)); } if (sg > _lv) { k = (sg - _lv)/(double) (255 - _lv); g = (int) ((k*sg) + ((1.0 - k)*g)); } if (sb > _lv) { k = (sb - _lv)/(double) (255 - _lv); b = (int) ((k*sb) + ((1.0 - k)*b)); } _leds[i] = Color.FromArgb(r, g, b); } /* Temporal softening phase. */ if (ledChange || _softening == 0) continue; var diffR = Math.Abs(_leds[i].R - _ledsOld[i].R); var diffG = Math.Abs(_leds[i].G - _ledsOld[i].G); var diffB = Math.Abs(_leds[i].B - _ledsOld[i].B); r = _leds[i].R; g = _leds[i].G; b = _leds[i].B; int sum; if (diffR < _softening) { if (diffR > (_softening >> 1)) { sum = _leds[i].R + _leds[i].R + _ledsOld[i].R; r = sum/3; } } if (diffG < _softening) { if (diffG > (_softening >> 1)) { sum = _leds[i].G + _leds[i].G + _ledsOld[i].G; g = sum/3; } } if (diffB < _softening) { if (diffB > (_softening >> 1)) { sum = _leds[i].B + _leds[i].B + _ledsOld[i].B; b = sum/3; } } _leds[i] = Color.FromArgb(r, g, b); }
Пусть _leds - массив светодиодов класса Color, _ledsOld - значения кадра до конвертации, LedLumWindow - ширина окна предыдущих кадров, для оценки среднего изменения интенсивности, в конечном сетапе окно у меня было 100, что примерно при 30кад/с равняется 3-секундам. _lumData - массив значения интенсивности предыдущих кадров.

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

8. Сглаживание светодиодов по соседям.
Вообще в конечном сетапе, сглаживание мне не очень понравилось, и я его отключил, но в некоторых случаях может пригодиться. Тут мы просто усредняем цвет каждого светодиода по его соседним.
var smothDiameter = 2*_smoothRadius + 1; Array.Copy(_leds, _ledsOld, _leds.Length); for (var i = 0; i < _ledsOld.Length; i++) { var r = 0; var g = 0; var b = 0; for (var rad = -_smoothRadius; rad <= _smoothRadius; rad++) { var pos = i + rad; if (pos < 0) { pos = _ledsOld.Length + pos; } else if (pos > _ledsOld.Length - 1) { pos = pos - _ledsOld.Length; } r += _ledsOld.R; g += _ledsOld.G; b += _ledsOld.B; } _leds[i] = Color.FromArgb(r/smothDiameter, g/smothDiameter, b/smothDiameter); }
9. Сохраняем текущий стейт, чтобы тред отправки пакетов схватил и отправил его на контроллер подсветки.
Я умышленно разделил процесс обработки кадров и отправки пакетов на контроллер: пакеты отправляются раз в определенный интервал(у меня это 40мс), чтобы ардуино спела обработать предыдущий, ибо чаще чем 30мс она захлебывается, таким образом выходит, что мы не зависим напрямую от частоты кадров захвата и не мешаем тому процессу(а ведь отправка пакета тоже тратит время).
Немного про ардуино
Нельзя просто так взять и отправить по сериалу здоровенный пакет на ардуино, ибо онв ыйдет за пределы дефолтного буфера HardwareSerial и ты потеряешь его конец.
Решается это довольно просто: выставляем значение размера буфера HardwareSerial достаточного размера, чтобы влезал весь отправляемый пакет с массивом цветов, для меня это 410.
UI
Сам софт был реализован в виде win службы, чтобы настраивать все параметры + включать/отключать я сделал Web UI, который связывался с службой через WebService на службе. Итоговый интерфейс на экране мобильника выглядит так:
Результат
В итоге результат оправдал все ожидания, и теперь играя в игры на консолях я получаю еще больше погружения в атмосферу игры.

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

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

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

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

Спасибо за внимание, очень надеюсь, что кому-нибудь моя статья поможет.

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

Итак, для сборки устройства понадобится:
1. Контроллер Arduino
2. с плотностью светодиодов 30шт на метр (для моего 32"" ТВ ушло 2 метра)
3. Светодиодный драйвер TLC5940
4. Источник питания 12 В

Ниже изображено схематичное изображение устройства подсветки:

Сзади телевизора наклеено 4 светодиодных ленты (левая, левая вверху, правая вверху, правая). Каждая лента подключена к LED-драйверу TLC4950 и источнику питания 12В. Светодиодный драйвер TLC4950 обеспечивает ШИМ управление яркостью каждого цвета: красного, зеленого и синего. LED-драйвером управляет контроллер Arduino, который в свою очередь получает команды от ПК. На компьютере запущена специальная программа, написанная на языке processing, которая анализирует каждый кадр видеоизображения и дает соответствующие команды Arduino.

Далее необходимо заготовить светодиодные ленты. Для моего 32" телевизора получилось в каждой ленте получилось по 15 светодиодов. На лентах предусмотрены специальные места, где можно спокойно припаяться после того, как вы обрезали ее.

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

Соединение Arduino и TLC5940:
Arduino TLC5940
Pin 2 ======= Pin 27 (VPRG)
Pin 3 ======= Pin 26 (SIN)
Pin 7 ======= Pin 25 (SCLK)
Pin 4 ======= Pin 24 (XLAT)
Pin 5 ======= Pin 23 (BLANK)
Pin 6 ======= Pin 19 (DCPRG)
Pin 8 ======= Pin 18 (GSCLK)

Остальные выводы TLC5940 присоединяем согласно следующей таблице:
Pin 22 (GND) === Arduino Ground
Pin 21 (VCC) === Arduino +5V
Pin 20 (IREF) === Arduino Ground через резистор 2кОм
Pin 1-15,28 === PWM Output (ШИМ выход на RGB-ленты)

От источника питания +12В я подключил к светодиодным лентам, а "общий" от источника питания к Arduino Ground.

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

Программа, запускаемая на компьютере написана на языке Processing (официальный сайт http://www.processing.org). Программа постоянно делает скриншоты экрана, а затем вычисляет средние значения трех цветов (красный, зеленый, синий) для разных мест на экране (левое, левое верхнее, правое верхнее, правое). После вычислений, программа пересылает данные в порт, к которому подключен контроллер Arduino.

Программа для Arduino считывает приходящие ей данные с порта и дает управляющие команды для LED-драйвера TLC5940, какой уровень яркости нужен для красного, зеленого или синего цветов. А далее, TLC5940 выдает ШИМ-сигнал для управления светодиодами.

  • Сергей Савенков

    какой то “куцый” обзор… как будто спешили куда то