domingo, 4 de julio de 2010

Ambilight casero para PC

Holas, aquí va el segundo tema util que hacer con arduino. En este caso montaremos un ambilight casero con las tiras de leds RGB del IKEA. Personalmente no recomiendo comprarlas, no porque sean malas, todo lo contrario, funcionan perfectamente, pero son un pelin caras para mi gusto.

Hay otra alternativa en Dealextreme, más económica, y servirá perfectamente.

Hardware

Las tiras de leds que tengo son así:


Cada tira tiene 4 conectores, uno para cada canal R, G y B (Rojo, Verde y Azul) y un cuarto por donde le entran los 12v que pide.

Tenemos que fijarnos si hay alguna leyenda por las tiras donde lo indique ya que en mi caso, el orden está cambiado y es RBG en lugar de RGB, la W será de power.



En cuanto al circuito necesario para que funcione la cosa, aquí pongo un esquema hecho a mano para que quede clara la cosa.



Como se puede apreciar, usamos un chip ULN2003 para controlar la potencia que pasa por los distintos canales.

Este chip soporta bien los 12v pero está limitado a 0.5A de salida, así que asegurate que las tiras de leds no consumen más de eso si no quieres salir ardiendo XDD

El resto es simplemente conectar a las salidas PWM de arduino por un lado y por el otro a las tiras de leds.

Los 12v se los meteremos a ambas tiras directamente por su pin.

Las X marcadas significa que no se usan.

Una vez montado en una placa prototipo o en un proto shield (como es mi caso) nos quedará algo como esto



El interruptor y las resistencias y tal podeis ignorarlas porque no son parte de esto, solo son para poder resetear el arduino con el shiel montado



Software

En cuanto a la parte de programar el arduino, debemos cargar el siguiente programa:

// This sketch translates Boblight commands to control RGB LEDs via PWM.
// Implements LTBL serial protocol (http://blogger.xs4all.nl/loosen/articles/420470.aspx)
// 2009-11-27 (c) Szymon Kobalczyk (http://geekswithblogs.net/kobush/)
// http://opensource.org/licenses/mit-license.php

#define DEBUG 0 // set to 1 to send debug to SoftSerial (2,4)

#define checkByte1 0x55
#define checkByte2 0xAA

int ledPin = 13; // debug led

#define channelCount 6
word channels[channelCount]; // holds current color values
int channelPins[channelCount] = { 6, 3, 5, 11, 9, 10 }; // PWM pins to control LED strips (2x RGB)

#if DEBUG
#include
int rxPin = 2;
int txPin = 4;
NewSoftSerial xSerial(rxPin, txPin);
#endif

void setup() {
digitalWrite(ledPin, HIGH); // say we're alive

Serial.begin(9600); // open serial

#if DEBUG
xSerial.begin(57600);
xSerial.print("[boblight] ");
#endif

for (int i =0; i < channelCount; i++)
{
channels[i] = 0; // reset all channels
pinMode(channelPins[i], OUTPUT); // setup channel pin
}
setLight();

#if DEBUG
xSerial.println("Setup finished.");
#endif

digitalWrite(ledPin, LOW);
}

void loop()
{
// continuously looks to the serial port
// if there is data it processes it
pollSerialPort();
}

void setLight() {
word val;
byte high, low;
for (int i=0; i < channelCount; i++)
{
val = channels[i];
high = val >> 8;
//low = val & 0xFF;
analogWrite(channelPins[i], high);

#if DEBUG
xSerial.print(channelPins[i]);
xSerial.print(":");
xSerial.print(high, DEC);
xSerial.print(" ");
#endif
}
#if DEBUG
xSerial.println();
#endif
}

// process incoming data
void pollSerialPort() {
int data;
if (Serial.available() >= 4) { // if at least 4 bytes are in the buffer
data = Serial.read();
echo(data);
if (data == checkByte1) { // check first prefix byte 0x55
data = Serial.read();
echo(data);
if (data == checkByte2) { // check second prefix byte 0xAA
digitalWrite(ledPin, LOW); // signal prefix recognized
data = Serial.read();
if (data < 127)
readChannels(data);
else
readCommand(data);

return;
}
}
// error
digitalWrite(ledPin, HIGH); // signal unrecognized sequence
}
}

void echo(int data) {
#if DEBUG
xSerial.print((byte)data, HEX);
xSerial.print(" ");
#endif
}

