Go Down

Topic: Simple RGB LED "demo": Approach advice (Read 948 times) previous topic - next topic


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.
Code: [Select]
/*         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 );
Don't PM me for help as I will ignore it.


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

Go Up

Please enter a valid email to subscribe

Confirm your email address

We need to confirm your email address.
To complete the subscription, please click the link in the email we just sent you.

Thank you for subscribing!

via Egeo 16
Torino, 10131