I had some spare time today and managed to put up an ambient lighting using a single RGB LED and an Arduino UNO Micro controller.
There are many implementations of Arduino Ambient light setups like
http://siliconrepublic.blogspot.com/2011/02/arduino-based-pc-ambient-lighting.html
The above implementation is a really cool one which uses a +RGB LED Strip to create the ambient light effect from the PC's averaged screen color.
But sadly I didn't have a RGB LED Strip but only one RGB LED. So I tried to create the ambient light effect using the single RGB LED. So the setup is as following
The RGB LED is a common anode (positive) one so the 5v is connected to the common anode via a 1k resistor. And I use pin 9, 10, 11 with Pulse Width Modulation (PWM) for Blue, Green and Red cathodes (negative) respectively. I drive the PWM pins using the Arduino analogWrite(). But since the RGB pins are cathodes it negates the driving value. Meaning if I give a high value (255) it will dim the corresponding color and if I give a low value (0) it will increase the brightness of the corresponding color.
Sketch Code for Arduino UNO
In order to capture the Screen Averaged color I used the implementation from the above mentioned post yet I used Java instead of Processing because I am familiar with it. I used RXTX Library for COM port writing.
The Java Code is below
I used a White Paper Scroll to cover the RGB LED so that the light is evenly visible.
There are many implementations of Arduino Ambient light setups like
http://siliconrepublic.blogspot.com/2011/02/arduino-based-pc-ambient-lighting.html
The above implementation is a really cool one which uses a +RGB LED Strip to create the ambient light effect from the PC's averaged screen color.
But sadly I didn't have a RGB LED Strip but only one RGB LED. So I tried to create the ambient light effect using the single RGB LED. So the setup is as following
The RGB LED is a common anode (positive) one so the 5v is connected to the common anode via a 1k resistor. And I use pin 9, 10, 11 with Pulse Width Modulation (PWM) for Blue, Green and Red cathodes (negative) respectively. I drive the PWM pins using the Arduino analogWrite(). But since the RGB pins are cathodes it negates the driving value. Meaning if I give a high value (255) it will dim the corresponding color and if I give a low value (0) it will increase the brightness of the corresponding color.
Sketch Code for Arduino UNO
int bluePin = 9;
int greenPin = 10;
int redPin = 11;
int blueBrightness = 0;
int greenBrightness = 0;
int redBrightness = 0;
void setup() {
// Setting Up the COM Port
Serial.begin(9600);
// Changing PIN modes to OUTPUT
pinMode(bluePin, OUTPUT);
pinMode(greenPin, OUTPUT);
pinMode(redPin, OUTPUT);
}
void loop() {
if(Serial.available() >= 4) {
if(Serial.read() == 0xff) {
// 0, 0, 0 is Black
// 255, 255, 255 is White
redBrightness = Serial.read();
greenBrightness = Serial.read();
blueBrightness = Serial.read();
}
}
/*
Since the RGB LED has cathode pins for
RGB we need to deduct value from 255
meaning if the brightness is 255 from the
PC for a color we need to give 0 so that it
will eluminate brightly
*/
analogWrite(bluePin, 255 - blueBrightness);
analogWrite(greenPin, 255 - greenBrightness);
analogWrite(redPin, 255 - redBrightness);
delay(10);
}
In order to capture the Screen Averaged color I used the implementation from the above mentioned post yet I used Java instead of Processing because I am familiar with it. I used RXTX Library for COM port writing.
The Java Code is below
package com.shazin.ambientrgb;
/**
*
* @author Shazin Sadakath
*/
import gnu.io.CommPortIdentifier;
import gnu.io.SerialPort;
import java.awt.AWTException;
import java.awt.Robot;
import java.awt.image.BufferedImage;
import java.awt.Rectangle;
import java.awt.Dimension;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Enumeration;
import java.util.logging.Level;
import java.util.logging.Logger;
public class AmbientRGB implements Runnable {
private static Robot robot;
private static SerialPort port = null;
private static CommPortIdentifier cpi = null;
public static void main(String[] args) throws AWTException {
Enumeration enums = CommPortIdentifier.getPortIdentifiers();
robot = new Robot();
while (enums.hasMoreElements()) {
cpi = (CommPortIdentifier) enums.nextElement();
if ("COM27".equals(cpi.getName())) {
break;
}
}
if (cpi != null) {
try {
port = (SerialPort) cpi.open("ArduinoJavaBridge", 1000);
if (port != null) {
port.setSerialPortParams(9600,
SerialPort.DATABITS_8,
SerialPort.STOPBITS_1,
SerialPort.PARITY_NONE);
}
System.out.println("Ready!");
new Thread(new AmbientRGB()).start();
} catch (Exception e) {
Logger.getLogger(AmbientRGB.class.getName()).log(Level.SEVERE, null, e);
}
}
}
public void run() {
OutputStream os = null;
try {
os = port.getOutputStream();
} catch (IOException ex) {
Logger.getLogger(AmbientRGB.class.getName()).log(Level.SEVERE, null, ex);
}
while (true && os != null) {
int pixel;
float r = 0;
float g = 0;
float b = 0;
Rectangle rectangle = new Rectangle(new Dimension(1366, 768));
BufferedImage screenshot = robot.createScreenCapture(rectangle);
int i = 0;
int j = 0;
for (i = 0; i < rectangle.getWidth(); i = i + 2) {
for (j = 0; j < rectangle.getHeight(); j = j + 2) {
pixel = screenshot.getRGB(i, j);
r = r + (int) (255 & (pixel >> 16));
g = g + (int) (255 & (pixel >> 8));
b = b + (int) (255 & (pixel));
}
}
int totalPixels = (683 * 384);
r = r / totalPixels;
g = g / totalPixels;
b = b / totalPixels;
try {
os.write(0xff);
os.write((byte) (r));
os.write((byte) (g));
os.write((byte) (b));
os.flush();
Thread.sleep(10);
} catch (Exception ex) {
Logger.getLogger(AmbientRGB.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
}
I used a White Paper Scroll to cover the RGB LED so that the light is evenly visible.