Arduino based Ambilight for you computer :)

I wanted to make a really cheap yet working implementation of an ambient light system (like those behind the new fancy TVs) for computers. I used Processing to capture screenshots, get an average screen color, and send it to the Arduino which controls an RGB led strip based on the values. I am glad it works great and am happy to share it with everyone!

Check out my setup and demo:

Also I have posted my code, materials and schematic:

Enjoy!! New ideas and comments please! :slight_smile:

Looking good, an improvement to this would be to split the screen up in multiple fields, and then use an mega or multiplexing to control 4 strips instead of one. :slight_smile:

I visited your blog - looks very nice, congrats :slight_smile:

I actually just ordered the same rgb led strip to use with my music visualizer as a more dramatic improvement. Any tips or suggestions with using the strip?

Thanks guys! @majordecibel: Sparkfun mentions that the B and G pin might be switched sometimes and that is really true! Mine was like that so do not panic if the colors look horribly wrong: just switch the B and G pin wires. Also, remember that the ULN2003A chip is really nice to drive this strip since our Arduino PWN pinouts are 5VDC and the strip requires 12VDC. Finally, remember to ground the ULN2003A chip because I seems to "work" without the biasing but the light is much weaker and fluctuates a lot (it made me sad initially). Then I realized and grounded the pin, and the led strip was glorious :slight_smile:

royboy:
I used Processing to capture screenshots, get an average screen color, and send it to the Arduino which controls an RGB led strip based on the values. I am glad it works great and am happy to share it with everyone!
.....
Enjoy!! New ideas and comments please! :slight_smile:

Awsome looks really great
What kind of processor power is needed on the computer?
Is it possible to devide the screen in 3 parts (left / right / top) for some more effect.

I want to make this on my HTPC.

Thanks for sharing your idea (processing and so)

Great!
I am actually going to do something like this.

The problem at the moment is that I don't know anything about programming or the arduino things.
For now I am testing out some rgb led strip that I got from ebay to see if it's worth ordering more of. I guess the lifetime of these led strips isn't as good as the ones I have seen at our wholesalers. Also the RGB amplifiers from ebay are a lot cheaper than the quality ones here. I wonder if this will result in a burnt down house :slight_smile:

Anyway... Iam going to do something similar to this:
http://fibreled.jet.ie/wp-content/uploads/2009/08/IMG_9826.jpg

I will be using this controller(common anode) when not watching tv:
http://www.ledlightsworld.com/24-keys-infrared-rgb-controller-p-120.html
And when watching tv I'll use it as ambilight with Arduino.

All video and all audio is coming from a computer(Mac).
As my lights will be in the ceiling I don't need more than one rgb out channel for the strip.

I noticed that a lot of people are using solutions that only work with specific software like winamp, vlc or xbmc.
Which isn't good for me as plugins usually, IF they come for mac are updated much later than the ones for PC.
Thats why I like yours better as it will work with anything(right?).

Someone on youtube did it like this:
"A very simple hack using lowpass filters on the VGA color signals and an Arduino that generates PWM from the filtered signals driving an IKEA "Dioder" LED strip."

What do you think of this?

You wrote "I skip every alternate pixel making my program 4 times faster".
How about every 4 or 8 pixels?
What happens? A feeling is that you still would get a ok average when watching movies?

You also wrote "delay(10); //delay for safety" and "delay(10); //just to be safe"
Is this milliseconds? Could you explain what the safety is for?

Is it possible to reduce or increase the overall brightness of the leds if they for example are too bright?

Is it possible to make the screenshots smaller than the actual screen to get better performance?
If you cut XXX pixels off every side of the screen and still get a good average reading?

Is it much more complicated and more expensive to use Bluetooth instead of a USB cable?
I would like to have all equipment on the other side of the room.

Thank you
C

@NietGiftig:

  1. What kind of processor power is needed on the computer?
    This is what i see in my task-manager:
    DWM: ~34,540K CPU 02 (desktop window manager is affected due to teh constant screenshots)
    javaw.exe: ~32,880K CPU 13 (how much the processing code uses up)
    My computer specs: 2.4 Ghz 64-bit Windows 7

  2. Is it possible to devide the screen in 3 parts (left / right / top) for some more effect.
    Yes it is :slight_smile:

//right now part of my code is:
for(i =0;i<1368; i=i+2){
for(j=0; j<928;j=j+2){
pixel = screenshot.getRGB(i,j); //the ARGB integer has the colors of pixel (i,j)
r = r+(int)(255&(pixel>>16)); //add up reds
g = g+(int)(255&(pixel>>8)); //add up greens
b = b+(int)(255&(pixel)); //add up blues
}
}

Change it to:

//for left (one-third screen):
for(i =0;i<456; i=i+2){
for(j=0; j<928;j=j+2){
pixel = screenshot.getRGB(i,j); //the ARGB integer has the colors of pixel (i,j)
r = r+(int)(255&(pixel>>16)); //add up reds
g = g+(int)(255&(pixel>>8)); //add up greens
b = b+(int)(255&(pixel)); //add up blues
}
}


//for right (one-third screen):
for(i =912;i<1368; i=i+2){
for(j=0; j<928;j=j+2){
pixel = screenshot.getRGB(i,j); //the ARGB integer has the colors of pixel (i,j)
r = r+(int)(255&(pixel>>16)); //add up reds
g = g+(int)(255&(pixel>>8)); //add up greens
b = b+(int)(255&(pixel)); //add up blues
}
}
 
//for top (one-third screen):
for(i =0;i<1368; i=i+2){
for(j=0; j<310;j=j+2){
pixel = screenshot.getRGB(i,j); //the ARGB integer has the colors of pixel (i,j)
r = r+(int)(255&(pixel>>16)); //add up reds
g = g+(int)(255&(pixel>>8)); //add up greens
b = b+(int)(255&(pixel)); //add up blues
}
}

@chnics:

  1. I noticed that a lot of people are using solutions that only work with specific software like winamp, vlc or xbmc.
    Which isn't good for me as plugins usually, IF they come for mac are updated much later than the ones for PC.
    Thats why I like yours better as it will work with anything(right?).
    Yes it will work with anything. And also on any OS. Just export the application from processing (checklist the Mac option) then enjoy it as a standalone application.

2)Someone on youtube did it like this:
"A very simple hack using lowpass filters on the VGA color signals and an Arduino that generates PWM from the filtered signals driving an IKEA "Dioder" LED strip."

What do you think of this?
It is a genius way to the same thing and I actually pondered about doing it. But I was just too lazy to design a circuit to do so. Its major advantage is that it wont take up processing power of your CPU. Some minor disadvantages are its slightly slow response time, inability to control light based on sections of the screen and using up your VGA port.

  1. You wrote "I skip every alternate pixel making my program 4 times faster".
    How about every 4 or 8 pixels?
    What happens? A feeling is that you still would get a ok average when watching movies?
    I have yet to try it. I strongly believe it will still be fine for movies.

  2. You also wrote "delay(10); //delay for safety" and "delay(10); //just to be safe"
    Is this milliseconds? Could you explain what the safety is for?
    Yes, on the arduino's code change:

analogWrite (RedPin, red);
analogWrite (GreenPin, green);
analogWrite (BluePin, blue);

to:

analogWrite (RedPin, n*red);
analogWrite (GreenPin, n*green);
analogWrite (BluePin, n*blue);

where n is a variable with maximum 1 and minimum 0. you can control n from a potentiometer to adjust the brightness using a dial :stuck_out_tongue: Or you can keep n fixed to lets say 0.5 for half the brightness.

  1. Is it possible to make the screenshots smaller than the actual screen to get better performance?
    If you cut XXX pixels off every side of the screen and still get a good average reading?
    Yes it is :). See the answer to query 2 of NietGiftig. (see above)

  2. Is it much more complicated and more expensive to use Bluetooth instead of a USB cable?
    It is more complicated. And it might slow down the response time.

Lastly, upload a video when youre done!! its a great interior decor idea.

Thanks for the info and addition.

I see that it all about this piece of code, the use of Processing makes it a lot easier. :slight_smile:

for(i =0;i<1368; i=i+2){
for(j=0; j<928;j=j+2){
pixel = screenshot.getRGB(i,j); //the ARGB integer has the colors of pixel (i,j)

I use full HD so for me it would be 1920 x 1080
But iI can speed things up by skipping more pixels.

Do you think that 3 times a (smaller) screenshot is not to much an overhead in processortime?
I don't want the films I'm playing to stutter
I use XBMC as player.

FYI.
I use this kind of LED strip, works good I have made my Aquarium light with these LED's
http://www.dealextreme.com/details.dx/sku.41522

this is awesome :slight_smile:

great idea and implementation.

I have installed Processing on my Pc.
And because don't have the drivers at the moment i took one RGB LED witch I had as spare.
And yes it worked.
I changed the capture parameters for my screen. (1920x1080)

I think that it need some tinkering because not all types of RGB Led's are equal.
The LED did not get off with a black screen but stayed on more or less white coloured.
Red on the screen did not made a the LED very red
I think that the treshold for each color is differend and also depends on the type of LED (strip) that you are using.

But the begin is promising and Processing looks very much capable for this task.

Now searching for an "how to" to monitor the serialport while the Processing sends data to the Arduino
I want to see the values.
I think that I have to search in Processing :slight_smile:

Thanks fkeel!
@ NietGiftig
If you are using my code, you should be able to see the values in processing itself (the numbers being continuously printed at the black potion in the bottom of processing) Something of that sort (weak colors, not totally dark when black screen) happened when I initially used the non-PWM pins accidentally. Also happened when I didn't ground pin 8 of the ULN2003A chip (should be connected to ground of 12V power supply and also Arduino GND pin). Also, remember that since you changed the resolution you should also change the numbers you divide the total by when averaging.

r=r/(684*464); //average red (should change to r=r/(950*540) )
g=g/(684*464); //average green  (should change to g=g/(950*540) )
b=b/(684*464); //average blue   ((should change to b=b/(950*540) )

I hope this will solve the problem because I think LED strips functions more or less the same.

Thanks for the input royboy,

I had already changed the parameters, but its good to see them from you too.

I don´t see the numbers in the application screen, but I have add some print statements in the Processing code and now they are there. (I´m learning quick, after all its works almost the same as the Arduino code :slight_smile: )
The average color in the little screen however did work, that´s why I assume that it has to do with the Arduino - RGB Led combination.

When I bypass the average colour and feed the Arduino with zero's for all colours then the LED stays off, but when I increase the value to 1 then it´s lightning up.
I use the same pins as you did and I don´t use the driver yet, just a plain RGB led with resistors to the Arduino.
But I´m sure that I will find the problem, and more sure that its not in your code.

The part in your code :
r = r+(int)(255&(pixel>>16)); //add up reds
g = g+(int)(255&(pixel>>8)); //add up greens
b = b+(int)(255&(pixel)); //add up blues
is something i have to discover how it works because the are so many shades of red (and blue and green)

Just playing and discovering now, that's also a fun part for me.

Thanks for the answers Royboy!
I just ordered all the Arduino stuff last night.
Hopefully the wait won't be too long. Bluetooth was quite expensive so I got a Uno.

Sure I'll do a video!
Though I am between apartments so it will be after a move And after a renovation. So don't wait up.. :slight_smile:

You got great feedback on your blog!

You guys who are talking about 2,3 and 4 channels for your ambilights. There are videos on youtube with 64.
Search for "64 channel ambilight".

Royboy, are you still interested in this project and looking to improve it or do you see yourself as done and going for the next challenge?

chnics:
You guys who are talking about 2,3 and 4 channels for your ambilights. There are videos on youtube with 64.
Search for "64 channel ambilight".

Yeah that's pretty cool but the fade in/out is much too slow on it for my liking. Presumably that can be adjusted though :slight_smile:

I wouldn't have thought that doing a lot of channels would be too tricky.

I'm currently wondering about if some kind of VGA passthrough device would be possible, with a chip controlling the ambilight without the computer having to do anything.

Perhaps this is more easily possible for RGB video?

RGB video presumably would be relatively easy as the RGB is split up already.

mowcius:
I'm currently wondering about if some kind of VGA passthrough device would be possible, with a chip controlling the ambilight without the computer having to do anything.

Perhaps this is more easily possible for RGB video?

RGB video presumably would be relatively easy as the RGB is split up already.

The problem with RGB or VGA is that if you also have to divide the screen
If you want to get good Ambilight you extend the screen with the colours projected on the wall.
So you have to divide the screen where each side gets the colour of that portion of the screen.
Thats not posible with the RGB output from your Tv set without additional hardware to devide the screen as far as I know.

To take it a step further, i have seen a demo with thunder and explosions wich were directed to a seperate very bright LED wich pulsed on the explosions. :smiley:

NietGiftig:
The problem with RGB or VGA is that if you also have to divide the screen
If you want to get good Ambilight you extend the screen with the colours projected on the wall.
So you have to divide the screen where each side gets the colour of that portion of the screen.
Thats not posible with the RGB output from your Tv set without additional hardware to devide the screen as far as I know.

Yeah, that was the conclusion I came to after a while.

Is there anyway for the script to avoid averaging the black bars on widescreen movies?

Yes, define the screen portion that you need.

I'm curently developing a version with 4 the sides from the screen giving sepate outputs.
In that version I have a pixel offset feature, with that you can skip the black bars.

By the way most of the work must be done in Processing, not on the Arduino

@chnics "Royboy, are you still interested in this project and looking to improve it or do you see yourself as done and going for the next challenge?"

My aim was to quickly create a platform which is easy to understand and modify. My job is done here :slight_smile: I am quite happy with it :slight_smile: It will at most take a person a day of coding and a week of shipping materials to extend this to screen borders and so on. So good luck to everyone who wants to extend this further! And please post your code somewhere where everyone can find :smiley:

It is another weekend and thus time for me to work on something else :stuck_out_tongue:

edit: just tried this myself. 9.6 volts works just fine...

Has anyone tried powering these strips off 9.6 volts? I assume it should work, but the LED's will simply be dimm. Does that make sense? Can anyone who has a working setup and a 9v battey lying around quickly give this a try and tell me the results? I would like to incroporate this into an excisting project and dont have 12v available...

Well, if someone has the equipment to quickly check this out for me, it would be apreceated.

Cheers

P.