Arduino Ambilight TV with Processing – Ozilight Part 2

The second part of the Ozilight Arduino Ambilight TV project would be about how to control the RGB LED strip using Arduino, learn how to communicate between the Processing application and the Arduino, and ultimately integrate these ideas into our TV ambilight system. If you have not seen the first part, it’s here.

If you have not seen the result, check out this video.

How to control the RGB LED strip using Arduino

I am using the WS2811 RGB LED strip, and it’s not controlled by RGB PWM signals, but some other protocol which only requires one wire connection. This would be quite difficult to do from scratch. Luckily the Adafruit team has developed a library for this type of LED strip, check out the NeoPixel Library.

I won’t go into too much detail how to use this library since it’s very simple, look it up on one of the examples included in the library.

This video shows I am running the example in the library.

Communication between the Processing application and the Arduino

Serial communication is the most obvious option here (USB cable). Although we are not controlling the LEDs with RGB values directly, we still need to send the RGB values to the Arduino from Processing application. For 25 LEDs, we will have at least 75 data we need to send each time we take a screen shot.

That’s quite a few data here, and things could go wrong sometimes with data transmission (lost data). So what I have here is a two way communication protocol:

  • Each time we are sending these 75 RGB data, we always append some constant values at the beginning, such as characters ‘o’ and ‘z’. This is a identifier for the Arduino so it knows this is the start of some new data
  • When the Arduino finished receiving all the 75 RGB data, it will talk to the Processing Application, “I am done now, next bunch of data please.”
  • When there is lost data, the Arduino would receive fewer then 75 data, and it will just stupidly wait. So we will need some kind of timeout functions to time how long we have waited and give up on the current operation.

Finally Arduino Ambilight TV is created by putting everything together

Don’t have much to say about this, went quite smoothly once I figured out how each part should work. I made a light adjustment to the LEDs position, now it’s 10 columns and 6 rows. (same number of LEDs, 25 of them, but taking 1 LED from the bottom left edge to the top edge)

ambilight-tv-led-location

And mounting the LED strip on the TV needs to be very accurate as well. It’s best to make the LEDs face slightly outward, so you can see more of the light from the front. But I am lazy so I just simply use Sellotape Tape, and it’s not accurate, AT ALL. ( I know I could do better than that)

ambilight TV back view led mount

In the code, You might notice a new array variable prevColor, this is a copy of ledColor from last cycle, and we will mix the current colour with previous colour, to get a nice and smooth colour transition effect.

If you are not sure what  “&0xff ” means, check out my post about this.

The current of each LED is about 20mA, so 25 of them is about 500mA.

amibilight-TV-connection-arduino-led-strip

Host Source code (Processing)

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!");
    exit();
  }

  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]);
    fill(rgb);  
    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')
          break;
      }

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

  }

  // Benchmark, how are we doing?
  println(frameRate);
  arraycopy(ledColor, 0, prevColor, 0, ledColor.length);

}

Slave Source code (Arduino)

#include <Adafruit_NeoPixel.h>

#define PIN 6
#define NUM_LED 25
#define NUM_DATA 77 // NUM_LED * 3 + 2
#define RECON_TIME 2000 // after x seconds idle time, send afk again.

// Parameter 1 = number of pixels in strip
// Parameter 2 = pin number (most are valid)
// Parameter 3 = pixel type flags, add together as needed:
//   NEO_KHZ800  800 KHz bitstream (most NeoPixel products w/WS2812 LEDs)
//   NEO_KHZ400  400 KHz (classic 'v1' (not v2) FLORA pixels, WS2811 drivers)
//   NEO_GRB     Pixels are wired for GRB bitstream (most NeoPixel products)
//   NEO_RGB     Pixels are wired for RGB bitstream (v1 FLORA pixels, not v2)
Adafruit_NeoPixel strip = Adafruit_NeoPixel(NUM_LED, PIN, NEO_GRB + NEO_KHZ800);

uint8_t led_color[NUM_DATA];
int index = 0;
unsigned long last_afk = 0;
unsigned long cur_time = 0;

