четверг, 28 марта 2013 г.

Ambilight своими руками из подручных средств - BlockPWM (TLC5940)

Наигравшись вдоволь с ёлкой и её гирляндой (см. пост за январь 2013), захотелось сообразить какую-нибудь модную 'mod-lamp' и в поисках вдохновения по содержимому компьютера (от интернета я был безнадежно далеко как по расстоянию, так и по времени) наткнулся на интересную задумку, так называемый самодельный Ambilight от сайта compcar.ru.
Смысл таков: на монитор или телевизор на тыльную сторону цепляются трехцветные светодиоды, которые управляются с помощью Arduino, на компьютере же специальная программка просчитывает содержимое монитора, вернее его краев, и посылает цветовой код на ардуинку.
И я подумал, что у меня есть все что нужно чтобы сообразить подсветку монитора на пять точек, ведь один BlockPWM работает на 16ть каналов, а это пять каналов RGB.

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

Осталось за малым - подогнать код под мой BlockPWM, т.е. для управления микросхемой TLC5940. С кодом долго не мучился, начало как обычно при подключении BlockPWM, середина с примера из сайта, да еще автовыключение прописал:
Код под спойлером:

#include "Tlc5940.h"
#define ZONES 5
#define CHANNELS ZONES*3

unsigned long previousMillis = 0; //таймер простоя
unsigned long interval = 3000;    //интервал простоя 3000 - 3 сек

void setup(){
  Serial.begin(115200);
  Tlc.init();
}

void loop()
{
  unsigned long currentMillis = millis();
  if (Serial.available() > CHANNELS)  
  {  
    if (Serial.read() == 255)  //проверка прификса       
      {
        for (int i = 0; i < CHANNELS; i++)  {
          Tlc.set(i, Serial.read() * 16);
        }       
        previousMillis = currentMillis;   
        Tlc.update();
      } 
  } else {  
      if(currentMillis - previousMillis > interval) {
         previousMillis = currentMillis;
         for (byte i = 0; i < CHANNELS; i++) Tlc.set(i, 0);
         Tlc.update();
      }
  }
}


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