Introduction: Ambient Computer Lights - Using an Arduino With NeoPixel Strip

Hey everyone,

i decided to revisit an old project of mine, adding ambient light's to my computer. This time i decided to use a NeoPixel 30 rgb led strip instead of individually wiring up rgb led's. This project is incredibly simple and requires very little money to put it all together.

Parts Needed:
1 - NeoPixel Strip of rgb leds (I used the Adafruit NeoPixel Digital RGB LED Weatherproof strip  http://www.adafruit.com/products/1376)
1 - Arduino
some pins to make connecting the strip to the arduino easier

Wiring the strip is very simple so i wont go into any details. There might also be an additional 5v and Ground which does not need to be attached.

Red = 5v
White = Ground
Green = pwm pin

done!

Adafruit recommends using an additional power supply. However, as long as you keep the strip to 30 led's you wont need one.

If you have any troubles with getting the NeoPixel strip to work, please refer to one of adafruits many tutorials.
http://learn.adafruit.com/adafruit-neopixel-uberguide/arduino-library

If you do not have Processing installed already, this would be the time to do it!
http://www.processing.org/download/?processing





Step 1: The Code

The real meat and bone of this project is the code which makes the ambient lights possible. A while back i found some code by Rajarshi Roy which took average rgb values from a screenshot of the computer screen (using Processing) to be used with an rgb led. I then modified the code to scan the screenshot in 10 sections (192x1080 resolution). Once i had the average value of each section i was then able to output the values to the arduino, and then to the NeoPixel strip. Since there are 30 led's to work with, i assigned 3 led's to represent each section of the screen.

I experimented with more sections, but any more than 10 caused too much cpu usage.

I soon after decided to implement TouchOSC into the program to allow for iPhone control. That code is not included in this instructable, however if you email me (cgmalantonio@gmail.com) i will gladly send you the code. This code allows for a toggle on the Ambient lights, as well as RGB sliders and an XY touch pad for generating even more colors.


Well, lets begin!

First we have the Arduino code, this is responsible for taking the rgb values from the Processing sketch and outputting those values to the NeoPixel strip.

--------------------------------------------------------------------------------------------
--------------------------------Arduino Sketch----------------------------------------
--------------------------------------------------------------------------------------------

//Ambi: AmbientNeoPixel Arduino Sketch
//Created By: Cory Malantonio

#include <Adafruit_NeoPixel.h>
#define PIN 6
Adafruit_NeoPixel strip = Adafruit_NeoPixel(60, PIN, NEO_GRB + NEO_KHZ800);

int r[11]; // array for each color value
int g[11];
int b[11];

void setup() {
  Serial.begin(9600);
  strip.begin(); // prep the neopixel
  strip.show();
}

void loop() {

  if (Serial.available()>=31) {
    if (Serial.read() == 0xff){
            for (int x = 1; x < 11; x++){
        r[x] = Serial.read(); // read in the values from processing
        g[x] = Serial.read(); // in the same order we sent them
        b[x] = Serial.read();

        r[x] = constrain(r[x], 0, 255); // just incase any values slip away
        g[x] = constrain(g[x], 0, 255);
        b[x] = constrain(b[x], 0, 255);

      }
    }
  }


int Xval = 1; // count to 30
int Yval = 2; // while loading rgb values
int Zval = 3; // into 3 led's at a time

for (int z = 1; z < 11; z++){

strip.setPixelColor(Xval, r[z], g[z], b[z]);
strip.setPixelColor(Yval, r[z], g[z], b[z]);
strip.setPixelColor(Zval, r[z], g[z], b[z]);

Xval = Xval + 3;
Yval = Yval + 3;
Zval = Zval + 3;
}

  strip.show(); //output to the neopixel
  delay(20); //for safety
}


--------------------------------------------------------------------------------------------

--------------------------------------------------------------------------------------------

Here is the processing sketch,
the only real adjustment you will have to make will be the line
port = new Serial(this, Serial.list()[#], 9600;

the # is referring to the usb device number the arduino is plugged into.
i would suggest trying 0, then 1, then 2, etc until you find the one you are using.


--------------------------------------------------------------------------------------------
--------------------------------Processing Sketch-----------------------------------
--------------------------------------------------------------------------------------------
edit: i got a great email asking about changing the resolution on the processing sketch.
Since then, i changed out the processing sketch with one more fit to edit (without having to dive into the code).
--------------------------------------------------------------------------------------------

/*  Ambi2: AmbientNeoPixel Processing Sketch
**  Created by: Cory Malantonio
**  ambiArray is based on a design by Rajarshi Roy
*/


import cc.arduino.*;
import java.awt.Robot;
import java.awt.AWTException;
import java.awt.event.InputEvent;
import java.awt.image.BufferedImage;
import java.awt.Rectangle;
import java.awt.Dimension;
import processing.serial.*;


//-------Set Resolution Here-----//
int resX = 1920;
int resY = 1080;
//-------------------------------//

int sectW = resX / 10;  //Section Width for the 10 sections
int SectRx = sectW / 4; //Section resolution for x
int SectRy = resY / 4;  //Section resolution for y

Serial port;
Robot GrabRGBval;

void setup()
{
  port = new Serial(this, Serial.list()[2], 9600);
  //Serial.list()[#], # = usb device number
 
  try
  {
    GrabRGBval = new Robot();
  }
  catch (AWTException e)
  {
    println("Robot class not supported by your system!");
    exit();
  }
 
  size(200, 200);
  background(0);
  noFill();
}

void draw()
{
  int pixel;

  float[] rA = new float[11];
  float[] gA = new float[11];
  float[] bA = new float[11];
  int[] reso = new int[11];
 
  for (int Ar = 1; Ar < 11; Ar++){  //load the resolutions into the array
  reso[Ar] = sectW * Ar;              //192 is 1/10th of the 1920 resolution
  }
 
  float r=0;
  float g=0;
  float b=0;
  reso[0]=0;
 
 BufferedImage screenshot = GrabRGBval.createScreenCapture(new Rectangle(new Dimension(resX, resY)));
 
for (int LED = 1; LED < 11; LED++){
  int x=0;
  int y=0;
 
  //reso array increments in 10ths of the 1920 resolution, starting at 0
  for ( x = reso[LED-1] ; x < reso[LED]; x = x + 4) {  //"x + 4" is skipping pixels
    for (y = 0; y < resY; y = y + 4) {                 // to help it run faster
      pixel = screenshot.getRGB(x, y);
      r = r+(int)(255&(pixel>>16));
      g = g+(int)(255&(pixel>>8));
      b = b+(int)(255&(pixel));
    }
  }

  r=r/(SectRx*SectRy); //48 is 1/4th each 10th of the screen. Above we are skipping pixels
  g=g/(SectRx*SectRy); //we are left with 1/4th the pixels.
  b=b/(SectRx*SectRy); //270 is 1/4th of the 1080 resolution
rA[LED] = r;
gA[LED] = g;
bA[LED] = b;

}

   port.write(0xff); //write marker, arduino is looking for this
   for (int Br = 1; Br < 11; Br++){
   port.write((byte)(rA[Br]));
   port.write((byte)(gA[Br]));
   port.write((byte)(bA[Br]));
  }
 
  delay(10); //delay for safety

    for (int cOne = 1; cOne < 11; cOne++){  
  fill(0);
  stroke(rA[cOne], gA[cOne], bA[cOne]);
  rect((cOne - 1)*20, 0, cOne*20, 200);
  fill(rA[cOne], gA[cOne], bA[cOne]);
  rect((cOne - 1)*20, 0, cOne*20, 200);
}
}





Comments

author
AsheshP (author)2017-02-05

Hey,

Can I use an adafruit trinket instead of the arduino?

Thanks!

author
daykkin (author)2014-02-27

Hello! Great idea! Please tell me how change the code if i have RGB 5050 LED Strip this type (3 color PWN pin / 1 Ground) http://www.aliexpress.com/item/10m-lot-5050-rgb-Waterproof-led-strip-300-DC-12V-14-4W-RGB-Blue-Yellow-Red/1552880999.html

author
NicolaiH4 (author)daykkin2016-04-24

you cant do that you will need neopixel with this code as each Led is solo addressable. with your strip you cant change the each led separately.

you can still use it for ambilight. with Arduino. but you will to find or write another code. and the result will not be as good tho

author
Moffe2k (author)2016-03-24

I have bought a 30 led strip sa described, but the first LED won't light up, but the 29 others do (All 30 work in the strandtest). How do I change the code to include the last one? Anyone else having this issue?

author
Moffe2k (author)Moffe2k2016-03-24

Nevermind, I think I'm getting a hang of this.

I changed 1,2,3 to 0,1,2 on the following lines if anyone is interested:

int Xval = 0; // count to 30

int Yval = 1; // while loading rgb values

int Zval = 2; // into 3 led's at a time

author
fij7 (author)2015-11-20

Hey, is there any way to set this up for multiple monitors?

author
sam_conboy (author)fij72015-12-30

I want to find a way of it working for dual monitors, was wondering if setting the resolution to the size of both displays would mean that the screen cap covers both screens

author
cgmalantonio (author)sam_conboy2015-12-30

You would have to do some tweaking to the code but it should work just fine. Adjust the resolution of the screenshots to the resolution of both monitors combined. There might be a few more tweaks to make too but the code is easily understandable and it should not be too difficult to get working.

author
MarkH43 (author)2015-07-07

author
Simon-GabrielG (author)2015-04-03

Thanks for the tutorial! easy projets for great result!I was wondering if it was possible to make the prosseing ignore some of the whithe color to have a more colorful ledstrip the average of all color from a row tend to be grey that result in a white ledstrip.

author
MarcelW (author)2015-03-15

Hallo bei mir funktioniert der Sketch ganz gut außer das Rot und Grün vertauscht sind. Es wäre schön wenn mir jemand helfen könnte.

author
rmatkar made it! (author)2015-01-02

Nice tut... works perfectly the first time. However I did not understand why did u do

Changed the code to work with my 72 led neopixel strip.

colors.mp4
author
FlyBooster (author)2014-11-20

Hi, Amazing tuts ! congrats ;-)

It's possible to use NeoPixel Ring instead Strip ?

author
macdonaldj (author)2014-11-04

can you show how the strip is installed on back?

About This Instructable

20,532views

70favorites

License:

Bio: I am a recent graduate from the University of Pittsburgh. While i was there i got a Bachelors degree in Computer Science and explored a ... More »
More by cgmalantonio:Personal Black Box - Arduino Mega + Ultimate GPS Shield + LSM303Ambient Computer Lights - using an Arduino with NeoPixel stripArduino Motorized Window Blinds
Add instructable to: