This
instructable is a quick write-up of my experience creating a
multifunctional moodlight. Some basic knowledge of electronic circuits
is expected. The project has not yet finished, some adding
functionality and tweaking has to be done but it is already functional.
If you guys are enthousiast about this instructable I will update it.
At the heart of the system is an Arduino. It will process the input from USB or each of the Capacitive touch inputs and control the RGB light.
This instructable is split into three sections:
- The capacitive touch section covers the invisible input buttons
- The moodlight section covers the controlling of the moodlight
- The ambilight section covers input by serial port, processing RGB values generated by a computer program to control the lights.
Disclaimer: Electronics can be dangerous, you yourself are responsible for any damage done. Some code is collected from forums and might not contain the name of its owner. Please let me know and I'll add your name.
At the heart of the system is an Arduino. It will process the input from USB or each of the Capacitive touch inputs and control the RGB light.
This instructable is split into three sections:
- The capacitive touch section covers the invisible input buttons
- The moodlight section covers the controlling of the moodlight
- The ambilight section covers input by serial port, processing RGB values generated by a computer program to control the lights.
Disclaimer: Electronics can be dangerous, you yourself are responsible for any damage done. Some code is collected from forums and might not contain the name of its owner. Please let me know and I'll add your name.
Step 1: Item list
The following components are needed for this instructable:
- Arduino+USB cable
- Breadboard
- Computer power supply
- 3x RGB strips, check out dealextreme.com.
- 3x TIP120 FETs, like http://uk.farnell.com/stmicroelectronics/tip120/darlington-transistor-to-220/dp/9804005
- A bunch of resistors (6* 10 kiloOhm, 3 * 2 megaOhm)
- A lot of wire.
- Tools
Capacitive touch
- Metal rings for groundplates
- Copper wire or plate
- Something to build it into (like a bookshelf:)
- Arduino+USB cable
- Breadboard
- Computer power supply
- 3x RGB strips, check out dealextreme.com.
- 3x TIP120 FETs, like http://uk.farnell.com/stmicroelectronics/tip120/darlington-transistor-to-220/dp/9804005
- A bunch of resistors (6* 10 kiloOhm, 3 * 2 megaOhm)
- A lot of wire.
- Tools
Capacitive touch
- Metal rings for groundplates
- Copper wire or plate
- Something to build it into (like a bookshelf:)
Step 2: Capacitive Touch - Basics & Circuit
Since
I was painting my bookshelfs, I had the oppurtunity to 'upgrade' them
as well. I wanted to control the moodlight by means of invisible touch.
At first, my plan was to use a dedicated IC for this (like the Atmel
QT240). But then I stumbled upon a page explaining that the Arduino can
emulate a capacitive sensor by software.
The electronic circuit can be found in the picture, the sensor is a spiralled copper wire (only one is shown for simplicity). Sensitivity is controlled by the resistors found before every pin. They can range from 1 MegaOhm (absolute touch) to 40 MegaOhm (12-24 inch away) depending on if absolute or near touch is needed (I ended up using 2M Ohm resistors). Experiment with the values until the sensor behaves like desired. It is a good idea to install some conducting surface (seperated by a thin non-conducting piece) connected to the circuits' ground at the back of each spiral. This way the sensors will be more stable and less influenced by noise.
Some more pictures about installing the sensors in a bookshelf. A plug is installed as well for easy connection with the circuit later on. Filler is used to conceal everything, and after that they are ready to be painted.
The electronic circuit can be found in the picture, the sensor is a spiralled copper wire (only one is shown for simplicity). Sensitivity is controlled by the resistors found before every pin. They can range from 1 MegaOhm (absolute touch) to 40 MegaOhm (12-24 inch away) depending on if absolute or near touch is needed (I ended up using 2M Ohm resistors). Experiment with the values until the sensor behaves like desired. It is a good idea to install some conducting surface (seperated by a thin non-conducting piece) connected to the circuits' ground at the back of each spiral. This way the sensors will be more stable and less influenced by noise.
Some more pictures about installing the sensors in a bookshelf. A plug is installed as well for easy connection with the circuit later on. Filler is used to conceal everything, and after that they are ready to be painted.
Step 3: Capacitive Touch - Code & Testing
The
following source code can be used on the Arduino for debugging, check
the values with the arduino serial monitor. Six values are generated.
The first is a measure of the performance of the system. The second to
sixth are the sensed values on every pin. The values should rise when
nearing your finger. If not, check for bad connections and interference.
The resistor values can be changed to determine sensitivity. By
implementing an if-then structure which is activated at a certain
logical treshold, a switch can be made. This will be used in the final
arduino code.
More information, suggested to read: http://www.arduino.cc/playground/Main/CapSense
--- Arduino CapTouch Debugging Code ---
#include
void setup() {
CapSense cs_2_3 = CapSense(2,4); // 10M resistor between pins 2 & 4, pin 4 is sensor pin, add wire, foil
CapSense cs_2_4 = CapSense(2,7); // 10M resistor between pins 2 & 7, pin 7 is sensor pin, add wire, foil
CapSense cs_2_5 = CapSense(2,8); // 10M resistor between pins 2 & 8, pin 8 is sensor pin, add wire, foil
CapSense cs_2_6 = CapSense(2,12); // 10M resistor between pins 2 & 12, pin 12 is sensor pin, add wire, foil
CapSense cs_2_7 = CapSense(2,13); // 10M resistor between pins 2 & 13, pin 13 is sensor pin, add wire, foil
void setup()
{
Serial.begin(9600);
}
void loop()
{
long start = millis();
long total1 = cs_2_3.capSense(30);
long total2 = cs_2_4.capSense(30);
long total3 = cs_2_5.capSense(30);
long total4 = cs_2_6.capSense(30);
long total5 = cs_2_7.capSense(30);
Serial.print(millis() - start); // check on performance in milliseconds
Serial.print("\t"); // tab character for debug windown spacing
Serial.print(total1); // print sensor output 1
Serial.print("\t");
Serial.print(total2); // print sensor output 2
Serial.print("\t");
Serial.print(total3); // print sensor output 3
Serial.print("\t");
Serial.print(total4); // print sensor output 4
Serial.print("\t");
Serial.println(total5); // print sensor output 5
delay(10); // arbitrary delay to limit data to serial port
}
--- END ---
More information, suggested to read: http://www.arduino.cc/playground/Main/CapSense
--- Arduino CapTouch Debugging Code ---
#include
void setup() {
CapSense cs_2_3 = CapSense(2,4); // 10M resistor between pins 2 & 4, pin 4 is sensor pin, add wire, foil
CapSense cs_2_4 = CapSense(2,7); // 10M resistor between pins 2 & 7, pin 7 is sensor pin, add wire, foil
CapSense cs_2_5 = CapSense(2,8); // 10M resistor between pins 2 & 8, pin 8 is sensor pin, add wire, foil
CapSense cs_2_6 = CapSense(2,12); // 10M resistor between pins 2 & 12, pin 12 is sensor pin, add wire, foil
CapSense cs_2_7 = CapSense(2,13); // 10M resistor between pins 2 & 13, pin 13 is sensor pin, add wire, foil
void setup()
{
Serial.begin(9600);
}
void loop()
{
long start = millis();
long total1 = cs_2_3.capSense(30);
long total2 = cs_2_4.capSense(30);
long total3 = cs_2_5.capSense(30);
long total4 = cs_2_6.capSense(30);
long total5 = cs_2_7.capSense(30);
Serial.print(millis() - start); // check on performance in milliseconds
Serial.print("\t"); // tab character for debug windown spacing
Serial.print(total1); // print sensor output 1
Serial.print("\t");
Serial.print(total2); // print sensor output 2
Serial.print("\t");
Serial.print(total3); // print sensor output 3
Serial.print("\t");
Serial.print(total4); // print sensor output 4
Serial.print("\t");
Serial.println(total5); // print sensor output 5
delay(10); // arbitrary delay to limit data to serial port
}
--- END ---
Step 4: Mood light - Basics & Circuit
Now
it is time to build the output part of the system. The arduino's PWM
pins will be used to control each colour. PWM means Pulse Width
Modulation, by switching a pin on and off very quickly the leds will be
dimmed from 0 to 255. Every pin will be amplified by a FET. For now, the
system has only one channel per color, meaning that all RGB strips
will be controlled at once and 3 PWM pins are needed (one for every
colour). In the future I want to be able to control each of my four RGB
strips. That means 4*3=12 PWM pins (and probably an Arduino Mega).
Ok, time for some schematics! This (see picture) is a basic representation of the circuit (will make a nicer one soon). The capacitive sensors are included as well (green part). Basically there are three components that have to be explained:
- FET
This is the amplifier I was talking about. It has a Gate, a Source and a Drain. It amplifies the senses a small current on the gate (connected to the Arduino) and opens the way for the RGB strip that is driven on 12 volts. Source should be on +12V, drain on GND (Ground). Check the specifcations sheet of your FET for exact pinout. Every RGB channel should be positioned before its own FET. In this sense, it is acting like an Arduino controlled switch.
- RGB strip
This 12 volts RGB strip is of the common anode (+) type. Meaning, that the common wire should be connected to +12V and the current is sinked through each of the seperate colour channels. The strip has incorporated resistors, so no worries about that!
- Resistors
Three 10k resistors will make sure that the FET won't turn on when they are not supposed to turn on. Three others will limit the maximum current the FET will drain. The top three resistors are already in the RGB strip.
I soldered USB cables to the RGB strips so I can modularly connect them easily. Plugs from an old hub are placed on my breadboard. Use an old computer power supply for juice, 12V for powering the RGB strip and eventually 5V for the circuit if you want it to run without the USB cable.
Ok, time for some schematics! This (see picture) is a basic representation of the circuit (will make a nicer one soon). The capacitive sensors are included as well (green part). Basically there are three components that have to be explained:
- FET
This is the amplifier I was talking about. It has a Gate, a Source and a Drain. It amplifies the senses a small current on the gate (connected to the Arduino) and opens the way for the RGB strip that is driven on 12 volts. Source should be on +12V, drain on GND (Ground). Check the specifcations sheet of your FET for exact pinout. Every RGB channel should be positioned before its own FET. In this sense, it is acting like an Arduino controlled switch.
- RGB strip
This 12 volts RGB strip is of the common anode (+) type. Meaning, that the common wire should be connected to +12V and the current is sinked through each of the seperate colour channels. The strip has incorporated resistors, so no worries about that!
- Resistors
Three 10k resistors will make sure that the FET won't turn on when they are not supposed to turn on. Three others will limit the maximum current the FET will drain. The top three resistors are already in the RGB strip.
I soldered USB cables to the RGB strips so I can modularly connect them easily. Plugs from an old hub are placed on my breadboard. Use an old computer power supply for juice, 12V for powering the RGB strip and eventually 5V for the circuit if you want it to run without the USB cable.
Step 5: Mood light - Code & Control
The
mood light is controlled by the capacitive sensors. For now, I only
programmed sensors 2 & 3 for colour changing. The other sensors have
no function as of yet. Here is the code:
--- Arduino Mood Control Code ---
#include
const boolean invert = true;
const long timeout = 10000;
// Capacitive sensor declaration
CapSense In1 = CapSense(2,4); // 2M resistor between pins 4 & 2, pin 2 is sensor pin, add wire, foil
CapSense In2 = CapSense(2,7); // 2M resistor between pins 4 & 6, pin 6 is sensor pin, add wire, foil
CapSense In3 = CapSense(2,8); // 2M resistor between pins 4 & 8, pin 8 is sensor pin, add wire, foil
CapSense In4 = CapSense(2,12); // 2M resistor between pins 4 & 8, pin 8 is sensor pin, add wire, foil
CapSense In5 = CapSense(2,13); // 2M resistor between pins 4 & 8, pin 8 is sensor pin, add wire, foil
// PWM Pin declarations
int PinR1 = 3;
int PinG1 = 5;
int PinB1 = 6;
// Other variables
int Color1 = 128; // start at a red like colour
int Brightness1 = 255; // start at full brightness
int RedValue1, GreenValue1, BlueValue1; // The RGB components
void setup()
{ // set sensor timeout values
In1.set_CS_AutocaL_Millis(timeout);
In2.set_CS_AutocaL_Millis(timeout);
In3.set_CS_AutocaL_Millis(timeout);
In4.set_CS_AutocaL_Millis(timeout);
In5.set_CS_AutocaL_Millis(timeout);
}
void loop()
{
long start = millis();
long total1 = In1.capSense(30);
long total2 = In2.capSense(30);
long total3 = In3.capSense(30);
long total4 = In4.capSense(30);
long total5 = In5.capSense(30);
if (total2 > 150) {
Color1++; // increment the color
if(Color1 > 255) { //
Color1 = 0;
}
} else if (total3 > 200) {
Color1--; // decrement the color
if(Color1 < 0) { //
Color1 = 255;
}
// convert hue to rgb
hueToRGB(Color1, Brightness1);
// write colors to PWM pins
analogWrite(PinR1, RedValue1);
analogWrite(PinG1, GreenValue1);
analogWrite(PinB1, BlueValue1);
}
// function to convert a color to its Red, Green, and Blue components.
void hueToRGB(int hue, int brightness)
{
unsigned int scaledHue = (hue * 6);
unsigned int segment = scaledHue / 256; // segment 0 to 5 around the color wheel
unsigned int segmentOffset = scaledHue - (segment * 256); // position within the segment
unsigned int compliment = 0;
unsigned int prev = (brightness * ( 255 - segmentOffset)) / 256;
unsigned int next = (brightness * segmentOffset) / 256;
if(invert)
{
brightness = 255-brightness;
compliment = 255;
prev = 255-prev;
next = 255-next;
}
switch(segment ) {
case 0: // red
RedValue1 = brightness;
GreenValue1 = next;
BlueValue1 = compliment;
break;
case 1: // yellow
RedValue1 = prev;
GreenValue1 = brightness;
BlueValue1 = compliment;
break;
case 2: // green
RedValue1 = compliment;
GreenValue1 = brightness;
BlueValue1 = next;
break;
case 3: // cyan
RedValue1 = compliment;
GreenValue1 = prev;
BlueValue1 = brightness;
break;
case 4: // blue
RedValue1 = next;
GreenValue1 = compliment;
BlueValue1 = brightness;
break;
case 5: // magenta
default:
RedValue1 = brightness;
GreenValue1 = compliment;
BlueValue1 = prev;
break;
}
}
--- END ---
--- Arduino Mood Control Code ---
#include
const boolean invert = true;
const long timeout = 10000;
// Capacitive sensor declaration
CapSense In1 = CapSense(2,4); // 2M resistor between pins 4 & 2, pin 2 is sensor pin, add wire, foil
CapSense In2 = CapSense(2,7); // 2M resistor between pins 4 & 6, pin 6 is sensor pin, add wire, foil
CapSense In3 = CapSense(2,8); // 2M resistor between pins 4 & 8, pin 8 is sensor pin, add wire, foil
CapSense In4 = CapSense(2,12); // 2M resistor between pins 4 & 8, pin 8 is sensor pin, add wire, foil
CapSense In5 = CapSense(2,13); // 2M resistor between pins 4 & 8, pin 8 is sensor pin, add wire, foil
// PWM Pin declarations
int PinR1 = 3;
int PinG1 = 5;
int PinB1 = 6;
// Other variables
int Color1 = 128; // start at a red like colour
int Brightness1 = 255; // start at full brightness
int RedValue1, GreenValue1, BlueValue1; // The RGB components
void setup()
{ // set sensor timeout values
In1.set_CS_AutocaL_Millis(timeout);
In2.set_CS_AutocaL_Millis(timeout);
In3.set_CS_AutocaL_Millis(timeout);
In4.set_CS_AutocaL_Millis(timeout);
In5.set_CS_AutocaL_Millis(timeout);
}
void loop()
{
long start = millis();
long total1 = In1.capSense(30);
long total2 = In2.capSense(30);
long total3 = In3.capSense(30);
long total4 = In4.capSense(30);
long total5 = In5.capSense(30);
if (total2 > 150) {
Color1++; // increment the color
if(Color1 > 255) { //
Color1 = 0;
}
} else if (total3 > 200) {
Color1--; // decrement the color
if(Color1 < 0) { //
Color1 = 255;
}
// convert hue to rgb
hueToRGB(Color1, Brightness1);
// write colors to PWM pins
analogWrite(PinR1, RedValue1);
analogWrite(PinG1, GreenValue1);
analogWrite(PinB1, BlueValue1);
}
// function to convert a color to its Red, Green, and Blue components.
void hueToRGB(int hue, int brightness)
{
unsigned int scaledHue = (hue * 6);
unsigned int segment = scaledHue / 256; // segment 0 to 5 around the color wheel
unsigned int segmentOffset = scaledHue - (segment * 256); // position within the segment
unsigned int compliment = 0;
unsigned int prev = (brightness * ( 255 - segmentOffset)) / 256;
unsigned int next = (brightness * segmentOffset) / 256;
if(invert)
{
brightness = 255-brightness;
compliment = 255;
prev = 255-prev;
next = 255-next;
}
switch(segment ) {
case 0: // red
RedValue1 = brightness;
GreenValue1 = next;
BlueValue1 = compliment;
break;
case 1: // yellow
RedValue1 = prev;
GreenValue1 = brightness;
BlueValue1 = compliment;
break;
case 2: // green
RedValue1 = compliment;
GreenValue1 = brightness;
BlueValue1 = next;
break;
case 3: // cyan
RedValue1 = compliment;
GreenValue1 = prev;
BlueValue1 = brightness;
break;
case 4: // blue
RedValue1 = next;
GreenValue1 = compliment;
BlueValue1 = brightness;
break;
case 5: // magenta
default:
RedValue1 = brightness;
GreenValue1 = compliment;
BlueValue1 = prev;
break;
}
}
--- END ---
Step 6: Ambi light - Arduino side
Of
course, it would be totally cool to be able to control the mood light
from your computer. For example to create an ambilight or a sound
controlled disco. This section focusses on the ambilight part, in the
future I will add more functionality.
Well, there's no additional circuitry because it is all available in the Arduino. What we are going to use is the serial communiction capabilities and some 'Processing 1.0' software. Hook-up your arduino to your computer by an USB cable (if you were uploading sketches to it, it already is).
For the arduino, well have to add some extra code for serial communication. The code will switch to listen mode, turning of the capacitive sensors as long as it receives RGB values from the computer. It then sets the RGB values to the PWM pins. This is my final code for now, check for the changes yourself:
--- Arduino Ambilight Code ---
#include
const boolean invert = true;
const long timeout = 10000;
long commStart = 0;
char val;
// Capacitive sensor declaration
CapSense In1 = CapSense(2,4); // 2M resistor between pins 4 & 2, pin 2 is sensor pin, add wire, foil
CapSense In2 = CapSense(2,7); // 2M resistor between pins 4 & 6, pin 6 is sensor pin, add wire, foil
CapSense In3 = CapSense(2,8); // 2M resistor between pins 4 & 8, pin 8 is sensor pin, add wire, foil
CapSense In4 = CapSense(2,12); // 2M resistor between pins 4 & 8, pin 8 is sensor pin, add wire, foil
CapSense In5 = CapSense(2,13); // 2M resistor between pins 4 & 8, pin 8 is sensor pin, add wire, foil
// PWM Pin declarations
int PinR1 = 3;
int PinG1 = 5;
int PinB1 = 6;
// Other variables
int Color1 = 128; // start at a red like colour
int Brightness1 = 255; // start at full brightness
int RedValue1, GreenValue1, BlueValue1; // The RGB components
void setup()
{
Serial.begin(9600); // start serial communiction
// set sensor timeout values
In1.set_CS_AutocaL_Millis(timeout);
In2.set_CS_AutocaL_Millis(timeout);
In3.set_CS_AutocaL_Millis(timeout);
In4.set_CS_AutocaL_Millis(timeout);
In5.set_CS_AutocaL_Millis(timeout);
}
void loop()
{
long start = millis();
long total1 = In1.capSense(30);
long total2 = In2.capSense(30);
long total3 = In3.capSense(30);
long total4 = In4.capSense(30);
long total5 = In5.capSense(30);
if (Serial.available()) { // If data is available to read,
val = Serial.read(); // read it and store it in val
commStart = millis();
if (val == 'S') { //If start char is recieved,
while (!Serial.available()) {} //Wait until next value.
RedValue1 = Serial.read(); //Once available, assign.
while (!Serial.available()) {} //Same as above.
GreenValue1 = Serial.read();
while (!Serial.available()) {}
BlueValue1 = Serial.read();
}
Serial.print(RedValue1);
Serial.print(GreenValue1);
Serial.println(BlueValue1);
} else if ((millis() - commStart) > 1000) {
if (total2 > 150) {
Color1++; // increment the color
if(Color1 > 255) { //
Color1 = 0;
}
} else if (total3 > 200) {
Color1--; // decrement the color
if(Color1 < 0) { //
Color1 = 255;
}
}
hueToRGB(Color1, Brightness1);
}
analogWrite(PinR1, RedValue1);
analogWrite(PinG1, GreenValue1);
analogWrite(PinB1, BlueValue1);
}
// function to convert a color to its Red, Green, and Blue components.
void hueToRGB(int hue, int brightness)
{
unsigned int scaledHue = (hue * 6);
unsigned int segment = scaledHue / 256; // segment 0 to 5 around the color wheel
unsigned int segmentOffset = scaledHue - (segment * 256); // position within the segment
unsigned int compliment = 0;
unsigned int prev = (brightness * ( 255 - segmentOffset)) / 256;
unsigned int next = (brightness * segmentOffset) / 256;
if(invert)
{
brightness = 255-brightness;
compliment = 255;
prev = 255-prev;
next = 255-next;
}
switch(segment ) {
case 0: // red
RedValue1 = brightness;
GreenValue1 = next;
BlueValue1 = compliment;
break;
case 1: // yellow
RedValue1 = prev;
GreenValue1 = brightness;
BlueValue1 = compliment;
break;
case 2: // green
RedValue1 = compliment;
GreenValue1 = brightness;
BlueValue1 = next;
break;
case 3: // cyan
RedValue1 = compliment;
GreenValue1 = prev;
BlueValue1 = brightness;
break;
case 4: // blue
RedValue1 = next;
GreenValue1 = compliment;
BlueValue1 = brightness;
break;
case 5: // magenta
default:
RedValue1 = brightness;
GreenValue1 = compliment;
BlueValue1 = prev;
break;
}
}
--- END ---
Well, there's no additional circuitry because it is all available in the Arduino. What we are going to use is the serial communiction capabilities and some 'Processing 1.0' software. Hook-up your arduino to your computer by an USB cable (if you were uploading sketches to it, it already is).
For the arduino, well have to add some extra code for serial communication. The code will switch to listen mode, turning of the capacitive sensors as long as it receives RGB values from the computer. It then sets the RGB values to the PWM pins. This is my final code for now, check for the changes yourself:
--- Arduino Ambilight Code ---
#include
const boolean invert = true;
const long timeout = 10000;
long commStart = 0;
char val;
// Capacitive sensor declaration
CapSense In1 = CapSense(2,4); // 2M resistor between pins 4 & 2, pin 2 is sensor pin, add wire, foil
CapSense In2 = CapSense(2,7); // 2M resistor between pins 4 & 6, pin 6 is sensor pin, add wire, foil
CapSense In3 = CapSense(2,8); // 2M resistor between pins 4 & 8, pin 8 is sensor pin, add wire, foil
CapSense In4 = CapSense(2,12); // 2M resistor between pins 4 & 8, pin 8 is sensor pin, add wire, foil
CapSense In5 = CapSense(2,13); // 2M resistor between pins 4 & 8, pin 8 is sensor pin, add wire, foil
// PWM Pin declarations
int PinR1 = 3;
int PinG1 = 5;
int PinB1 = 6;
// Other variables
int Color1 = 128; // start at a red like colour
int Brightness1 = 255; // start at full brightness
int RedValue1, GreenValue1, BlueValue1; // The RGB components
void setup()
{
Serial.begin(9600); // start serial communiction
// set sensor timeout values
In1.set_CS_AutocaL_Millis(timeout);
In2.set_CS_AutocaL_Millis(timeout);
In3.set_CS_AutocaL_Millis(timeout);
In4.set_CS_AutocaL_Millis(timeout);
In5.set_CS_AutocaL_Millis(timeout);
}
void loop()
{
long start = millis();
long total1 = In1.capSense(30);
long total2 = In2.capSense(30);
long total3 = In3.capSense(30);
long total4 = In4.capSense(30);
long total5 = In5.capSense(30);
if (Serial.available()) { // If data is available to read,
val = Serial.read(); // read it and store it in val
commStart = millis();
if (val == 'S') { //If start char is recieved,
while (!Serial.available()) {} //Wait until next value.
RedValue1 = Serial.read(); //Once available, assign.
while (!Serial.available()) {} //Same as above.
GreenValue1 = Serial.read();
while (!Serial.available()) {}
BlueValue1 = Serial.read();
}
Serial.print(RedValue1);
Serial.print(GreenValue1);
Serial.println(BlueValue1);
} else if ((millis() - commStart) > 1000) {
if (total2 > 150) {
Color1++; // increment the color
if(Color1 > 255) { //
Color1 = 0;
}
} else if (total3 > 200) {
Color1--; // decrement the color
if(Color1 < 0) { //
Color1 = 255;
}
}
hueToRGB(Color1, Brightness1);
}
analogWrite(PinR1, RedValue1);
analogWrite(PinG1, GreenValue1);
analogWrite(PinB1, BlueValue1);
}
// function to convert a color to its Red, Green, and Blue components.
void hueToRGB(int hue, int brightness)
{
unsigned int scaledHue = (hue * 6);
unsigned int segment = scaledHue / 256; // segment 0 to 5 around the color wheel
unsigned int segmentOffset = scaledHue - (segment * 256); // position within the segment
unsigned int compliment = 0;
unsigned int prev = (brightness * ( 255 - segmentOffset)) / 256;
unsigned int next = (brightness * segmentOffset) / 256;
if(invert)
{
brightness = 255-brightness;
compliment = 255;
prev = 255-prev;
next = 255-next;
}
switch(segment ) {
case 0: // red
RedValue1 = brightness;
GreenValue1 = next;
BlueValue1 = compliment;
break;
case 1: // yellow
RedValue1 = prev;
GreenValue1 = brightness;
BlueValue1 = compliment;
break;
case 2: // green
RedValue1 = compliment;
GreenValue1 = brightness;
BlueValue1 = next;
break;
case 3: // cyan
RedValue1 = compliment;
GreenValue1 = prev;
BlueValue1 = brightness;
break;
case 4: // blue
RedValue1 = next;
GreenValue1 = compliment;
BlueValue1 = brightness;
break;
case 5: // magenta
default:
RedValue1 = brightness;
GreenValue1 = compliment;
BlueValue1 = prev;
break;
}
}
--- END ---
Step 7: Ambi light - Computer side
On the side of the computer a Processing 1.0 sketch is run, see processing.org
. This little (somewhat messy) program calculates the average
screencolor at every instant and sends this to the serial port. It is
very basic as of yet and it could use some tweaking, but it works very
well! I will update it in the future for multiple separate RGB strips
and screen sections. You could also do that yourself, the language is
quite straightforward.
Here is the code:
--- Processing 1.0 Code ---
import processing.serial.*;
import java.awt.AWTException;
import java.awt.Robot;
import java.awt.Rectangle;
import java.awt.image.BufferedImage;
PImage screenShot;
Serial myPort;
static public void main(String args[]) {
PApplet.main(new String[] {
"--present", "shooter" }
);
}
void setup() {
size(100,100); //size(screen.width, screen.height);
// Print a list of the serial ports, for debugging purposes:
println(Serial.list());
// I know that the first port in the serial list on my mac
// is always my FTDI adaptor, so I open Serial.list()[0].
// On Windows machines, this generally opens COM1.
// Open whatever port is the one you're using.
String portName = Serial.list()[0];
myPort = new Serial(this, portName, 9600);
}
void draw () {
//image(screenShot,0,0, width, height);
screenShot = getScreen();
color kleur = color(0,0,0);
kleur = colour(screenShot);
//myPort.write(int(red(kleur))+','+int(green(kleur))+','+int(blue(kleur))+13);
//myPort.write(int(red(kleur)));
//myPort.write(',');
//myPort.write(int(green(kleur)));
//myPort.write(',');
//myPort.write(int(blue(kleur)));
//myPort.write(13);
fill(kleur);
rect(30, 20, 55, 55);
}
color colour(PImage img) {
int cols = (img.width);
int rows = (img.height);
int dimension = (img.width*img.height);
int r = 0;
int g = 0;
int b = 0;
img.loadPixels();
// Ga elke pixel langs (dimension)
for (int i = 0; i < (dimension/2); i++) {
r = r + ((img.pixels[i] >> 16) & 0xFF);
g = g + ((img.pixels[i] >> 8) & 0xFF);
b = b + (img.pixels[i] & 0xFF);
}
int mean_r = r/(dimension/2);
int mean_g = g/(dimension/2);
int mean_b = b/(dimension/2);
color mean_clr = color(mean_r, mean_g, mean_b);
myPort.write('S');
myPort.write(mean_r);
myPort.write(mean_g);
myPort.write(mean_b);
return (mean_clr);
}
PImage getScreen() {
GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
GraphicsDevice[] gs = ge.getScreenDevices();
DisplayMode mode = gs[0].getDisplayMode();
Rectangle bounds = new Rectangle(0, 0, mode.getWidth(), mode.getHeight());
BufferedImage desktop = new BufferedImage(mode.getWidth(), mode.getHeight(), BufferedImage.TYPE_INT_RGB);
try {
desktop = new Robot(gs[0]).createScreenCapture(bounds);
}
catch(AWTException e) {
System.err.println("Screen capture failed.");
}
return (new PImage(desktop));
}
--- END ---
Here is the code:
--- Processing 1.0 Code ---
import processing.serial.*;
import java.awt.AWTException;
import java.awt.Robot;
import java.awt.Rectangle;
import java.awt.image.BufferedImage;
PImage screenShot;
Serial myPort;
static public void main(String args[]) {
PApplet.main(new String[] {
"--present", "shooter" }
);
}
void setup() {
size(100,100); //size(screen.width, screen.height);
// Print a list of the serial ports, for debugging purposes:
println(Serial.list());
// I know that the first port in the serial list on my mac
// is always my FTDI adaptor, so I open Serial.list()[0].
// On Windows machines, this generally opens COM1.
// Open whatever port is the one you're using.
String portName = Serial.list()[0];
myPort = new Serial(this, portName, 9600);
}
void draw () {
//image(screenShot,0,0, width, height);
screenShot = getScreen();
color kleur = color(0,0,0);
kleur = colour(screenShot);
//myPort.write(int(red(kleur))+','+int(green(kleur))+','+int(blue(kleur))+13);
//myPort.write(int(red(kleur)));
//myPort.write(',');
//myPort.write(int(green(kleur)));
//myPort.write(',');
//myPort.write(int(blue(kleur)));
//myPort.write(13);
fill(kleur);
rect(30, 20, 55, 55);
}
color colour(PImage img) {
int cols = (img.width);
int rows = (img.height);
int dimension = (img.width*img.height);
int r = 0;
int g = 0;
int b = 0;
img.loadPixels();
// Ga elke pixel langs (dimension)
for (int i = 0; i < (dimension/2); i++) {
r = r + ((img.pixels[i] >> 16) & 0xFF);
g = g + ((img.pixels[i] >> 8) & 0xFF);
b = b + (img.pixels[i] & 0xFF);
}
int mean_r = r/(dimension/2);
int mean_g = g/(dimension/2);
int mean_b = b/(dimension/2);
color mean_clr = color(mean_r, mean_g, mean_b);
myPort.write('S');
myPort.write(mean_r);
myPort.write(mean_g);
myPort.write(mean_b);
return (mean_clr);
}
PImage getScreen() {
GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
GraphicsDevice[] gs = ge.getScreenDevices();
DisplayMode mode = gs[0].getDisplayMode();
Rectangle bounds = new Rectangle(0, 0, mode.getWidth(), mode.getHeight());
BufferedImage desktop = new BufferedImage(mode.getWidth(), mode.getHeight(), BufferedImage.TYPE_INT_RGB);
try {
desktop = new Robot(gs[0]).createScreenCapture(bounds);
}
catch(AWTException e) {
System.err.println("Screen capture failed.");
}
return (new PImage(desktop));
}
--- END ---
Step 8: Result
And this is the result, it is actually at the bottom side of my bed. I still need to replace the cloth, it will diffuse the light more. More pictures on that soon.I hope you like this instructable and I also hope it is a base for your own creativity. Because of time-constraints I wrote it very quickly. You might need to have some basic arduino/electronics knowledge to understand it but I plan to update it in the future if it is well received.
0 comments:
Post a Comment