Hue-controllable RGB LED lamp

I thought up a different value -> RGB formula a couple of years ago when I dabbled a little in Milkdrop. While it isn't perfect, it worked pretty well imho. (I needed it for a lightbeam that splits up into different colors, for a "Dark Side of the Moon" animation: http://raron.deviantart.com/art/Dark-Side-of-the-Moon-54658436) Here, yellow is the worst represented color (although it is present - barely.)

This is what I came up with:
R = 0.5 + 0.5 * cos((value+0.125) * 2 * PI)
G = 0.5 + 0.5 * cos((value+0.375) * 2 * PI)
B = 0.5 + 0.5 * cos (value * PI)

Where value is from 0 to 1, as is the returned RGB values in this case.

As stated, not perfect (could be more tweaking fixes it, but I kind of liked the formulas too ::slight_smile: ), it doesn't give quite clean colors.

I had to test it on my arduino with a common-anode RGB LED of course. Unfortunately it didn't turn up too well. Here, it is the green which is the worst, and also the yellow... so yeah not perfect at all. I just wanted my say in the matter :smiley: Although the original HSV formula is much better (I presume, I haven't tested it yet but I'm pretty sure it is).

Anyway, this sums up my RGB test sketch:

const int ledRed = 9;
const int ledGreen = 10;
const int ledBlue = 11; 

double redLevel;
double greenLevel;
double blueLevel;


void setup() 
{
 pinMode(ledRed, OUTPUT);
 pinMode(ledGreen, OUTPUT); 
 pinMode(ledBlue, OUTPUT);
}

void loop() 
{
    int value = analogRead(analogPin);
    double RGBslider = (double)value/1024.0;
    
    redLevel   = 128.0 * ( 1 + cos( 2 * PI * (RGBslider + 0.125)));
    greenLevel = 128.0 * ( 1 + cos( 2 * PI * (RGBslider + 0.375)));
    blueLevel  = 128.0 * ( 1 + cos( PI * RGBslider));
    
    if (redLevel > 255) redLevel = 255;
    if (redLevel < 0) redLevel = 0;
    if (greenLevel > 255) greenLevel = 255;
    if (greenLevel < 0) greenLevel = 0;
    if (blueLevel > 255) blueLevel = 255;
    if (blueLevel < 0) blueLevel = 0;
    
    analogWrite(ledRed, 255 - ((byte)redLevel)); // negating the output for common anode (sinking)
    analogWrite(ledGreen, 255 - ((byte)greenLevel)); 
    analogWrite(ledBlue, 255 - ((byte)blueLevel));
}