Make your own TV ambilight using Arduino

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.

Remove these adsRemove these ads by Signing Up

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.

Step 2: Mount LED strip on TV

Picture of Mount LED strip on TV
My example is a bad one. you should be more accurate about the LED positions. and the should be facing outward with a angle, so the Lights can be seen brighter from the front.

The sketch is how the LEDs should be mounted on the TV. 

Step 3: The Connection (Arduino, Power)

Picture of The Connection (Arduino, Power)
The good thing about these LED strip is, it only requires one data connection from the Arduino.

You have to use external power source. I am using a 5V 2A power adapter for this. 

Note: GND of the power source should be connected to the Arduino GND.

Step 4: Finally the source code

Just copy these source code and you are good to go

I use Processing on the computer

tkotnik13 days ago

All work fine bud LED not turn ON,

I have this LED WS2812B 5050 RGB Stripe weiss mit WS2811 Chip (link:

And adapter output 5V 2A...

Is this ok

maewert3 months 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)  maewert3 months ago
That's right, you are not bad! :-D
tkotnik lacglzh15 days ago


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 :


daykkin1 month ago

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

ps. is it her ?

MrSkuit3 months 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!
crime4sin MrSkuit2 months ago

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 =;

if (inByte == 'y')




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


// Benchmark, how are we doing?


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


Jacob_M3 months 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,
crime4sin Jacob_M2 months ago


he use ws2811 chip led,

it have only 3 connections...


Get More Out of Instructables

Already have an Account?


PDF Downloads
As a Pro member, you will gain access to download any Instructable in the PDF format. You also have the ability to customize your PDF download.

Upgrade to Pro today!