Picture of Make your own TV ambilight using Arduino
This is a very easy project.

Here is the result

I won't go into too much detail how each part works, because I have written some information on my blog.

But you should be able to make it work with the information given on this instructable.


Step 1: Prepare RGB LED strip

Picture of Prepare RGB LED strip
The RGB LEDs came as a strip, but I want them to be separated further, so I soldered wires in between. I also use hot glue to strengthen the soldering points.

you could buy led strips that have long cables, or you can just use this out of the box, it's up to you.

I am using 25 LEDs.
Conradv13 months ago

The graphical representation works fine but the Neopixel stay off. Datapin is the right one. Seems like there is something wrong with the communication :(

TomažN4 months ago

I feel as though the program processing is not working properly. Does anyone have a matter that work? I would ask that we send this file. thank you

TomažN4 months ago

I use a macbook air. I have a problem that processing does not want to run a single LEDs. I always change the port between 0 and 3, and after 10 attempts, the LED lights light up but not always. What would cause this?

TomažN6 months ago


I have one problem. The red color is green and purple is light blue. how to fix this?

Just change this line:

Adafruit_NeoPixel strip = Adafruit_NeoPixel(NUM_LED, PIN, NEO_GRB + NEO_KHZ800);


Adafruit_NeoPixel strip = Adafruit_NeoPixel(NUM_LED, PIN, NEO_RGB + NEO_KHZ800);

Mr.Yourself6 months ago

Hi everybody,

thanks for good idea how to improve home entertainment. Everything works
well (for now only with 8pcs of 2812 for testing) I already ordered
strip with 150 pcs of these LEDs. As I know that to drive every LED
separatelly would take amount of PC capacity, I tried to change Arduino
code to send every incoming byte to 3 neighbouring LEDs. (in the
processing I would use just 50 rectangles) Is anybody able to check what
I have done wrong? I copied here only the part which I changed against original code. (With this program I can not light up more than 50
LEDs. Is the limit the line with “#define NUM_LED 50″ ? When I change it
to 150, Arduino expect bytes for 150 LEDs and receive only 50. Thanks.


for (int i = 0; i < (3 * NUM_LED); i++) {
int led_index = i * 3 + 2;
strip.setPixelColor(i, strip.Color(led_color[led_index], led_color[led_index + 1], led_color[led_index + 2]));
strip.setPixelColor(i, strip.Color(led_color[led_index], led_color[led_index + 1], led_color[led_index + 2]));
strip.setPixelColor(i, strip.Color(led_color[led_index], led_color[led_index + 1], led_color[led_index + 2]));


seb_168 made it!10 months ago

I made it and it works perfectly, thanks you. But i'm thinking about using c# instead of processing for better performances. If someone already test this ..?

jajunkie seb_1689 months ago

i can not figure out what i am doing wrong. i get the processing code to run and it changes colors as needed in the java window. i can also get the arduino code loaded and the ozy reply but i do not get any lights changing. all the leds just turn blue and thats it. i am running the apa104 60 led strip. if anyone can help that would be great.

jajunkie jajunkie9 months ago

when i look at the serial monitor it just says ozy and keeps repeating 'y'.

zootalaws seb_16810 months ago
Did you make it using the exact code here, or did you have to rewrite it?
seb168 zootalaws10 months ago

I used the code here, I just change values and 1 or 2 lines

zootalaws seb_16810 months ago

Seb, Do you want to post both bits of code that you used?

I get intermittent results, some times, but have never gotten it to work properly.

mat.tripp9 months ago

Hi i am struggling a little with processing.

how do specify which monitor to measure ?

and how to specify what com port to use?


mat.tripp9 months ago

Hi i am struggling a little with processing.

how do specify which monitor to measure ?

and how to specify what com port to use?


reducingmyconsumption made it!1 year ago

I made this using WS2801 LEDs (pictured below) because they were much cheaper than WS2811/ WS2812, they came pre-wired (but this limits the size of your TV to around 32") and the performance is exactly the same.

The only thing that I would change in your build is the processing software. I used ambibox 2.1.4 instead of processing because it allows greater customisation and has a lot of extra features. It allows multiple profiles for different aspect ratios which is important when watching movies, it can react to sound instead of screen captures for when you're browsing the web (rather that projecting boring website colours onto your wall) plus you can change saturation and brightness which allows you to fine tune it to suit your rooms wall colour and it's much easier to use than processing!

Thanks for posting this, you inspired me to build my amblight build a few moths ago and I absolutely love it.

lacglzh (author)  reducingmyconsumption1 year ago

I didn't know you can get this type of LED, well done on your build! :-D

zootalaws lacglzh10 months ago

You can get 'xmas lights' of 50 WS2811 LEDs for about $12. Saves a lot of soldering!

I am trying to get your apps working without much luck. I'm not much of a programmer, but I can fumble through. I mapped out the LED layout in Excel but am confused about x and y numbers and 0,0.

In your code, you say you have (for 25 LEDs) 10 x 6. but for me, that makes 32 LEDs - 10 across the top, 6 on the sides x 2.

So top left is 0,0, left side is 0 column, is the top left LED counted in both top and left column?

Regardless - I can't get the two halves to fire. I am confident they are exactly as you had in your example, with the port setup for my comm port setup - I can see the oxy in the Arduino serial monitor if I use that, but the LEDs just all stay lit white. It's like it never gets past the basic initialisation.

bogdanbarnea10 months ago
Tanks for your helpful project i realised ambilight whit 120 led and some modifications and is work perfectly tnx again
maewert1 year ago
I think I understand what you are doing. You hook up your TV as a computer monitor and you execute a PROCESSING script running on the computer which monitors the edges of the video image and sends the color data to the Arduino over the serial port. The Arduino receives the color data from your computer and clocks them out to a Neopixel RBG LED strip which you have modified to fit your TV. Cool.
lacglzh (author)  maewert1 year ago
That's right, you are not bad! :-D


GREAT JOB i like it very much, but i have a litle problem with arduino code.

When i copy/paste arduino code to arduino software, he give me this errors:

strip_1m:15: error: Adafruit_NeoPixel does not name a type

strip_1m.ino: In function void setup():

strip_1m:23: error: strip was not declared in this scope

I real like to do this project for myself, i have allready all done , only this probem is left.

Maybe please someone send me Adruino code to mai email please : tomza.kotnik@gmail.com


Hi tkotnik / lacglzh,

I have the same issue with the Arduino Code. How did you solve this?

email me at kanda.az@gmail.com

Thanks in advance

PiotrS1 year ago


Jacob_M1 year ago
Hey, its a very good tutorial but I didn't understand few things
which type of LEDs is it? I have a RGB led strip and it looks very different, I have 4 connections, 3 for red,green,blue and one for GND, and you have only 3
Please explain your self better I want to make this.
and How you wire this up? the picture isn't understandable.
Thank you,


he use ws2811 chip led,

it have only 3 connections...

NOW ,APA102 come out ,it is new build in ,but have data ,clock ,GND 5V ,4 connection

it is very great ,i will build my own project ,but use apa102 apa104 led strip to replace the led pixel

Ma cosa fa variare il colore e la luminosità del led rgb?
Un sensore luminosità?
bnasty941 year ago

i have a question and someone please help me this project is what made me want an arduino but i have everything i need but what is the aux adapter that goes to the ardiuno can someone please help me

bnasty941 year ago

yes i would really like some help yes i am a noob to the arduino but what is the aux cable with the adapter for i would love to do this project but i need some help please

This is super cool! You should enter it in the Home Technology Contest....!!!!

lacglzh (author)  craftclarity1 year ago

thank you, I just did! :-D

lacglzh (author)  lacglzh1 year ago

no, i can't, because they said it's too old...

molovesdiy1 year ago
i think this would make my head hurt!!!
radicator1 year ago

Hi, first thank you for sharing your project, I've made all the passage and uploaded the fix code without errors, processing works good and a appear the window with the edge color of the monitor, but the led strip do not turn on...I've checked it with some library examples ant it works good, is there any test that I can do to learn how to fix the problem? I have an arduino Mega board and a ws2811 chip led strip, really thanks! Riccardo

tkotnik1 year ago

All work fine bud LED not turn ON,

I have this LED WS2812B 5050 RGB Stripe weiss mit WS2811 Chip (link: http://www.ebay.co.uk/itm/281268099789?ssPageName...

And adapter output 5V 2A...

Is this ok

daykkin1 year ago

Hello! Nice instruction! Please give link to your LED strip (your blog not opening for me :/)

ps. is it her http://www.aliexpress.com/item/11-Hot-sale-WS2801-... ?

MrSkuit1 year ago
First of all nicely done!
I'm trying to do the same thing here for a few days know. I got the arduino one and a dreamcolor led strip (with 3 wires). Tried your sources for arduino and processing.
No problems at the arduino source. But from the processing source, I get ArrayIndexOutOfBoundsException: 77, at this part:
serialData[data_index++] = (byte)ledColor[i][0];.
I'm new with this kind of software and have no idea how to solve this. If you could help me that would be great!

Here is the fix :

import java.awt.*;

import java.awt.image.*;

import processing.serial.*;


// using 12 RGB LEDs

static final int led_num_x = 4;

static final int led_num_y = 4;

static final int leds[][] = new int[][] {

{1,3}, {0,3}, // Bottom edge, left half

{0,2}, {0,1}, // Left edge

{0,0}, {1,0}, {2,0}, {3,0}, // Top edge

{3,1}, {3,2}, // Right edge

{3,3}, {2,3}, // Bottom edge, right half



// using 25 RGB LEDs

static final int led_num_x = 10;

static final int led_num_y = 6;

static final int leds[][] = new int[][] {

{2,5}, {1,5}, {0,5}, // Bottom edge, left half

{0,4}, {0,3}, {0,2}, {0,1}, // Left edge

{0,0}, {1,0}, {2,0}, {3,0}, {4,0}, {5,0}, {6,0}, {7,0}, {8,0}, {9,0}, // Top edge

{9,1}, {9,2}, {9,3}, {9,4}, // Right edge

{9,5}, {8,5}, {7,5}, {6,5} // Bottom edge, right half


static final short fade = 70;

static final int minBrightness = 120;

// Preview windows

int window_width;

int window_height;

int preview_pixel_width;

int preview_pixel_height;

int[][] pixelOffset = new int[leds.length][256];

// RGB values for each LED

short[][] ledColor = new short[leds.length][3],

prevColor = new short[leds.length][3];

byte[][] gamma = new byte[256][3];

byte[] serialData = new byte[ leds.length * 3 + 2];

int data_index = 0;

//creates object from java library that lets us take screenshots

Robot bot;

// bounds area for screen capture

Rectangle dispBounds;

// Monitor Screen information

GraphicsEnvironment ge;

GraphicsConfiguration[] gc;

GraphicsDevice[] gd;

Serial port;

void setup() {

int[] x = new int[16];

int[] y = new int[16];

// ge - Grasphics Environment

ge = GraphicsEnvironment.getLocalGraphicsEnvironment();

// gd - Grasphics Device

gd = ge.getScreenDevices();

DisplayMode mode = gd[0].getDisplayMode();

dispBounds = new Rectangle(0, 0, mode.getWidth(), mode.getHeight());

// Preview windows

window_width = mode.getWidth()/5;

window_height = mode.getHeight()/5;

preview_pixel_width = window_width/led_num_x;

preview_pixel_height = window_height/led_num_y;

// Preview window size

size(window_width, window_height);

//standard Robot class error check

try {

bot = new Robot(gd[0]);


catch (AWTException e) {

println("Robot class not supported by your system!");



float range, step, start;

for (int i=0; i<leds.length; i++) { // For each LED...

// Precompute columns, rows of each sampled point for this LED

// --- for columns -----

range = (float)dispBounds.width / led_num_x;

// we only want 256 samples, and 16*16 = 256

step = range / 16.0;

start = range * (float)leds[i][0] + step * 0.5;

for (int col=0; col<16; col++) {

x[col] = (int)(start + step * (float)col);


// ----- for rows -----

range = (float)dispBounds.height / led_num_y;

step = range / 16.0;

start = range * (float)leds[i][1] + step * 0.5;

for (int row=0; row<16; row++) {

y[row] = (int)(start + step * (float)row);


// ---- Store sample locations -----

// Get offset to each pixel within full screen capture

for (int row=0; row<16; row++) {

for (int col=0; col<16; col++) {

pixelOffset[i][row * 16 + col] = y[row] * dispBounds.width + x[col];




// Open serial port. this assumes the Arduino is the

// first/only serial device on the system. If that's not the case,

// change "Serial.list()[0]" to the name of the port to be used:

// you can comment it out if you only want to test it without the Arduino

//port = new Serial(this, Serial.list()[0], 115200);

// A special header expected by the Arduino, to identify the beginning of a new bunch data.

serialData[0] = 'o';

serialData[1] = 'z';


void draw() {

//get screenshot into object "screenshot" of class BufferedImage

BufferedImage screenshot = bot.createScreenCapture(dispBounds);

// Pass all the ARGB values of every pixel into an array

int[] screenData = ((DataBufferInt)screenshot.getRaster().getDataBuffer()).getData();

data_index = 2; // 0, 1 are predefined header

for (int i=0; i<leds.length; i++) { // For each LED...

int r = 0;

int g = 0;

int b = 0;

for (int o=0; o<256; o++) { //ARGB variable with 32 int bytes where

int pixel = screenData[ pixelOffset[i][o] ];

r += pixel & 0x00ff0000;

g += pixel & 0x0000ff00;

b += pixel & 0x000000ff; }

// Blend new pixel value with the value from the prior frame

ledColor[i][0] = (short)(((( r >> 24) & 0xff) * (255 - fade) + prevColor[i][0] * fade) >> 8);

ledColor[i][1] = (short)(((( g >> 16) & 0xff) * (255 - fade) + prevColor[i][1] * fade) >> 8);

ledColor[i][2] = (short)(((( b >> 8) & 0xff) * (255 - fade) + prevColor[i][2] * fade) >> 8);

serialData[data_index++] = (byte)ledColor[i][0];

serialData[data_index++] = (byte)ledColor[i][1];

serialData[data_index++] = (byte)ledColor[i][2];

float preview_pixel_left = (float)dispBounds.width /5 / led_num_x * leds[i][0] ;

float preview_pixel_top = (float)dispBounds.height /5 / led_num_y * leds[i][1] ;

color rgb = color(ledColor[i][0], ledColor[i][1], ledColor[i][2]);


rect(preview_pixel_left, preview_pixel_top, preview_pixel_width, preview_pixel_height);


if (port != null) {

// wait for Arduino to send data

for (;;) {

if (port.available() > 0) {

int inByte = port.read();

if (inByte == 'y')




port.write(serialData); // Issue data to Arduino


// Benchmark, how are we doing?


arraycopy(ledColor, 0, prevColor, 0, ledColor.length);