Hopefully Simple Question about Color Fade
Moderators: adafruit_support_bill, adafruit

Hopefully Simple Question about Color Fade

by DanielParadise on Sat Feb 23, 2013 5:18 pm

Hello! I am looking to accomplish what I hope will be a simple project.

I have a Doctor Who messenger box gizmo that I have always liked. What it does is simply fade between all the colors (RGB and everything in between). I want to do that with a strand of WS2801 Lights hooked up to my Uno. I want the lights to fade between RGB (and everything in between that the lights are capable of) over a period of perhaps 6 minutes (equal time for each color if possible). Also, I want every light on the strand to be in sync. If the first bulb is green then the last is green, etc...

Now, I got the lights to do what I want, for the most part, by hobbling this code together from the sample code (like a monkey wacking a wrench against a pipe till it stops leaking):

Code: Select all | TOGGLE FULL SIZE
#include "SPI.h"
#include "Adafruit_WS2801.h"

int dataPin  = 2;    // Yellow wire on Adafruit Pixels
int clockPin = 3;    // Green wire on Adafruit Pixels


Adafruit_WS2801 strip = Adafruit_WS2801((uint16_t)7, (uint16_t)7, dataPin, clockPin);

void setup() {
   
  strip.begin();

  // Update LED contents, to start they are all 'off'
  strip.show();
}

void loop() {
 
  rainbow(20);

}

void rainbow(uint8_t wait) {
  int i, j;
   
  for (j=0; j < 256; j++) {     // 3 cycles of all 256 colors in the wheel
    for (i=0; i < strip.numPixels(); i++) {
      strip.setPixelColor(i, Wheel( (i + j) % 255));
    } 
    strip.show();   // write all the pixels out
    delay(2400);
  }
}

/* Helper functions */

uint32_t Color(byte r, byte g, byte b)
{
  uint32_t c;
  c = r;
  c <<= 8;
  c |= g;
  c <<= 8;
  c |= b;
  return c;
}


uint32_t Wheel(byte WheelPos)
{
  if (WheelPos < 85) {
   return Color(WheelPos * 3, 255 - WheelPos * 3, 0);
  } else if (WheelPos < 170) {
   WheelPos -= 85;
   return Color(255 - WheelPos * 3, 0, WheelPos * 3);
  } else {
   WheelPos -= 170;
   return Color(0, WheelPos * 3, 255 - WheelPos * 3);
  }
}


My questions are:

    Why does the time between each color transition change when I change the number next to the rainbow variable (20 in this case)?

    Am I right in assuming that the delay (2400 in this case) it the main factor in the color fade time?

    Am I properly using all the colors these lights are capable of?

Any help in this matter would be GREATLY appreciated as this has been a pain in my backside for 2 years now and I would love to put this to bed. Thanks in advance!

Dan
DanielParadise
 
Posts: 2
Joined: Mon Jan 23, 2012 4:40 pm

Re: Hopefully Simple Question about Color Fade

by ZTiK.nl on Sat Feb 23, 2013 5:56 pm

I had a similar problem which was indeed caused by the delay();
Other people may have a better solution than me, but I think this will help you out.

The delay(); causes the entire program to sleep for X period.
I solved this by using another function : millis();

This doesn't make your program stall/hang/wait, but makes use of an interrupt timer, and when the timer has hit its target, make it run your code.

Anyway, if anyone has a better solution I'd love to hear it too :)

Just my thoughts, but I have a feeling that delay()'s are meant to be used in setup();, not in loop(); unless you specifically want/need your entire program to wait



edit:
I seemed to have mixed up my Teensy code with Arduino code, which is almost but not entirely compatible...
The code I used on Teensy is elapsedMillis(); which does what I described above
I haven't seen an Arduino function comparable yet
Last edited by ZTiK.nl on Sat Feb 23, 2013 6:04 pm, edited 1 time in total.
ZTiK.nl
 
Posts: 21
Joined: Thu Jan 17, 2013 2:43 pm

Re: Hopefully Simple Question about Color Fade

by tldr on Sat Feb 23, 2013 6:03 pm

