C++ Software Developer
0,0
рейтинг
8 февраля 2013 в 15:42

Пиксельная подсветка просто и быстро tutorial

Ролики с демонстрацией пиксельной подсветки выглядят довольно эффектно — куча разноцветных всплохов, динамичные отблески смотрятся просто замечательно и выглядят более подвижными по сравнению с другими типами подобной подсветки.
Желание поработать с управляемыми огоньками с помощью arduino побудили меня соорудить такую систему. Как оказалось, это довольно простое мероприятие, на которое в сумме было потрачено всего несколько часов (собственно, само сооружение — 10 минут, остальное — софт). Детали процесса сборки и программирования я и изложу в этой статье. Софт, выводы и демо прилагаются.



Аппаратная часть


Для такой подсветки нам понадобятся следующие предметы и устройства:
  • Светодиодная лента на микросхемах WS2801 (с индивидуальным управлением каждым пикселем) нужной длины. Выглядит эта лента приблизительно таким образом:

    Лучше покупать ленту в силиконовой оболочке. Я покупал на ebay, можно попробовать купить напрямую у китайцев, будет дешевле раза в полтора. Длина ленты должна быть достаточной, чтобы обернуть её по периметру вокруг монитора или телевизора.
  • Arduino nano (или один из многочисленных клонов) — например, вот это. Подойдёт и не nano, нужно будет лишь правильно подключить.
  • Провода, называемые DuPont — не знаю, как они называются по-русски, выглядят вот так:

    Эти провода нужны для припаивания к ленте и подключения к ардуино. Нужно всего 2шт — так как они обжаты с двух сторон, разрезав пополам получим нужные нам 4 провода с разъемами.
  • Блок питания 5V + разъем питания, подходящий к этому блоку — и то, и другое в обилии продается как в радиомагазинах, так и на ebay, любых цветов, размеров и исполнений.
    Лента потребляет около 2A / метр в максимально ярком режиме. В повседневной работе 2 метра ленты питаются от БП 3A без каких-либо проблем.
  • Паяльник (любой, в разумных пределах), паяльные принадлежности, нож для зачистки проводов, изолента/термоусадка по вкусу.


Схема (если это гордое слово подходит для соединения двух изделий четырьмя проводами) приведена на рисунке:


Процесс сборки прост до безобразия. Детально описывать его нет смысла (по этой же причине нет фотографий готового «изделия» — ардуин с четырьмя проводами в интернете полно).
  1. Припаять всё, как показано на схеме.
  2. Присоединить провода к arduino, саму ардуинку соединить с PC, подключить блок питания.
  3. Залить в ардуино скетч (см. ниже), запустить исполняемый файл на компьютере (ссылки на софт также см. ниже), установить в программе нужный порт COM.
    Если вы пользуетесь Windows Vista/7 — нужно обязательно отключить Aero. Иначе скорость работы просто плачевная, какого-то решения проблемы низкой скорости захвата экрана при включенном Aero, как я понял, не существует.
  4. Убедиться, что всё работает, выключить.
    Следует упомянуть, что работает софт в 32-битном цвете only. Это можно легко поправить, но большого смысла, на мой взгляд, в такой правке нет.
  5. Прикрепить ленту на монитор. Пустить ленту нужно от левого нижнего угла по периметру по часовой стрелке (ЛН->ЛВ->ПВ->ПН->ЛН). Разрезать ничего не нужно, лента хорошо гнется практически в любом месте, так что проблем быть не должно. Для закрепления я использовал двухсторонний скотч — лента очень легкая и этого более чем достаточно.

На этом сборка закончена. Остаётся посчитать и задать количество пикселей по вертикали и горизонтали, и можно смотреть ролики, играть, etc. и радоваться.

Программная часть


Программная часть состоит из двух компонентов:
  • Скетч для Arduino;
  • Программа управления для PC.

Скетч для Arduino

В ардуино нужно залить код, приведенный ниже. Используется библиотека SmallUART (которая, впрочем, ничего особенно выдающегося не делает, при желании можно обойтись стандартными средствами).
/*** ARDUINO CODE FOR PIXEL LIGHT ***/
#include <SPI.h>
#include <SmallUart.h>

unsigned long lastTime;  // Time strip was updated last time
const unsigned long fadeTimeout = 3000;

////////////////////////////////////////////////////////////
//
void setup() {
  UART_Init(115200);  
  SPI.begin();
  SPI.setBitOrder(MSBFIRST);
  SPI.setDataMode(SPI_MODE0);
  SPI.setClockDivider(SPI_CLOCK_DIV8);
  blackoutAll();
  delay(1);
  lastTime = millis();
}

////////////////////////////////////////////////////////////
//
void loop() {
  uint8_t data; 
  UART_SendByte( 'R' ); // Byte "We're ready"
  bool valid = false;
  data = uartRead( valid );
  if ( valid ) {
    uint16_t pix_num = data * 3; // Total following bytes
    for( uint16_t i=0; i < pix_num; i++ ) {
      data = uartRead( valid );
      if ( !valid )
        break;
      SPI.transfer( data ); // Transfer byte to SPI
    }
    lastTime = millis();
  }
  
  if ( millis() - lastTime > fadeTimeout )
    blackoutAll();
}

////////////////////////////////////////////////////////////
// Turn off all possible 256 leds
void blackoutAll() {
  for ( int16_t i = 0; i < 768; i++ )
    SPI.transfer( 0 ); //погасить все пикселы ленты
}

////////////////////////////////////////////////////////////
// Read byte with timeout
unsigned char uartRead( bool& valid ) {
  uint8_t res = 0;
  valid = false;
  for ( uint8_t i = 0; i < 255; ++i ) { // Max timeout 256*10
    if( UART_ReadByte( res ) ) {
      valid = true;
      break;
    }
    delayMicroseconds(10);
  } 
  return res;
}


Тут всё предельно просто:
  1. Посылаем сигнал, что мы готовы принять данные о подсветке;
  2. В течение небольшого промежутка времени ожидаем данные;
  3. Если данные пришли, то первый байт из этих данных — число диодов, которые обслуживаются. Умножаем на 3 (RGB) для того, чтобы узнать количество последующих байт;
  4. Переправляем принимаемые данные в ленту;
  5. Обновляем метку времени о последнем обновлении ленты (это нужно для тайм-аута и гашения всех пикселей ленты).


Программа для PC

Вроде бы есть готовые решения для этого, но то, что я видел, мне не понравилось категорически, и вообще это неспортивно, зря что ли ардуино используется. Поэтому, пожевывая бутерброд, левой ногой была написана программа для захвата областей экрана, обработки их и передачи нужных данных в ленту. Вся программа с потрохами доступна на гитхабе по адресу github.com/sergrt/pixie (за код не пинайте).
Используется Qt 5.0.1 — интереса ради, никаких особенных вещей, присущих именно этой версии, не задействовано, так что вполне хорошо заработает и на 4 последние правки сделаны с использованием новых классов, так что теперь с версией 4 исходный код несовместим. Поскольку большую часть своих развлечений я проделываю под Windows, проект сделан под неё — Visual Studio 2012, захват GDI или DirectX. Я честно пытался генерировать .pro файлы для Qt Creator, но этот процесс страшно глючит с новым VS Qt Add-in, в итоге сходу эти файлы не заработали, разбираться не стал. Но всё можно без проблем скомпилировать под linux, см. UPD #3.

Настройки программы

Основная настройка — это указание количества светодиодов по вертикали и горизонтали, а также задание размеров захвативаемых областей. В мои 22" поместилось 10 шт по вертикали и 17 по горизонтали:

Ограничение частоты кадров разумно установить около 30. Значение «0» используется для работы с максимально возможной скоростью.

Также нужно правильно указать порт для обмена с Arduino и скорость обмена. Скорость в скетче по умолчанию 115200:


Для настройки яркости, порога срабатывания и ограничителя сделана отдельная вкладка «Обработка». Параметры, там представленные, регулируются в реальном времени:


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

Немного про внутренности софта для интересующихся

Основная идея состоит в запуске потока, хватающего области по заданному механизму, с подстраиваемым fps, и передающий эти области на обработку и последующую передачу ленте. Области захватываются в соответствии с настройками (кто бы мог подумать), цвет пикселя определяется простым средним по трем каналам RGB соответствующей области экрана. Опционально можно включить (директивами препроцессора) преобразование в Lab и усреднение его силами, но этот кусок кода не оптимизирован никак (взят как есть с просторов интернета), тормозит, поэтому по умолчанию выключен. Более того, каких-то особенных преимуществ Lab не заметно в контексте данной задачи, так что это не повод печалиться.
Обработка областей осуществляется по вертикалям и горизонталям, а на ленту отсылается последовательность цветов, начиная с левого нижнего угла и далее по периметру по часовой стрелке (так, как мы наматывали ленту на монитор при сборке).
Захват DirectX по скорости примерно равен захвату с GDI, при том, что в первом случае захватывается экран целиком, а во втором — только нужные куски. Вероятно, тут есть запас по оптимизации.
Обильное использование memcpy связано в первую очередь со скоростью работы — все остальные методы показали себя медленнее в той или иной степени.

Выводы и впечатления


Запас яркости у ленты просто огромный, что хорошо — можно пользоваться даже при наличии других источников света. В полной темноте лучше подвигать бегунками и сделать помягче. Сама лента вполне может служить самостоятельным источником освещения, нужно лишь переделать скетч.
Полагаю, немалое значение имеет диагональ монитора/телевизора. Чем больше — тем лучше.
Также следует устанавливать экран так, чтобы поблизости не было поверхностей, от которых отражаются светодиоды (в моём случае это боковые поверхности колонок) — это не особо критично, но лучше, чтобы резко выделяющихся пикселей не было видно совсем — так как между ними изрядное расстояние, это не лучшим образом влияет на картинку.

Что понравилось:
Просмотр видео и игры с такой подсветкой субъективно разгружают глаза — пропадает жесткий фокус на картинке монитора. Ощущение усталости глаз наступает позже, если не переусердствовать с яркостью. Смотреть видео как минимум необычно, для полноты эффекта лучше делать это с некоторого расстояния.

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

Ниже — ролик, как это выглядит в динамике. Оператор приносит свои извинения за заваленный горизонт.



Ссылки



P. S. Дабы соблюсти приличия, привожу ссылку на отправную точку, откуда я начинал — compcar.ru/forum/showthread.php?t=9462

UPD #1 На гитхабе обновилось ПО (включая исполняемый файл) — добавлена возможность группировать светодиоды для смягчения эффекта при просмотре не особенно динамичны фильмов.

UPD #2 Добавил поддержку захвата экрана силами Qt (при помощи QScreen), так что теперь можно строить кроссплатформенное приложение. Наличие желающих помочь потестировать приветствуется.

UPD #3 Благодаря помощи eugenis (https://github.com/eugenis) появился полноценный файл проекта pro, исправлены неточности для правильной компиляции под linux, немного оптимизирован код. Все эти радости доступны на гитхабе.
Сергей @sergrt
карма
47,0
рейтинг 0,0
C++ Software Developer
Реклама помогает поддерживать и развивать наши сервисы

Подробнее
Реклама

Самое читаемое

