One of my upcoming projects will require me to control an RGB LED with a single potentiometer.
Scouting the internet for relevant code came out a tad fruitless as most code had poor transitions between each RGB value, as you could see each LED momentarily turning OFF between major transitions.
/////////////////////////////////////////////////////////////////////////////////////////////
// RGB LED control - v1.1 //
// //
// A simple program for controlling an RGB led with a single potentiometer. //
// As per I/O pins below, the RED pin of the RGB LED is connected to pin #9 of the Arduino //
// GREEN pin to pin #10, and BLUE pin to pin #11. Also the output of the potentiomenter is //
// located on pin #A0. //
// //
// ANTALIFE - 09.08.15 //
/////////////////////////////////////////////////////////////////////////////////////////////
//MUH I/O PINS
int R_pin = 9;
int G_pin = 10;
int B_pin = 11;
int RGB_pot_pin = 0;
//MUH VARIABLES
int anal_val = 0; // ;^)
int theta = 0;
int colour = 0;
void setup()
{
//MUH OUTPUTS
pinMode(R_pin, OUTPUT);
pinMode(G_pin, OUTPUT);
pinMode(B_pin, OUTPUT);
}
void loop()
{
//Using an RGB circle with RED being 0deg, GREEN being 120deg, and BLUE being 240deg
//Here we map the 360deg circle to a value between 0 and 255 (aka the duty of the PWM)
theta = analogRead(RGB_pot_pin)/4;
colour = (6*theta)%255;
//RED TO GREEN [0deg -> 120deg OR 0 -> 85]
if (theta <= 42.5)
{
RGB_write(255,colour,0);
}
else if ((theta > 42.5) && (theta < 85))
{
RGB_write((255-colour),255,0);
}
//GREEN TO BLUE [120deg -> 240deg OR 85 -> 170]
else if ((theta > 85) && (theta < 127.5))
{
RGB_write(0,255,colour);
}
else if ((theta > 127.5) && (theta < 170))
{
RGB_write(0,(255-colour),255);
}
//BLUE TO RED [240deg -> 360deg(or 0deg) OR 170 -> 255(or 0)]
else if ((theta > 170) && (theta < 212.5))
{
RGB_write(colour,0,255);
}
else if ((theta > 212.5) && (theta < 255))
{
RGB_write(255,0,(255-colour));
}
}
void RGB_write(int R_val, int G_val, int B_val)
{
//A simple function that displays the desired LED colour by setting the duty of the
//PWM on each RGB LED
analogWrite(R_pin, R_val);
analogWrite(G_pin, G_val);
analogWrite(B_pin, B_val);
}
To give a quick explanation of the code look at the picture below. You see how as you move around the colour wheel (or change the theta angle) the R G B values of the LED change accordingly giving you a certain colour. One other thing to note is that only two values are being changed at any given point, that is from 0deg to 120deg only the R and G values change while B stays constant (you can witness this by playing around with the colour wheel link above).
Knowing all this the above code maps the angle theta to a certain mixture of PWM duty on each LED, in the end giving you a pretty display of colours.
EDIT: Turns out humans see the brightness of colours differently,
here is a good post about how this would have to be accounted for in software.