void setup() {
	strip.begin();
	strip.show(); // Initialize all pixels to 'off'
	Serial.begin(115200);
	Serial.print("ozy"); // Send ACK string to host

	for(;;){

		if (Serial.available() > 0) {
			led_color[index++] = (uint8_t)Serial.read();

			if (index >= NUM_DATA){

				Serial.write('y');
				last_afk =  millis();
				index = 0;		

				if ((led_color[0] == 'o') && (led_color[1] == 'z')){
					// update LEDs
					for(int i=0; i<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.show(); 					 				}	 				 			} 			 		} 		else{ 		 			cur_time = millis(); 			if (cur_time - last_afk > RECON_TIME){
				Serial.write('y');
				last_afk =  cur_time;
				index = 0;
			}

		}

	}

}

void loop() {
}

100 thoughts on “Arduino Ambilight TV with Processing – Ozilight Part 2

  1. sammy

    Hi…me again….I’m hoping somebody can help me, as I’m very frustrated. I’ve got 25 ws2811 string of led’s mounted. When running the strand test from Arduino IDE, all seem to be working. I’ve copied the slave code and pasted it in Arduino IDE. When I upload it, the lights flash white briefly. I then copied the source code, and pasted it in Processing (2.2.1). When I run the Processing program, the popup showing what colours it’s reading is correct, but nothing happens with the lights. Framerate numbers scroll in the black area at the bottom of the Processing window, but nothing happens with the lights. I’ve gone to the line in the code which is:
    //port=newSerial(this, Serial.list()[0], 115200);
    I’ve tried putting different numbers inbetween the square brackets, as I know my Arduino is on com3. But nothing seems to change.
    Any help is appreciated, as this is my first Arduino project, and my frustration level is going through the roof!!!
    Thanks!!

    Reply
  2. Scott

    I’m hoping someone can help me. I’m getting ready to start this project, but I’m totally new to code. I’m using 25 ws2811 rgb leds and an Arduino uno. I’m not sure if I’m supposed to just copy and paste the code, or IV I havd to enter any values into the code. I suspect I have to deter the size of my tv somewhere, but I have no idea where. Saying it’s in the first part does me no good. What lines of code am I supposed to enter data into? Please help!!!

    Reply
  3. Scott

    Hi…I’m super-excited to start this project….just waiting for parts. I’ve never worked with Arduino. I have two questions after reviewing the tutorial…1. Other than arduino ide, processing, and your code, what else do I have to download? There’s mentions of a library and something called “neo-pixel”? Are these two necessary? 2. Where in the code do I enter the dimensions of my tv? (I have no coding experience…please be kind!)
    Thanks!

    Reply
  4. Mor

    Hi Oscar,
    i’m trying to build this project and came to a stop after changing the leds array.
    i’m using 54 leds (18×11).
    i have updated the array with the new params and changes the led_num_x and led_num_y to 18 and 11.
    when trying to run i get ArrayIndexOutOfBoundsException:2080109 on the following line:
    int pixel = screenData[ pixelOffset[i][o] ];

    any idea what cause this?

    Thanks
    Mor

    Reply
    1. Mor

      screenData.length = 2073600 and the pixelOffset[i][o] is 2080109.
      but why? is it screenData should be bigger or pixelOffset should be smaller?

      Reply
    2. Oscar Post author

      it’s saying the value of pixelOffset[i][o] is larger than the size of the screenData array.
      might be worth debugging what i and o is when this happen, and what is in that pixelOffset.

      Reply
      1. Mor

        Hi Oscar,
        i finally managed to make it work.
        i had some problems with the led array (which cause the index out of bound) and after that i saw that the processing ignore the ‘y’ that comes from the arduino.
        i changed the line: int inByte = port.read(); to char inByte = port.readChar(); and it worked.
        now i have to calculate the space between the leds and then soldier them.

        thanks for the instructions.
        Mor

    3. olivier

      procces code stop by for(;;){

      if(port.available() > 0){
      int inByte = port.read();
      if (inByte == ‘y’)
      break;

      i gave also change it like the Required , then is’t still not working . HOw can i fix iet ?

      Reply
  5. Texy

    Hi Oscar :)

    First of all thanks for posting your project on here ,but I have only one question if you could answer it.
    Can I do this project with the WS2801 led strip, and how would the code look like then?

    Thanks :)

    Reply
  6. Tom

    Hello again,

    I have next question for you guys. Is there software for controling led ws2811? (like prismatic or Ambibox) I mean with current flash firmware in arduino. Launch app in processing for movie or another app for mod lamp for example.

    Reply
  7. TheJMan

    Hi!

    First of all, great guide you have here.
    It works for me and my 100 led setup.

    I use an I3 processor in my laptop and I think it should be able to handel 100 leds, however I am only getting max 6 fps. I would like to get this up to a consistent 15 fps at least.

    I am looking into threading etc, but processing is not my main programming language, I was thinking of letting 4 threads handle 1/4th of the leds.

    If you or anyone have any ideas on improving the performance then please let me know!

    Reply
  8. Rusty

    Hi, can you tell me you like quedaria code for 30,60,30 and 120 led to fence faster changing colors .

    a greeting and thank you very much .

    Reply
  9. David

    found a bad value changed 218 to 3
    now it say
    ArrayIndexOutOfBoundsException:3

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

    Reply
  10. David

    Well fixed that problem! Had a numbering issue. Now I Get : ArrayIndexOutOfBoundsException:218

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

    Reply
  11. David

    Hi Oscar, This looks like a fun project to do. I had managed to get this working with boblight but has a slight delay and limited to using XBMC. I spent some time with your code only to end up with what think is a limitation in the led array. I have a Samsung UN65H7150 Smart TV. I glued 4 strips of WS2812 to it, totaling of 286 leds.(85 x 48) When I put it in your code I get “ArrayindexOutOfBoundsException:1” in Processing. I’m not much of a coder but can somewhat read it.

    This is what I changed:

    static final int led_num_x = 86;
    static final int led_num_y = 48;
    static final int leds[][] = new int[][] {
    {85,47},{84,47},{83,47},{82,},{81,47},{80,47},{79,47},{78,47},{77,47},{76,47},{75,47},{74,47},{73,47},{72,47},{72,47},{71,47},{70,47},{69,47},{68,47},{67,47},{66,47},{65,47},{64,47},{63,47},{62,47},{61,47},{60,47},{59,47},{58,47},{57,47},{56,47},{55,47},{54,47},{53,47},{52,47},{51,47},{50,47},{49,47},{48,47},{47,47},{46,47},{45,47},{44,47},{43,47},{42,47},{41,47},{40,47},{39,47},{38,47},{37,47},{36,47},{35,47},{34,47},{33,47},{32,47},{31,47},{30,47},{29,47},{28,47},{27,47},{26,47},{25,47},{24,47},{23,47},{22,47},{21,47},{20,47},{19,47},{18,47},{17,47},{16,47},{15,47},{14,47},{13,47},{12,47},{11,47},{10,47},{9,47},{8,47},{7,47},{6,47},{5,47},{4,47},{3,47},{2,47},{1,47},{00,47}, // Bottom
    {0,47},{0,46},{0,45},{0,44},{0,43},{0,42},{0,41},{0,40},{0,39},{0,38},{0,37},{0,36},{0,35},{0,34},{0,33},{0,32},{0,31},{0,30},{0,29},{0,28},{0,27},{0,26},{0,25},{0,24},{0,23},{0,22},{0,21},{0,20},{0,19},{0,18},{0,17},{0,16},{0,15},{0,14},{0,13},{0,12},{00,11}, {00,10}, {0,9}, {0,8},{00,07},{00,06},{00,05},{00,04},{00,03},{00,02},{00,01},{00,00}, //LEFT
    {00,00},{01,00},{02,00},{03,0},{04,0},{05,0},{06,0},{07,00},{8,0},{9,0},{10,0},{11,0},{12,0}, {13,0}, {14,0}, {15,0}, {16,0},{17,0},{18,0},{19,0},{20,0},{21,0},{22,0},{23,0},{24,0},{25,0},{26,0},{27,0},{28,0},{29,0},{30,0},{31,0},{32,0},{33,0},{34,0},{35,0},{36,0},{37,0},{38,0},{39,0},{40,0},{41,0},{42,0},{43,0},{44,0},{45,0},{46,0},{47,0},{48,0},{49,0},{50,0},{51,0},{52,0},{53,0},{54,0},{55,0},{56,0},{57,0},{58,0},{59,0},{60,0},{61,0},{62,0},{63,0},{64,0},{65,0},{66,0},{67,0},{68,0},{69,0},{70,0},{71,0},{72,0},{73,0},{74,0},{75,0},{76,0},{77,0},{78,0},{79,0},{80,0},{81,0},{82,0},{83,0},{84,0},{85,0}, //UP
    {85,0},{85,1}, {85,2}, {85,3}, {85,4}, {85,5}, {85,6}, {85,7}, {85,8}, {85,9}, {85,10},{85,11},{85,12},{85,47},{85,47},{85,14},{85,15},{85,16},{85,17},{85,18},{85,19},{85,20},{85,21},{85,22},{85,23},{85,24},{85,25},{85,26},{85,27},{85,28},{85,29},{85,30},{85,31},{85,32},{85,33},{85,34},{85,35},{85,36},{85,37},{85,38},{85,39},{85,40},{85,41},{85,42},{85,43},{85,44},{85,45},{85,46},{85,47}, //RIGHT
    };
    static final short fade = 75;

    static final int minBrightness = 120;

    Any Ideas what it could be and what needs changing.

    It also complains after that: start = range * (float)leds[i][0] + step * 0.5; that it doesn’t like the [i]

    I’m lost at this moment. If you could help me figure this out, that would be fantastic?!

    Reply
    1. Oscar Post author

      1. which line of code give you “ArrayindexOutOfBoundsException:1”? can you paste the code here?
      2. double check the elements in your leds array, make sure there are only 286 elements.

      Reply
      1. David

        No Problem, Thanks for the reply! It errors on: start = range * (float)leds[i][1] + step * 0.5;
        that gives ArrayIndexOutOfBoundsException:1

        I found I had some duplicate numbers. Fixed it, but have the same error.

        import java.awt.*;
        import java.awt.image.*;
        import processing.serial.*;
        static final int timeout = 5000; // 5 seconds

        Serial openPort() {
        String[] ports;
        String ack;
        int i, start;
        Serial s;

        ports = Serial.list(); // List of all serial ports/devices on system.

        for(i=0; i<ports.length; i++) { // For each serial port…
        System.out.format("Trying serial port %sn",ports[i]);
        try {
        s = new Serial(this, ports[i], 115200);
        }
        catch(Exception e) {
        // Can't open port, probably in use by other software.
        continue;
        }
        // Port open…watch for acknowledgement string…
        start = millis();
        while((millis() – start) = 4) &&
        ((ack = s.readString()) != null) &&
        ack.contains(“Adan”)) {
        return s; // Got it!
        }
        }
        // Connection timed out. Close port and move on to the next.
        s.stop();
        }

        // Didn’t locate a device returning the acknowledgment string.
        // Maybe it’s out there but running the old LEDstream code, which
        // didn’t have the ACK. Can’t say for sure, so we’ll take our
        // changes with the first/only serial device out there…
        return new Serial(this, ports[1], 115200);
        }
        /*
        // 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 268 RGB LEDs
        static final int led_num_x = 86;
        static final int led_num_y = 48;
        static final int leds[][] = new int[][] {
        {85,47},{84,47},{83,47},{82,},{81,47},{80,47},{79,47},{78,47},{77,47},{76,47},{75,47},{74,47},{73,47},{72,47},{71,47},{70,47},{69,47},{68,47},{67,47},{66,47},{65,47},{64,47},{63,47},{62,47},{61,47},{60,47},{59,47},{58,47},{57,47},{56,47},{55,47},{54,47},{53,47},{52,47},{51,47},{50,47},{49,47},{48,47},{47,47},{46,47},{45,47},{44,47},{43,47},{42,47},{41,47},{40,47},{39,47},{38,47},{37,47},{36,47},{35,47},{34,47},{33,47},{32,47},{31,47},{30,47},{29,47},{28,47},{27,47},{26,47},{25,47},{24,47},{23,47},{22,47},{21,47},{20,47},{19,47},{18,47},{17,47},{16,47},{15,47},{14,47},{13,47},{12,47},{11,47},{10,47},{9,47},{8,47},{7,47},{6,47},{5,47},{4,47},{3,47},{2,47},{1,47},{00,47}, // Bottom
        {0,47},{0,46},{0,45},{0,44},{0,43},{0,42},{0,41},{0,40},{0,39},{0,38},{0,37},{0,36},{0,35},{0,34},{0,33},{0,32},{0,31},{0,30},{0,29},{0,28},{0,27},{0,26},{0,25},{0,24},{0,23},{0,22},{0,21},{0,20},{0,19},{0,18},{0,17},{0,16},{0,15},{0,14},{0,13},{0,12},{00,11}, {00,10}, {0,9}, {0,8},{00,07},{00,06},{00,05},{00,04},{00,03},{00,02},{00,01},{00,00}, //LEFT
        {00,00},{01,00},{02,00},{03,0},{04,0},{05,0},{06,0},{07,00},{8,0},{9,0},{10,0},{11,0},{12,0}, {13,0}, {14,0}, {15,0}, {16,0},{17,0},{18,0},{19,0},{20,0},{21,0},{22,0},{23,0},{24,0},{25,0},{26,0},{27,0},{28,0},{29,0},{30,0},{31,0},{32,0},{33,0},{34,0},{35,0},{36,0},{37,0},{38,0},{39,0},{40,0},{41,0},{42,0},{43,0},{44,0},{45,0},{46,0},{47,0},{48,0},{49,0},{50,0},{51,0},{52,0},{53,0},{54,0},{55,0},{56,0},{57,0},{58,0},{59,0},{60,0},{61,0},{62,0},{63,0},{64,0},{65,0},{66,0},{67,0},{68,0},{69,0},{70,0},{71,0},{72,0},{73,0},{74,0},{75,0},{76,0},{77,0},{78,0},{79,0},{80,0},{81,0},{82,0},{83,0},{84,0},{85,0}, //UP
        {85,0},{85,1}, {85,2}, {85,3}, {85,4}, {85,5}, {85,6}, {85,7}, {85,8}, {85,9}, {85,10},{85,11},{85,12},{85,13},{85,14},{85,15},{85,16},{85,17},{85,18},{85,19},{85,20},{85,21},{85,22},{85,23},{85,24},{85,25},{85,26},{85,27},{85,28},{85,29},{85,30},{85,31},{85,32},{85,33},{85,34},{85,35},{85,36},{85,37},{85,38},{85,39},{85,40},{85,41},{85,42},{85,43},{85,44},{85,45},{85,46},{85,47}, //RIGHT
        };
        static final short fade = 75;

        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][6];

        byte[][] gamma = new byte[256][3];
        byte[] serialData = new byte[218];
        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!”);
        exit();
        }

        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);
        port = openPort();
        // 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> 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]);
        fill(rgb);
        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’)
        break;
        }

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

        }

        // Benchmark, how are we doing?
        println(frameRate);
        arraycopy(ledColor, 0, prevColor, 0, ledColor.length);

        }

  12. Patz

    yes when i ran the initial tests allr an out fine and i saw red and orange, i also tried to change the rgb grb line in the adafruit top, but no avail. :(

    Reply
  13. Patz

    Repost edited : Hey there Oscar, (Happy New Year B.t.w) i’ve been fiddling around for many hours now and I have this strange problem which i cannot seem to solve!! And it’s killing me lol, (i’m not experienced with coding and stuff) as the ambilight basics work perfect, but the colours are terribly off, and as you can imagine it gives half satisfaction, and the terrible need for more since it still looks niiice, but could even be way better…..
    The processing tab is showing the proper colour schemes ie: Orange yellow etc. while the movie is running, and on destop wallpaper, but orange/yellow/red are displayed as purple/pink/blue/cyan by the LED’s.

    Easier to show the result: http://www.youtube.com/watch?v=5H090JUx8x0

    My hardware is Arduino with your processing code – processing with your host code with serial.listchanged from 0 to 1 – I left all the variables with amount of leds (25) (77) as is.
    BUT I must add that I use a random 5 meter led strip (WS2812 on pin 6) Uncut with 30 leds per meter, of which 75(if i counted correctly) are in use behind the tv, and the rest is unused still rolled up.

    Im not sure which parameters to change in case to get the proper settings for my strip, as I have read RGB channels can differ per led strip etc.

    Your or anyone’s help would be more than greatly appreciated!!

    Reply
    1. Oscar Post author

      okay, very weird issue. the light is changing with the TV, is the hardware looks fine. I think it could be an issue with the code.
      are you able to run the examples in the NeoPixel library? can you see red/orange light?

      Reply
      1. Patz

        If the internal channels of the LED strip would be reversed opposite to the one youre using, how would i reverse the code to use the reversed channel strip?
        Im no code wizard :( , and I read some manufacturers change the internal wiring of the led strips.
        Already TRIED some pure randomness but no help.

      2. Patz

        When I change the line : Adafruit_NeoPixel strip = Adafruit_NeoPixel(NUM_LED, PIN, NEO_GRB + NEO_KHZ800); to RGB the strand demo starts with Blue, if left on GRB it starts with Red.
        Is that normal? Isnt it supposed to run RGB or GRB (ie: RGB Red first Green second Blue last) sequence or doesnt it matter.

      3. Oscar Post author

        you can try different combinations, see if that works. Also I am interested in what result did you get in the colour test in part one. (the processing program window that divides the screen edges into many little boxes, showing their averaged colour) Is the test showing you the correct colours?

      4. Patz

        Yes, the amount of blocks as original cfg asks, and yes the colours where uber spot on in the processing tabby, and moving/colouring along the edges when testing, only the output of the leds does not match the input of what processing SAYS its outputting lol, im being lied at x)
        Also the blocks in processing fit the screen very well, since I randomly guessed the center

        Furhtermore i noticed that when 60 leds are asked in cfg as original, it uses about 75 on the strip, I dont care, it works and moves with fx, in wrong colours but that part works, just adding for extra info.

        I got really frantic this morning, and googled the hell out of my pc, tried totally different processing and arduino code combos, but nothing comes even close to this code you created.

        So i ended up fiddling (your code) with the positioning part of processing where the LED positions are defined by the raster thingy, first I uploaded the code to arduino to talk to 72 leds x3216+2=218
        Then i manually added all the (i hope they where correct) variables to define the sides etc. I used 30 on top 10 on sides 6 on bottom sides making a total of 72.
        I’m terrible at math and such combinations in the mind, I probably messed it up along the way, but I did end up with having more colour boxes in processing, (missing bottom ambi fx of screen but ok lol) which coloured with current actions on the screen.
        I got really happy, as I had learned somethnig new and the rasterization worked somewhat.
        the arduino was already updated to run the 72 leds (I think/thought/hoped).
        I enabled processing and let it talk to ardi, they seemed to have a busy convo as the LEDstrip just went full on light blue, redid the process, thought ….. hell maybe start media player run it full screen to wake “something up” BAMMM the rest of the strip went off and approx 40 leds stayed on behind the tv, in BLUE…. Blue used to be my favo colour lol….(I changed the amount of leds because I figured (as noob) the processing software is sending x amount of data for x amount of lights, while in reality more lights are used, so maybe the data is not sufficient to feed all the leds the correct bytes they need, hence not producing the correct colours… But I seem to fail at adapting the code for my leds.

        Basicly it works with your standard code only no reds and oranges, and above is what I desperately tried to solve. Busy on it since 8 this morning, as im noob everything takes 20x longer lol.

      5. Patz

        Could you please give a short tip on what variables or lines I should focus to adjust colours, as I can read the characters per character, but I receive the “story” as some foreign language lol, which it is.

      6. Patz

        I just found some info which makes me rethink the whole strategy that its code based.
        It could be, but maybe more is at work here….

        I found this:

        1-
        This is all to say that the interface is very time-specific. To run the LEDs you’ll need a real-time processor, like an Arduino; microprocessors like those on the Raspberry Pi or pcDuino can’t give you a reliably-timed pulse. Even if one bit is less than a microsecond off, that could mean the difference between purple and maroon.

        2-
        Lower voltages are always acceptable, with the caveat that the LEDs will be slightly dimmer. There’s a limit below which the LED will fail to light, or will start to show the wrong color.
        leds_cap.jpg
        Before connecting a NeoPixel strip to ANY source of power, we very strongly recommend adding a large capacitor (1000 µF, 6.3V or higher) across the + and – terminals. This prevents the initial onrush of current from damaging the pixels.

        -3
        The longer a wire is, the more resistance it has. The more resistance, the more voltage drops along its length. If voltage drops too far, the color of NeoPixels can be affected.

        I have a fast PC with i7 2600k cpu and 12Gb ram, also usb 3.0 in case it matters.

        But the power supply that I improvised for the led strip is POSSIBLY not powerful enough? So the colours are off? How fast does such effect occur you guess? Right now I use 12v 2A adapter from a mobile harddisk,(12v strip)no capacitor and no resistor.
        I will try to find some old machinery here where I can steal the resistor and cap from, and a I have an 12 volt led/gel battery 14Ah – Will resolder the wires as short as possible and re-test.

        In case you got any idea’s code wise pelase let me know.

      7. Patz

        The new stronger PSU did not do a thing besides run abit cooler…….. Still orange is purple and red blueish.

      8. Patz

        Erased everything in libraries and reinstalled them – had a look into the library itself and saw Define BRG…….. I changed Adafruit_NeoPixel strip = Adafruit_NeoPixel(NUM_LED, PIN, NEO_GRB + NEO_KHZ800); from GRB to BRG………..

        Now in youtube with an RGB video test the colours match the position on screen, before that blue and green where turned around.
        With an full screen test the whole strip goes full on deep colour, but red is still not red but orange…?
        Now when I run the same part of movie the oranges and reds are nor purple… they are greenish now?????????????

        I need some help getting lost here.

      9. Patz

        I got it working 40% now lol… (on youtube only…..and not 100% red and orange just short flashes) Il let it be like that, unless anyone has an idea.

        blue is blue, green is green, red is minimal red and orange, orange is also weird.
        there are orange flashes coming by but mainly blueish/whitish, I really hoped it could get to deep orange like the torch in avatar x(
        In MPC or VLC mediaplayer the colours are still off, there I cannnot get any reds at all, and no matter what i do only the colours switch… from position. ;Red; becomes purple blue or green, never actually red as in the movie,
        I guess my LED’s are messed up with these libraries, as the LED’s are not official from ada website.
        I learned alot by digging through your code though.

      10. Oscar Post author

        Sorry I really don’t know what to suggest. If I were you I would trouble shoot the LEDs by giving it a specific RGB or GRB data, just to check they are displaying the correct colour, whichever format they use. If that passes, I would then trouble shoot the code, using the processing testing window to see if they are detecting the colours on the screen correctly.

  14. Rodrigo Mompo

    Hi Oscar

    Thanks for the tutorial.
    In my case I’m adapting it to use it with tlc5940. For bigger amblights, this solution is better. I’m putting this ambitlight for a 4D cinema with a screen of 2,5 x 4,5 meters.In order to make it working I made some changes.
    The changes in arduino code are very simple (just use another library, Tlc5940).
    For the procesing code I had problems when connecting the port. I just disable the infinite loop for println(“y”) in the processing code and put a capacitator between 5v and reset to diasable autoreset.

    With this modifications all works. I will post this modifications in my blog if you don’t mind
    controlrobotics.rodrigomompo.com. I will send you the link if you want to put it in your blog too.

    Rodrigo Mompo

    Reply
    1. Oscar Post author

      it’s been a while now, but i vaguely remember it was the “gd” variable which holds all the monitors as objects. Google all the variables types under this comment “// Monitor Screen information ” might give you some ideas.

      Reply
    2. Mr. Yourself

      You can change it in the following line in Processing:

      bot = new Robot(gd[0]); //0 = usually PC monitor, 1 = second output (I have TV)

      Reply
  15. Danny

    How is the connection between TV and Arduino made? Will the lights work on regular tv-shows aswell?

    Will test this when I get an answer :)

    Reply
    1. Oscar Post author

      there is no connection between the TV and Arduino. The arduino is connected with a computer, and the TV (monitor) displays video from the computer.
      it will work on all kinds of TV/monitors as long as it is displaying what’s on the computer.

      Reply
  16. Dan

    First of all, thank you very much for the code!

    I’m able to get it working with 72 of my 74 LEDs.

    I’ve got the processing updated to work with 74 LEDs. It’s got the 74 little boxes and the colors they represent are correct.

    The issue, however, seems to be with the Arduino sketch.

    It works when I use:
    #define NUM_LED 72
    #define NUM_DATA 218 // NUM_LED * 3 + 2

    but none of the LEDs light up if I use:
    #define NUM_LED 74
    #define NUM_DATA 224 // NUM_LED * 3 + 2

    Any suggestions?

    Reply
    1. Oscar Post author

      That’s a weird one. I looked through my code, and can’t seem to find what the problem might be.
      Just out of curiosity, what happen if you use 73 LEDs? and 71?

      Reply
      1. Dan

        71 works, 73 doesn’t. It seems like it hits some sort of a limit.

        To do a bit of testing I commented out all of the serial reading parts of the arduino sketch and put a routine in the “loop” that lights up one LED at a time. That worked just fine up to the 74 LEDs, so I know that the adafruit_neopixel library is working as expected. If I were to guess, I’m encountering some issue with the serial transmission of the data.

        Did you ever have your code running 74+ lights?

      2. Oscar Post author

        no i never tried that many LEDs.
        can you make sure you have the “leds[][]” in the processing code set correctly? there should be 74 sets of number pairs, if you are using 74 leds.

  17. Mav

    Hi Sid,

    I think it is possible to set this on Raspberry Pi. There’s only one thing that disturbs me about that. I’ve obsserved Java process “eats” about 600 MB – 1,8 GB of my RAM when I run application. Other thing is probably processor. I’ve tried to run my 82-LED on my laptop and it was really laggy (colors switches quite late). I don’t have that problem on my PC (but it’s a good machine). In fact, you wont see too much CPU usage. I didn’t debug that problem because i only use it with PC.
    I think Rasp Pi would die trying to process it. There could be other way to do it with Rasp Pi. Mayby some other code.

    Regards, Mav

    Reply
  18. Mav

    Hello,

    First of all I’d like to thank you for sharing this project. I did it with 82 LEDs and all works fine (takes over 1GB RAM when running). I only had to add “println(“34″);” like Pryning said above.

    I have one question. How can I run Processing program without running source code? I mean, I know there’s an export option but when I run it from exported EXE it doesn’t really do anything (java is running but LEDs not working).

    Other question is: Why is it not working with games? Works with desktop, browsers, movies, etc, but when I run a game it freezes with last “known” setup. With game minimized all works fine until I maximize game again. I don’t really need it to work in games, but I’m curious why that happens.

    Can anyone give some advice?

    Thanks, Mav

    Reply
    1. Oscar Post author

      Hi Mav
      Like I mentioned in the post, I am not very familiar with Processing, so the only way I can think of is to “export” the application in the IDE. What games were you trying to run? maybe something to do with the game is running directX or opengl for video rendering? sorry i am not very sure.

      Reply
      1. Mav

        Hello again,

        I’ve solved lesser problem. All works great even with games. The only thing I had to do is to set in-game gaphics options to play in “windowed fullscreen” not just “fullscreen”. After that all work good everywhere.

        Still got problem with running exported application but I’m trying to find something on their website. I’ll post here more info if I find some solution.

        Regards, Mav

      2. Sid

        Is there a way to modify the program where you wouldn’t need a laptop connected to the TV, such as using a Raspberry Pi connected to the HDMI port or something?

        Thanks, Sid

  19. Sid

    Hello

    I am trying to recreate this on my TV, but since it is a 58″ TV, I will be using 190 LEDs all throughout. (60 by 35, with each LED spaced about one inch apart) I have a feeling that my arduino won’t be able to handle all those LEDs, but just to be sure, how many LEDs would you recommend me putting on my TV at the max if I want the whole border (even the full bottom)?

    I did modify the program to handle those lights so the window that pops up now has all 190 boxes of color and as i drag objects around my screen border, it doesn’t show much lag.

    The other question I had is on how you run it. Do you have to have the computer connect to the TV via HDMI as the processing program runs? (and as the arduino is connected to the lights around the TV)
    Is there any other way to make this work without the computer?

    Thanks, Sid

    Reply
  20. Claudio

    I alredy changed the code, but the response or the led’s is very slow. this is the processing code:
    (removed)
    every led works but as i said it is very slow changing colors.
    I’m sorry for my English.

    Reply
    1. Oscar Post author

      That’s great, it’s working.

      sorry i had to remove the code you posted, it was taking up too much space.
      one thing about my project is, it’s not the most optimized and efficient program, and it requires a decent computer to run.
      My PC is 3 years old, running 30 LEDs or more, you will start to notice delays in colour transitions. that’s why I need to reduce the number of LEDs I use.

      I think You have 3 options
      1. Improve the code I gave you, to run more efficient/faster.
      2. use a more powerful computer
      3. use fewer LEDs.

      Reply
  21. Claudio

    hello, frist of all congrats for a great project, it worked very well.
    What do i have to change in the code to use 60 led.

    Reply
    1. Oscar Post author

      do you see the two different examples for 12 LEDs and 25 LEDs? just follow the method there.

      Reply
  22. Noodle1

    When I run the arduino code I recieve

    In function ‘void setup()’:
    error: ‘Serial’ was not declared in this scope

    It seems I have copied the code incorrectly. What information is the void setup section looking for?

    Reply
    1. Oscar Post author

      Have you got the latest Arduino IDE? I was using version 1.05
      I just tried it myself, everything is compiling fine, must be your end.

      Reply
  23. Pryning

    So, i tried a few things and found out that is wasn’t the arduino programme.
    Going through the processing code i put in println(“x”) all the way through the code, so that i could se how far i came until it stopped. And when i changed
    for(;;){

    if(port.available() > 0){
    int inByte = port.read();
    if (inByte == ‘y’)
    break;
    }
    to
    for(;;){
    println(“34”);
    if(port.available() > 0){
    int inByte = port.read();
    if (inByte == ‘y’)
    break;
    }
    it started working
    I ended up just adding print(); and now it works. Very weird, but now it’s working :)
    Again thanks for your help, and your great programme.

    Reply
    1. Oscar Post author

      so weird! haha, well done anyway! :-D
      maybe it just needed some delay there? not sure… Glad it works!

      Reply
    2. bradley wilds

      i am new to the whole programming thing can you send me your whole code im getting the exact same problem and would love to get this working

      Reply
  24. Pryning

    I didn’t get any errors no. I’ve tried a different code, similar to yours (but not as good :b) and Proccessing didn’t have any problem with that. (It was using the same port definition that i’ve tried here)
    I’ll look into the arduino side of the problem later (Try another arduino).
    For now, thanks a lot for your quick and great response :)

    Reply
  25. Pryning

    Thanks for this great code/project!

    I have more than one com-devices connected(2), so when i run you code drectly, i guess it sends the information to the wrong device. My arduino is on COM3, which is the second device in the array (if i use println(Serial.list());).
    But when i set the array to 1 (the second place) the program just opens a blank window, and there is no communication to see on the arduinos RX/TX LEDs.

    The code i have uncommented and changed:
    port = new Serial(this, Serial.list()[1], 115200);

    I have also tried from 0 to 9, just in case.

    Hope you can help me :)

    Reply
    1. Oscar Post author

      is the Processing program working, when “port = new Serial(this, Serial.list()[1], 115200);” is commented out?

      Reply
      1. Pryning

        Yes.´I get the little window up and i can see the different boxes change colors when i move windows arount. It also prints out the framerate.

      2. Oscar Post author

        then it’s definitely the Arduino side is not working, or not talking to the Processing program for some reason.
        Very strange.

        And did you get any error when compiling the Arduino sketch? Did you change anything?

        maybe it’s got stuck somewhere in the Arduino code, can you also tried comment out the LED control codes? (the two lines start with “strip.”)

      3. Mike

        You’ve got a bug – you are looking for ‘y’ in your Processing code, but you will never get it. Look for 121 instead and everything hooks up fine.

        I’ve got a problem in that when I start the arduino, all the LEDs turn on white and the only LED that changes is the first one.

        I suspect, if you have things working, that you have a different version of the code than we’ve got. Because what you published, as it stands, will not work. It just can’t.

        Can you update the code to whatever it is that you have that’s working?

    1. Mike

      Yes, it works fine. Just amend the kludgy Windows com port stuff for the slick mac com port stuff and you will be fine.

      You will need to download Processing for Mac.

      Reply
  26. imagide

    Hi Riccardo well I’m Italian, I tried to solve my problems without results, if you are registered Arduino forum we can try together!
    on the forum i am imagider.

    Reply
  27. Riccardo

    Hi, first thanks for sharing your project with us, that is really intresting and helpful to complete a full home theatre setup.
    I’ve buyed a WS2812B WS2811 5050 RGB LED Strip that is individually adressable, set the power and other wire and it works fine with all test of neo_pixel and fast led library, I’ve compiled the arduino and processing sketch without any errors, but it would not work…I’ve tryed to fix like you say in the previous comments but without suxess, Ive worked a lot with arduino and stepper motors but with the led for me is the first time, so I’ve copy and paste the code and try to fix with previous post, is there any test that I can do to understand why it won’t work? Thanks really in advance for the aviability, Regards. Riccardo P.s. sorry for my english but this is not my mother language, I’ve write to you from Italy.

    Reply
    1. Oscar Post author

      There are only 3 connections from the LED strip. Ground goes to arduino GND and Power Supply GND. 5V goes to power supply 5V. Data pin goes to one of the Arduino digital pin .

      Reply
  28. yeff

    In processing code look for the line “if (inByte == ‘y’)” and make it “if (inByte == 121)”
    Problem is a byte which is the numerical ascii for y is compared to string (which will never result true ergo will never BREAK )…. so itll get caught in infinite loop.
    Worked for me

    Reply
    1. yeff

      I do have the same problem as wicked and imagider…
      Changed the code to include my port… Port number is correct, baud rates are same in both host and slave, driver setting ar set to same baudrate… No errors just empty processor box.

      Both programs work with the same port… Cuz when i try to upload to arduino while processor script is running the arduino throws an error… port not avvailable… until i turn of processing, the it ul’s just fine….
      Any idea’s what it could be?

      Reply
      1. Oscar Post author

        like I mentioned above, you should be using “Serial.list()[0]” instead of “COM3” or whatever COM name you have.

        change the number in the array index to your corresponding USB device number for the arduino.
        My Computer only had the Arduino connected, so I was using 0.

  29. Tomza

    All work fine bud LED not turn ON,
    I have this LED WS2812B 5050 RGB Stripe weiss mit WS2811 Chip

    And adapter output 5V 2A…

    Is this ok?

    Reply
      1. Tomza

        yes, i upload this program from libery to adruino:

        #include

        #define PIN 6

        // Parameter 1 = 25
        // Parameter 2 = Arduino pin number (most are valid)
        // Parameter 3 = pixel type flags, add together as needed:
        // NEO_KHZ800 800 KHz bitstream (most NeoPixel products w/WS2812 LEDs)
        // NEO_KHZ400 400 KHz (classic ‘v1’ (not v2) FLORA pixels, WS2811 drivers)
        // NEO_GRB Pixels are wired for GRB bitstream (most NeoPixel products)
        // NEO_RGB Pixels are wired for RGB bitstream (v1 FLORA pixels, not v2)
        Adafruit_NeoPixel strip = Adafruit_NeoPixel(60, PIN, NEO_GRB + NEO_KHZ800);

        // IMPORTANT: To reduce NeoPixel burnout risk, add 1000 uF capacitor across
        // pixel power leads, add 300 – 500 Ohm resistor on first pixel’s data input
        // and minimize distance between Arduino and first pixel. Avoid connecting
        // on a live circuit…if you must, connect GND first.

        void setup() {
        strip.begin();
        strip.show(); // Initialize all pixels to ‘off’
        }

        void loop() {
        // Some example procedures showing how to display to the pixels:
        colorWipe(strip.Color(255, 0, 0), 50); // Red
        colorWipe(strip.Color(0, 255, 0), 50); // Green
        colorWipe(strip.Color(0, 0, 255), 50); // Blue
        // Send a theater pixel chase in…
        theaterChase(strip.Color(127, 127, 127), 50); // White
        theaterChase(strip.Color(127, 0, 0), 50); // Red
        theaterChase(strip.Color( 0, 0, 127), 50); // Blue

        rainbow(20);
        rainbowCycle(20);
        theaterChaseRainbow(50);
        }

        // Fill the dots one after the other with a color
        void colorWipe(uint32_t c, uint8_t wait) {
        for(uint16_t i=0; i<strip.numPixels(); i++) {
        strip.setPixelColor(i, c);
        strip.show();
        delay(wait);
        }
        }

        void rainbow(uint8_t wait) {
        uint16_t i, j;

        for(j=0; j<256; j++) {
        for(i=0; i<strip.numPixels(); i++) {
        strip.setPixelColor(i, Wheel((i+j) & 255));
        }
        strip.show();
        delay(wait);
        }
        }

        // Slightly different, this makes the rainbow equally distributed throughout
        void rainbowCycle(uint8_t wait) {
        uint16_t i, j;

        for(j=0; j<256*5; j++) { // 5 cycles of all colors on wheel
        for(i=0; i< strip.numPixels(); i++) {
        strip.setPixelColor(i, Wheel(((i * 256 / strip.numPixels()) + j) & 255));
        }
        strip.show();
        delay(wait);
        }
        }

        //Theatre-style crawling lights.
        void theaterChase(uint32_t c, uint8_t wait) {
        for (int j=0; j<10; j++) { //do 10 cycles of chasing
        for (int q=0; q < 3; q++) {
        for (int i=0; i < strip.numPixels(); i=i+3) {
        strip.setPixelColor(i+q, c); //turn every third pixel on
        }
        strip.show();

        delay(wait);

        for (int i=0; i < strip.numPixels(); i=i+3) {
        strip.setPixelColor(i+q, 0); //turn every third pixel off
        }
        }
        }
        }

        //Theatre-style crawling lights with rainbow effect
        void theaterChaseRainbow(uint8_t wait) {
        for (int j=0; j < 256; j++) { // cycle all 256 colors in the wheel
        for (int q=0; q < 3; q++) {
        for (int i=0; i < strip.numPixels(); i=i+3) {
        strip.setPixelColor(i+q, Wheel( (i+j) % 255)); //turn every third pixel on
        }
        strip.show();

        delay(wait);

        for (int i=0; i < strip.numPixels(); i=i+3) {
        strip.setPixelColor(i+q, 0); //turn every third pixel off
        }
        }
        }
        }

        // Input a value 0 to 255 to get a color value.
        // The colours are a transition r – g – b – back to r.
        uint32_t Wheel(byte WheelPos) {
        if(WheelPos < 85) {
        return strip.Color(WheelPos * 3, 255 – WheelPos * 3, 0);
        } else if(WheelPos < 170) {
        WheelPos -= 85;
        return strip.Color(255 – WheelPos * 3, 0, WheelPos * 3);
        } else {
        WheelPos -= 170;
        return strip.Color(0, WheelPos * 3, 255 – WheelPos * 3);
        }
        }

        And nothing happens :(
        How start this program, i'm beginner on this but i'm trying :)
        Maybe you send me your code for anrduino and processing code to my mail, and i try this, otherwise i have wrong LEDs

        Thanks for help

      2. Oscar Post author

        did you download the NeoPixel Library? there are test sketch there you can test with.
        if your LED doesn’t work with the test sketch, it must be your LED connection, or they are not the right model, or they are broken.

  30. Wicked

    Hello, First I would like to thank you for sharing this project!

    I’m having some problems I can’t get it to work and I don’t know what the problem is… I will give u some information in case u have time to help me, the parts consist of 25 ws2811 led connected at uno at COM4 (USB) with screen resolution 1920×1200, I’m sure that the connection is ok, I have tested with strandtest and it works like it should but it don’t work when I try your code, I compile Slave Source code (Arduino) without any problem and upload it to Arduino, then I run Host Source code (Processing) and seems to work properly but the led don’t, they are turned off.

    I don’t know if/what I must change at the code I’m noob..

    Thanks in advance for your time

    Reply
    1. Wicked

      I made 1 change to the code of processing adding the “port = new Serial(this, “COM4”, 115200);” like it is suggested at the comments in line 135 but then it doesn’t work, when I run it it opens a blank window.

      Reply
      1. Oscar Post author

        you can’t use “COM4”, you need to use “Serial.list()[0]”.

        if you have more than 1 USB device, then you need to change the number in the array to the corresponding device number for your arduino.

  31. imagider

    hello, another problem.
    when I add “port = new Serial (this,” COM7 “, 115200);” the program doesn’t work.
    how can i fix?

    Reply
      1. asha

        I have the same problem in that the processing window pops up, but it is white when this line of code is added. The colours come up fine when the line is commented out. The LEDs light up white, matching the processing window that pops up is white I guess. But the window doesn’t follow the colour of the screen. Any help would be super duper. Thanks for the great tutorial though!! :)

  32. Matthew

    I’m not actually going to do this as I don’t have an Arduino but how does it track the colours on the screen of the TV? If you are wondering how I came across your blog it was for the raspberry pi buttons and LEDs tutorial

    Reply
    1. Oscar

      Hi, I don’t understand the language in that post. But i have managed to fix the error now.
      It’s the wordpress formatting that messed up the code. a few lines were commented out by accident.

      Reply
  33. imagider

    hello,
    I need your help another time.
    hou can I solve this problem?
    “ArrayIndexOutOfBoundsException: 77”
    this is the line of processing:
    “serialData[data_index++] = (byte)ledColor[i][0];”
    thank you

    Reply
    1. Oscar

      Hi, looks like “data_index” has become larger than the size of your array “serialData”.
      What is the length of your LED strip? (number of leds)

      mabye use serial to debug “data_index” agaist the size of the array.

      Reply

Leave a Reply

Your email address will not be published. Required fields are marked *

Are you Robot? *

I don't look at blog comments very often (maybe once or twice a week), so if you have any questions related to multirotor please post it on this forum IntoFPV.com... You're likely to get a response from me faster on there.