Комментарии (66)

  • 0
    Очень интересно, спасибо, давно хотел как то украсить свой уголок ;)
    А что за ролик на видео?
    • +1
      Трейлер к игре Mass Effect 3 — был выбран за динамичность и яркие сочными цвета.
    • +1
      Игра: Mass effect 3
      P.S. извините, за повтор
  • +3
    А зачем ардуино? если насколько я понял он используется только как преобразователь UART? Не проще взять USB-Uart на CP2101 стоит он 3$
    • 0
      Обмен с лентой по SPI, может быть переходники это тоже умеют, конечно, но конкретно в моем случе эта ардуинка используется еще как метеостанция, пусть теперь еще и монитор подсвечивает.
  • 0
    А на если на Raspberry Pi делать, то наверное, можно обойтись без компьютера, оставаясь, примерно в том же бюджете?
    • 0
      Примерно да, минус цена ардуино плюс цена Raspberry Pi.
      В таком случае нужно будет дописать класс по захвату экрана в linux (вряд ли на Raspberry Pi будет жить windows), и сделать запись сразу в SPI на ленту, минуя COM-порт.
    • +2
      Я смотрю, появился новый фетиш — Малина. Чуть что, идет предложение — давайте малиной решим. А что, $35 за малину + $25 за доставку — это же совсем дешево.

      Не нужна здесь малина. Вообще не нужна. Да и ардуино не нужна.
      В данном проекте достаточно купить в магазине любой конвертер USB-Serial (не важно на каком чипе, дрова по любому будут почти для любой ОС) рублей за 300 и немного переписать софт.

      PS. Можно использовать и малину без компьютера. Цепляем к ней видеокамеру, направляем камеру на монитор (телевизор), и далее уже обрабатываем полученное изображение и управляем светодиодной лентой. Получится достаточно дешево и универсально.
      • +1
        Моя идея в том чтобы играть малиной видео и ею же подсвечивать. Не используя ни компьютер, ни какой другой медиа плеер.
        • +1
          Я малинкой не обладаю, но вот друг купил и печалится — с его слов аппаратная поддержка декодирования видео есть только через родной специфический плеер, с остальными — результат печальный. Поправьте меня, если это не так.
        • 0
          По моему, малина не справится с таким. Это же надо декодировать видео, чтобы его вывести на экран и отправить на зонирование и получения цветов для подсветки. А декодер то аппаратный и, как мне кажется, он напрямую в видеобуфер результат работы выдает. Как оттуда получить данные — хз. А программно декодировать — точно не справится.
  • 0
    Подскажите, какие сильные/слабые стороны по сравнению с Лайтпаком (сайт) — наверняка ведь сравнивали.

    Ваш вариант выглядит проще и бюджетней, заинтересовали.
    • +1
      Самое большое достоинство — то, что подсветка подиодная, а не разбитая на 10 зон, как у лайтпака.
      +меньше проводов
      +меньше пайки
      +лучше качество
      -весьма дороже
      • 0
        Спасибо за разъяснения. Но и цена получается дешевле лайтпака тогда — лента от $14 за метр, клон Arduino/копия Arduino от $11
        • 0
          Да не очень-то дешевле, скорее наоборот.
          За 15 долларов на ибее можно взять 5 метров обычной, нечипованой RGB ленты. А это, на минуточку, уже разница в ~60 баксов на 5 метрах.
          Да и 5 метров на 40-ка дюймовый телевизор уже не хватит…
          Хотя, как заметили ниже можно обойтись и без ардуины, если пихать данные через конвертер, это уже экономия в пару баксов :)
          Да, плотность светодиодов у чипованной ленты меньше, Чем у обычной.
          Но по качеству картинки, по-моему, такая система будет в любом случае очень красиво делать лайтпако-подобные.
    • +1
      Преимущества очевидны:

      1. Для системы используются популярные, широко распространенные составные части (плата arduino, светодиодная лента), которые стали стандартом де-факто. При желании можно взять любую плату с микроконтроллером AVR, не обязательно arduino.
      2. Очень простая схема соединений, борода проводов за монитором получается гораздо меньше.
      3. Гибко настраивается количество подсвечиваемых точек по горизонтали и вертикали.

      Слабых сторон на мой взгляд нет, а все проблемы, от которых всегда страдал лайтпак (скорость работы, работоспособность во всех графических режимах на разных операционных системах) останутся и здесь. На коленке такие проблемы не решить, их можно побороть только тщательной реализацией ПО на компьютере.
  • 0
    Спасибо большое за статью, это намного интереснее, чем тот-же лайтпак и подобные устройства.
    Единственное, что огорчает — цена ленты. Обернуть средний телевизор будет стоить больше стони.
    • –1
      Да, цена весьма. На Aliexpress.com бывают предложения от 16$/метр с бесплатной доставкой.
      • 0
        Спасибо. Уже посмотрел, и вправду выходит весьма приемлемо.
        Еще технический вопрос — насколько метров хватит скорости шины?
        • –1
          Не могу сказать, у меня всего два метра этой ленты, однако встречались мне где-то ролики с огромными экранами, обернутыми четырьмя метрами ленты — всё работало вполне хорошо.
      • 0
        Это из-за индивидуального управления каждым пикселем? Вроде обычные ленты стоят в несколько раз дешевле.
      • 0
        Может я искать не умею… Если знаете, где брать по 16 баксов/метр, скиньте в личку пожалуйста.
        • +1
          Вот здесь, к примеру. 8 метров — по 14.75$, 16 — по 13,5$.

          Но это WS2811, она плотнее (60 LED на метр вместо 32) и управляется иначе, библиотекой FastSPI LED или кодом из этой заметки (он значительно короче).
          • 0
            >>Вот здесь, к примеру. 8 метров — по 14.75$, 16 — по 13,5$.
            На картинке товара не видно микросхем на ленте. Не настораживает?
            UPD: внимательно прочитал описание, пишут что контроллер встроен в LED
  • –7
    • +1
      С той статьи я начинал, в итоге всё продвинулось значительно дальше.
    • +1
      Зато автор статьи выложил внятное описание и исходный код, за что ему огромный респект.
    • +6
      Автором идеи уже 9 лет является Philips
      • –1
        Безусловно. Но Philips не пожелал сделать OpenSource проект
        Автор исправил свою ошибку и опубликовал ссылку на первоисточник, так что вопрос закрыт
  • –4
    Судя по скетчу, я так не считаю
    Вы только комментарии заменили на английские
    Считаю что было бы правильно, в статье указать ссылку на первоисточник
    • 0
      Прошу прощения, если задел чьи-то чувства, не со зла. Отличия не только в комментариях, ну да ладно. А сам процесс передачи в SPI трудно как-то по-другому логично оформить. Я привел в конце статьи ссылку на тот ресурс, так будет правильно.
  • 0
    Судя по комментариям меня одного интересует окончательная цена устройства + затраченные человеко-часы.
    • 0
      Время — 10 минут паять, 4-5 часов (два вечера) на софт. Итоговая цена около 2300 рублей.
      • –2
        >Пиксельная подсветка просто и быстро
  • +3
    Вот здесь уже давно нашли способ не отключать Аэро в Вин7/8 без потери производительности.
  • 0
    Пробовал реализовать простой boblight эффект на MSP430 Launchpad на основе этой статьи www.jevermeister.de/2011/11/mein-rgb-led-ambilight-mit-dem-msp430-funktioniert-mit-boblight/ В итоге получил не корректное отображение цветов — на экране зеленый, а светодиоды горят синим. И контакты переключал, и с автором связывался, не меняет дело. Может кто-то сможет помочь?
  • 0
    А блок питания для подобных лент на 5V нужен? На aliexpress.com в комплекте идут блоки на 12V (http://www.aliexpress.com/item/RGB-3528-SMD-LED-Strip-Light-Remote-Control-24key-Adapter-12V-3A-Free-by-China-Post/584901660.html). Для светодиодной ленты критично напряжение или только ток (для микроконтроллера естественно в случае 12-ти вольт нужен преобразователь)?
    • 0
      Обратите внимание, что это не та лента. Здесь нет управления каждым светодиодом.
      • 0
        Не заметил, спасибо. Я так понял они отличаются наличием контроллеров на ленте.
        • 0
          Именно, нужна с микросхемой на каждый диод. К тому же ваша лента 12-ти вольтовая, а нужна пяти.
          Или придется согласовывать уровни и использовать 12-ти вольтовый блок питания.
  • 0
    В используемой ленте (ссылка на лот с которой приведена в статье) используется питание именно 5V — там совсем другие светодиоды, их количество на метр, etc.
    (это должен был быть ответ на комментарий строкой выше)
  • 0
    Что то цвета в основном красные да фиолетовые, половина не совпадает с цветами на экране
    • 0
      Да уж, фиолетовый вместо белого как-то странно смотрится.
    • –1
      С цветопередачей всё в порядке, это эффект камеры + обои за экраном розовые.
  • 0
    Я бы ленту наклеил за монитор, чтобы ее не было видно, а только отсветы на стене, это было бы лучше для восприятия. И стоит подумать над фильтром, чтобы эффект был плавнее и быстрые переключения цветов не учитывались, а то в некоторых сценах лента начинает гирляндой работать.

    Спасибо за пример использования ленты.
    • 0
      Лента сейчас приклеена на угол — практически 45 градусов. Светодиодов вообще не видно, это эффект прозрачного пластика на мониторе (в статье я это указал). Эксперименты с наклейкой параллельно стене запланированы на ближайшие выходные, вероятно, станет лучше.
  • 0
    Клевая штучка, спасибо :)…
    А нет ли мыслей как это к ТВ прикрутить — кроме предложения камерой на него смотреть… Можно как-то, например, от какого-либо видеосигнала подсветкой управлять? Лобовое решение — неттоп на Атоме с видеовходом, на какое-то уж больно оно топорное — может кто поинтеллигентнее предложит;)?
  • 0
    Пока подобную фигню не сделают автономной для любого источника, читай тв, все это баловство
    • 0
      Плазменная панель + медиацентр с тюнером. Сейчас заказываю ленту. Будет автономно, ибо спутниковое все-равно через HTPC крутится.
      Вопрос к автору, как модифицировать схему на 12в ленту? У меня панель 59 дюймов, и на 5в больно мощный БП нужен будет. А на 12 у меня есть дура 20ти амперная.
      • 0
        Я бы уточнил у продавца — в фотографиях лота, ссылка на который в вашем комментарии, обычная лента 5V.
        • 0
          Тож закрались подозрения. Ибо она такая одна на всю алю.
      • 0
        Ну это ниразу не автономное
        • 0
          Почему? HTPC включен всегда. На панели тюнер есть, но не юзался ни разу.
          • 0
            Ну не будешь же к каждому телевизору лепить HTPC, особенно висящему на стене, где подсветка самое то
            • 0
              HTPC у меня в шкафу живет. А к телеку(висящему) канал в стене проложен. Туда много проводов пожно засунуть. И я имею в виду, что это для меня автономное решение. =)
            • 0
              Ну почему-бы и нет? Вот мой телевизор, скромный, правда, 26". За ним висит лайтпак, юсб-хаб (слева торчит кусочек кабеля), ик-приемник для пульта (снизу), и вебкамера на поворотной платформе (сверху). коробом вверх подключен к HTPC стоящему на шкафу.
              Вам же никто не мешает убрать системник под диван, или еще куда-нибудь, оставив только один-единственный короб на стене. А то и вовсе без него.
  • –2
    Жаль ничего в этом не мыслю, иначе бы что-нибудь из такой штуки сделал.
    Ничего полезного, так в качестве баловства. image
  • 0
    Насчет видимости преломленного света от светодиодов. Попробуйте в том месте с обратной стороны, где прямой свет от диодов на «козырек» вашей панели попадает, приклеить полоску непрозрачного материала — все равно то, что на прозрачный пластик попадает, в общей картине не должно участвовать (насколько я понимаю). Возможно, проблемой станет тень на стене от этой полоски сверху экрана (а может, ее не будет, если монитор достаточно далеко от стены стоит).
    Если тень все-таки будет мешать, попробуйте не непрозрачную полосу, а что-то рассеивающее, вроде белой бумаги использовать. Так у вас вместо отдельных диодов будет эффект цветной рамки. В общем, поэкспериментировать можно.
    • –1
      Попробую черной изолентой аккуратно заклеить с тыльной стороны. Она, конечно, не 100% непрозрачная для сильного источника света, но в любом случае положительный эффект будет.
  • 0
    Слишком высокая детализация получилась, надо бы еще немного усреднить — на примере видно, что в одном секторе блик на полметра, в соседних ничего — такое метание световых пятен быстро утомит.
    • –1
      В исходниках на гитхабе уже сделана «группировка пикселей» для уменьшения детализации и более комфортного просмотра фильмов в некоторых случаях. Там же есть компилированный исполняемый файл.
  • +1
    собрал себе ) Спасибо за ман.
    • 0
      Хорошо получилось :)
      • 0
        Да неплохо, но под 8-кой не хочет нормально работать, а вот как аеро в 7-ке в 8-й не могу найти где отключить.

        И спс за помощь ))

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