Simple RGB LED "demo": Approach advice

Hi Hi. I have a project i am working on using an RGB LED.

I want the LED to, at the press of a button, run through "all the colours of the rainbow", once.

As in, press the button: Red orange yellow green blue Off

I have been trying to understand and chop up the RGB demo code from oomlout:

but it doesn’t like my chopping. And i think the code is probably a bit over complex for my simple purpose.

What approach would the panel suggest for this simple task?

P.S. for my project, i would also like to be able to serial print a linerar representation of the colour value. I guess the easiest way to do this would be to assign the planned colour range an arbitrary value: red is 0, green is 128, blue is 256.. this may over complicate matters, it may make it simpler.



Attached is code I did for a similar project using an ATtiny85 but it will easily adapt to normal Arduino by just altering the relevant LED pin numbers to Arduino PWM pins (the ones with a ~ mark by them). This code is designed to work with the equivalent of common cathode LED’s but should still work with common anode. Don’t forget your resistors.

/*         ATtiny85
      Reset |1   8| VCC
    (A3) D3 |2   7| D2 (A1)
PWM (A2) D4 |3   6| D1 PWM
        GND |4   5| D0 PWM

// HLSMAX BEST IF DIVISIBLE BY 6. RGBMAX, HLSMAX must each fit in a byte. 
#define HLSMAX 240                              // H,L, and S vary over 0-HLSMAX 
#define RGBMAX 255                              // R,G, and B vary over 0-RGBMAX 

#define RedPin 0
#define GreenPin 1
#define BluePin 4

const long mainDelay = 10;                      // Delay between each colour change

byte R,G,B;                                     // Target RGB colour 
byte Ro,Go,Bo;                                  // Current RGB colour

void setup() { 

void loop() {
    for (word Hue=0; Hue <= HLSMAX; Hue++){     // Once around the circle
        HLS2RGB(Hue,HLSMAX,HLSMAX/2);           // Get target R,G,B colour
        boolean OK = false;                     //Flag colours don't match
        while (OK == false){
            long loopTime = millis();           //Read timer
            while ((millis() - loopTime) < mainDelay) {
            }    // Delay
            OK = true;                          // Flag colours match

            if (R > Ro){                        // Target R greater than current Ro
                Ro++;                           // Increment current
                OK = false;                     // Flag colours will change
            if (R < Ro){                        // Target R less than current Ro
                Ro--;                           // Decrement current
                OK = false;                     // Flag colours will change
            if (G > Go){
                OK = false;
            if (G < Go){
                OK = false;
            if (B > Bo){
                OK = false;
            if (B < Bo){
                OK = false;

void HLS2RGB(word hue, word sat, word lum) { 

    word M1,M2;                                 // calculated numbers 

    sat = constrain(sat, 1, HLSMAX);            // Don't allow sat<=0 or sat>HLSMAX
    lum = constrain(lum, 0, HLSMAX/2);          // Don't allow lum<0 or lum>(HLSMAX/2)

    if (lum <= (HLSMAX/2))
        M2 = (lum*(HLSMAX + sat) + (HLSMAX/2))/HLSMAX;
        M2 = lum + sat - ((lum*sat) + (HLSMAX/2))/HLSMAX;

    M1 = 2*lum-M2;

    // get RGB, change units from HLSMAX to RGBMAX 
    R = (Hue2RGB(M1,M2,hue+(HLSMAX/3))*RGBMAX +(HLSMAX/2))/HLSMAX; 
    G = (Hue2RGB(M1,M2,hue)*RGBMAX + (HLSMAX/2)) / HLSMAX;
    B = (Hue2RGB(M1,M2,hue-(HLSMAX/3))*RGBMAX +(HLSMAX/2))/HLSMAX; 
// Utility routine for HLS2RGB 
byte Hue2RGB(word m1, word m2, word hue) { 
    // range check: note values passed add/subtract thirds of range 
    if (hue < 0)
        hue += HLSMAX;

    if (hue > HLSMAX)
        hue -= HLSMAX;

    // return r,g, or b value from this tridrant 
    if (hue < (HLSMAX/6))
        return ( m1 + (((m2-m1)*hue+(HLSMAX/12))/(HLSMAX/6)));

    if (hue < (HLSMAX/2))
        return ( m2 );

    if (hue < ((HLSMAX*2)/3))
        return ( m1 + (((m2-m1)*(((HLSMAX*2)/3)-hue)+(HLSMAX/12))/(HLSMAX/6))); 
        return ( m1 );

You could use a conversion from HSL to RGB and then cycle through the hue.