i shouldn't imageine that the number next to the rainbow variable (20 in this case) does much of anything anymore, since you've modified the rainbow routine, replacing wait iin the call to delay to 2400. the delay is now fixed at 2.4 seconds. if our replace 2400, with wait, the answer to your first question will be yes and your second question no longer matters.

the answer to your third question, is, well not really. it displays 256 out of a possible 4.72236648e21 colors. to get more you'll have to mess with the wheel function, but, as written it does a dandy job. to get it to cycle over 6 minutes, you'd want to select a value (6 * 60 * 1000) / 256 which is real close to 1406, and call rainbow (1406) in loop. you'll also have to modify the declaration of the rainbow function.

Code: Select all | TOGGLE FULL SIZE
#include "SPI.h"
    #include "Adafruit_WS2801.h"

    int dataPin  = 2;    // Yellow wire on Adafruit Pixels
    int clockPin = 3;    // Green wire on Adafruit Pixels


    Adafruit_WS2801 strip = Adafruit_WS2801((uint16_t)7, (uint16_t)7, dataPin, clockPin);

    void setup() {
       
      strip.begin();

      // Update LED contents, to start they are all 'off'
      strip.show();
    }

    void loop() {

      rainbow(1406);

    }

    void rainbow(uint16_t wait) {
      int i, j;
       
      for (j=0; j < 256; j++) {     // 3 cycles of all 256 colors in the wheel
        for (i=0; i < strip.numPixels(); i++) {
          strip.setPixelColor(i, Wheel( (i + j) % 255));
        }
        strip.show();   // write all the pixels out
        delay(wait);
      }
    }

    /* Helper functions */

    uint32_t Color(byte r, byte g, byte b)
    {
      uint32_t c;
      c = r;
      c <<= 8;
      c |= g;
      c <<= 8;
      c |= b;
      return c;
    }


    uint32_t Wheel(byte WheelPos)
    {
      if (WheelPos < 85) {
       return Color(WheelPos * 3, 255 - WheelPos * 3, 0);
      } else if (WheelPos < 170) {
       WheelPos -= 85;
       return Color(255 - WheelPos * 3, 0, WheelPos * 3);
      } else {
       WheelPos -= 170;
       return Color(0, WheelPos * 3, 255 - WheelPos * 3);
      }
    }


this will cause each color to display for 1.406 seconds and for the entire cycle to take 5 minutes and 59.94 seconds. actually that's just the delays. with processing time thrown in it may take a little over 6 minutes.
"If I had known it was harmless, I would have killed it myself." - Phillip K. Dick, A Scanner Darkly
User avatar
tldr
 
Posts: 466
Joined: Thu Aug 30, 2012 12:34 am

Re: Hopefully Simple Question about Color Fade

by DanielParadise on Sun Feb 24, 2013 6:49 am

Thank you very much! This means a lot to me. I am ashamed to say that it has taken my lazy butt two years to get such a simple thing done and this works great!

As a sad aside, on the day I finally got everything working, I blew out 13 of the 25 bulbs by accidentally plugging in my 12 Volt power supply (which looks identical to the normal PS). I cut and spliced back together the remaining 12 and they work but it is still aggravating. I would, though, rather have 12 working bulbs then 25 bulbs doing nothing in my closet. Alway look on the bright side... no pun intended.

Anyway, thanks again!

Sincerely,
Daniel Paradise
DanielParadise
 
Posts: 2
Joined: Mon Jan 23, 2012 4:40 pm

Re: Hopefully Simple Question about Color Fade

by tldr on Sun Feb 24, 2013 5:10 pm

if you want a really spectacular failure plug in a laptop power supply. lights, sound effects and smoke then everything goes hazy as your eyes fill with tears.

and i've got 5m of leds that have been sitting around for a year and a half running adafruit's demo code, because i still haven't finished the project i bought them for. it's real pretty, though.
"If I had known it was harmless, I would have killed it myself." - Phillip K. Dick, A Scanner Darkly
User avatar
tldr
 
Posts: 466
Joined: Thu Aug 30, 2012 12:34 am



cron