void readChannels(int startChannel) {
int numChannels = Serial.read();

// wait for all data to come in (expecting 2 bytes per channel)
while (Serial.available() < numChannels * 2)
delay(10);

#if DEBUG
xSerial.print("SET: ");
// xSerial.print("Reading channels ");
// xSerial.print(startChannel, DEC);
// xSerial.print(" ");
// xSerial.print(numChannels, DEC);
#endif

byte high, low;
word val;
for (int i = 0; i < numChannels; i++)
{
high = Serial.read(); // echo(high);
low = Serial.read(); // echo(low);
val = word(high, low);

if (startChannel+i < channelCount)
channels[startChannel+i] = val;

#if DEBUG
xSerial.print(high, DEC);
xSerial.print(" ");
#endif
}

#if DEBUG
xSerial.println();
#endif

// apply changes
setLight();
}

void readCommand(int command) {
int numBytes = Serial.read();

#if DEBUG
xSerial.print("Reading command ");
xSerial.print(command, HEX);
xSerial.print(" ");
xSerial.print(numBytes, DEC);
#endif

if (command == 0x81) // request current values
{
requestValues();
}
else if (command == 0x83) // open light
{
setLight();
}
else if (command == 0x84) // close light
{
for (int i =0; i channels[i] = 0; // reset all channels
}
setLight();
}

#if DEBUG
xSerial.println();
#endif
}

void requestValues()
{
int startChannel = Serial.read();
int numChannels = Serial.read();

#if DEBUG
xSerial.print(" request current values ");
xSerial.print(startChannel, DEC);
xSerial.print(" ");
xSerial.print(numChannels, DEC);
#endif
Serial.print(checkByte1, BYTE);
Serial.print(checkByte2, BYTE);

if (startChannel >= channelCount || numChannels <=0)
{
// no data to send
Serial.print(0, BYTE);
Serial.print(0, BYTE);
}
else
{
numChannels = min(channelCount - startChannel, numChannels);
Serial.print(startChannel, BYTE);
Serial.print(numChannels, BYTE);

byte high, low;
word val;
for (int i=startChannel; i < startChannel + numChannels; i++)
{
val = channels[i];
high = val >> 8;
low = val & 0xFF;
Serial.print(high, BYTE);
Serial.print(low, BYTE);
}
}
}


Eso por parte de arduino.

Por otra parte debemos configurar un programa llamado boblight en el pc, que es el que se encarga de mirar los colores que hay en la pantalla e indicarle al arduino por el puerto serie cuales debe mostrar por las tiras de colores izquierda y derecha.
El programa consta de 2 ejecutables, uno rojo y otro verde, hay ke ejecutar el rojo y luego el verde.

El punto interesante aquí es el fichero de configuración boblight.conf. En este fichero deberemos configurar lo siguiente:


[device]
name ambilight
type LTBL
output "com11"
rate 9600
channels 6
interval 10000
Como vemos, yo lo tengo configurado para que se comunique con el arduino por el com11, este habrá que cambiarlo al que uses. Puedes saber cual usas desde el compilador de arduino, Tools > Serial port.

En cuanto al resto de fichero, podemos trastearlo también un poquito para que nuestro ambilight tenga unos colores más parecidos a los de la pantalla, por ejemplo:


[color]
name red
rgb FF0000
gamma 1.0
adjust 1.0
blacklevel 0.0


En este texto configuramos tanto el color Rojo como sus intensidades, a veces puede ser que la tira de leds se vea demasiado rojizo y podemos ajustarlo bajandole el adjust, 1.0 = 100% de potencia, así si le keremos bajar un poco ponemos 0.8 o así

Otro punto interesante son los dos últimos trozos


[light]
name left
color red ambilight 1
color green ambilight 2
color blue ambilight 3
hscan 0 50
vscan 12 88

[light]
name right
color red ambilight 4
color green ambilight 5
color blue ambilight 6
hscan 50 100
vscan 12 88


hscan es el la superficie horizontal que vamos a tomar referencia para esa tira de colores, y la vscan es la superficie vertical. En el caso de la primera luz, estamos tomando del 0% al 50% de la pantalla en horizontal, y del 12% al 88% en vertical ( el vertical está recortado para que no tome en cuenta las barras negras de las películas).

Una vez montado todo, cualquier cosa que tengas en la pantalla estará representado por el ambishield, aunque sea el propio escritorio.

Link de mi boblight aqui.
http://www.megaupload.com/?d=7A8RMLFX

Os porngo un video robado de otra persona para que veais como queda.

1 comentario:

  1. Buenas

    Estoy intentando hacer el ambilight pero no consigo que arranque el boblight me sale un error device is not responding. Hace poco que tengo el arduino y no en tiendo este codigo, utilizo el arduino UNO.
    A ver si me puedes echar un cable.

    Gracias

    PD: Gran web de arduino estan muy bien los diferentes proyectos

    ResponderEliminar