Pages: [1]   Go Down
Author Topic: Simple RGB LED "demo": Approach advice  (Read 699 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Jr. Member
**
Karma: 0
Posts: 57
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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:

http://oomlout.com/RGBL/CODE/_RGBL_AnalogTest.txt

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.



Thanks!

me.
Logged

Norfolk UK
Offline Offline
Faraday Member
**
Karma: 70
Posts: 2575
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
Code:
/*         ATtiny85
             --U--
      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() {
    pinMode(RedPin,OUTPUT);
    pinMode(GreenPin,OUTPUT);
    pinMode(BluePin,OUTPUT);
}

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){
                Go++;
                OK = false;
            }
            if (G < Go){
                Go--;
                OK = false;
            }
            if (B > Bo){
                Bo++;
                OK = false;
            }
            if (B < Bo){
                Bo--;
                OK = false;
            }
            analogWrite(RedPin,Ro);
            analogWrite(GreenPin,Go);
            analogWrite(BluePin,Bo);
        }
    }
}

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;
    else
        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)));
    else
        return ( m1 );
}
Logged


Yorkshire England
Offline Offline
Sr. Member
****
Karma: 2
Posts: 267
Arduino good init
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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

Pages: [1]   Go Up
Jump to: