Description:
For the third lab assignment, I built a circuit and wrote code to control three (RGB) LEDs using three potentiometers. For a more intuitive ability to mix colors, I mapped the three potentiometers not to the individual RGB LEDs, but to the three variables of the HSL (Hue, Saturation, Lightness) color space.
The HSL to RGB conversion is inspired by this Wikipedia article: http://en.wikipedia.org/wiki/HSL_color_space and the implementation was adapted from: http://stackoverflow.com/questions/2353211/hsl-to-rgb-color-conversion
Components used:
- (1) Arduino Uno
- (3) 220 Ohm resistors
- (3) Potentiometers
- (3) LEDs (red, green, blue)
- (1) Breadboard
- (several) cables
- (1) Skull diffusor (see last assignment)
Code used:
/*
* Enhanced "coffee-cup" HSL/RGB Color Mixer:
* Code for mixing and reporting PWM-mediated color
* Assumes Arduino 0004 or higher, as it uses Serial.begin()-style communication
*
* Control 3 LEDs with 3 potentiometers
* If the LEDs are different colors, and are directed at diffusing surface (stuck in a
* a Ping-Pong ball, or placed in a paper coffee cup with a cut-out bottom and
* a white plastic lid), the colors will mix together.
*
* The code was modified so that the three pots no longer represent the three color channels
* R(ed), G(reen) and B(lue), but to use the H(ue), S(aturation) and L(ightness). These inputs
* are then converted to the RGB color space and mixed from three LEDs.
*
* Both the HSL and the RGB color values are displayed to help to understand their relationship.
*
* The HSL to RGB conversion is inspired by this Wikipedia article: http://en.wikipedia.org/wiki/HSL_color_space
* and the implementation was adapted from: http://stackoverflow.com/questions/2353211/hsl-to-rgb-color-conversion
*
*/
// Analog pin settings
float aIn = 0; // Potentiometers connected to analog pins 0, 1, and 2
float bIn = 1; // (Connect power to 5V and ground to analog ground)
float cIn = 2;
// Digital pin settings
int aOut = 9; // LEDs connected to digital pins 9, 10 and 11
int bOut = 10; // (Connect cathodes to digital ground)
int cOut = 11;
// Values
float aVal = 0; // Variables to store the input from the potentiometers
float bVal = 0;
float cVal = 0;
// RGB Values
int r = 0; // Variables to store the RGB color values
int b = 0;
int g = 0;
int rgb[3];
// Variables for comparing values between loops
int i = 0; // Loop counter
int wait = (1000); // Delay between most recent pot adjustment and output
int checkSum = 0; // Aggregate pot values
int prevCheckSum = 0;
int sens = 0; // Sensitivity theshold, to prevent small changes in
// pot values from triggering false reporting
// FLAGS
int PRINT = 1; // Set to 1 to output values
int DEBUG = 0; // Set to 1 to turn on debugging output
void setup()
{
pinMode(aOut, OUTPUT); // sets the digital pins as output
pinMode(bOut, OUTPUT);
pinMode(cOut, OUTPUT);
Serial.begin(9600); // Open serial communication for reporting
}
void loop()
{
i += 1; // Count loop
aVal = analogRead(aIn); // Read input pins
bVal = analogRead(bIn);
cVal = analogRead(cIn);
aVal /= 1023; // Convert to [0-1] scale
bVal /= 1023;
cVal /= 1023;
hsl2rgb(aVal,bVal,cVal,rgb); // Convert HSL to RGB values
analogWrite(aOut, rgb[0]); // Send new values to LEDs
analogWrite(bOut, rgb[1]);
analogWrite(cOut, rgb[2]);
if (i % wait == 0) // If enough time has passed...
{
checkSum = aVal+bVal+cVal; // ...add up the 3 values.
if ( abs(checkSum - prevCheckSum) > sens ) // If old and new values differ
// above sensitivity threshold
{
if (PRINT) // ...and if the PRINT flag is set...
{
Serial.print("H: "); // ...then print the HSL and RGB values.
Serial.print(aVal);
Serial.print("\t");
Serial.print("S: ");
Serial.print(bVal);
Serial.print("\t");
Serial.print("L: ");
Serial.print(cVal);
Serial.print("\t\t");
Serial.print("R: ");
Serial.print(rgb[0]);
Serial.print("\t");
Serial.print("G: ");
Serial.print(rgb[1]);
Serial.print("\t");
Serial.print("B: ");
Serial.println(rgb[2]);
PRINT = 0;
}
}
else
{
PRINT = 1; // Re-set the flag
}
prevCheckSum = checkSum; // Update the values
if (DEBUG) // If we want debugging output as well...
{
Serial.print(checkSum);
Serial.print("<=>");
Serial.print(prevCheckSum);
Serial.print("\tPrint: ");
Serial.println(PRINT);
}
}
}
// HSL to RGB conversion adapted from http://stackoverflow.com/questions/2353211/hsl-to-rgb-color-conversion and http://en.wikipedia.org/wiki/HSL_color_space
int hsl2rgb (float h, float s, float l, int rgb[]) {
// Variables for conversion
float q = 0;
float t = 0;
if (s == 0) {
r = g = b = l; //achromatic
} else {
if (l < 0.5) {
q = l * (1 + s);
} else {
q = l + s - l * s;
}
float p = 2 * l - q;
r = hue2rgb(p, q, h + 0.33) * 255;
g = hue2rgb(p, q, h) * 255;
b = hue2rgb(p, q, h - 0.33) * 255;
}
rgb[0] = r;
rgb[1] = g;
rgb[2] = b;
}
float hue2rgb (float p, float q, float t) {
if(t < 0) {t += 1;}
if(t > 1) {t -= 1;}
if(t < 0.17) {return p + (q - p) * 6 * t;}
if(t < 0.5) {return q;}
if(t < 0.67) {return p + (q - p) * (0.67 - t) * 6;}
return p;
}
- Login to post comments