6 crossfading LEDS spinning in circle

hi all,
totally new but very excited.

only playing with leds for now, trying to understand slowly.
now i'm trying to do a simple-looking think.

I have 6 leds placed in circle. the basic idea would be to make them lighting with a sequence from 1 to 6 in loop. that's no problem.
now I want them to be fading. and what looks even more complex to me, is how to make them cross fading, meaning that when led 1 fading down reaches 66%, led 2 starts fading in. and even better would be that when led 1 fading down reaches 33% (meaning probably that led 2 is @33%) led 3 begins fading in.
hm ??
I managed to do that, or something near, through MAX/MSP and serial. it's totally messy, but working. but still, useless, as I'd like it not needing a computer beside ))
I can then change the spinning speed, which would be very important to me. also perhaps, the fading % would be great to have too (two analog inputs with potentiometers ?) .
so as I understood, for fading power, we can only use analog outputs 3,5, 6, 9, 10, 11.

does anyone have any idea if a similar project has been already developed ?
or one I could inspire from ?

does it look simple or complex ?
I have no idea.

thanks lots

? ?

<33333

frankarditi:
I have 6 leds placed in circle. the basic idea would be to make them lighting with a sequence from 1 to 6 in loop. that's no problem.
now I want them to be fading. and what looks even more complex to me, is how to make them cross fading, meaning that when led 1 fading down reaches 66%, led 2 starts fading in. and even better would be that when led 1 fading down reaches 33% (meaning probably that led 2 is @33%) led 3 begins fading in.
hm ??

frankarditi:
Have a look at this: http://www.arduino.cc/en/Tutorial/KnightRider

That's basically what you want, you just have to make it circular.

frankarditi:
so as I understood, for fading power, we can only use analog outputs 3,5, 6, 9, 10, 11.

That's in hardware. In software you can use all of them: http://arduino.cc/forum/index.php/topic,19451.0.html

frankarditi:
does it look simple or complex ?

Looks simple to me... but I build stuff like this: led cube - Google Search

fungus:
Have a look at this: http://www.arduino.cc/en/Tutorial/KnightRider

That's basically what you want, you just have to make it circular.

thanks lot fungus, that's it. I found it before, and thought "that's what I want", but basically I don't see how to make them fade, even though the third part tries to make movement a bit smoother, but only by delaying turning off into turning on next one.

and fading one after another looks easy, but how to do it interwoven ?

but basically I don't see how to make them fade,

No you can't with that code.

so as I understood, for fading power, we can only use analog outputs 3,5, 6, 9, 10, 11.

No they are not analogue outputs they are digital PWM outputs.
You need you write some code that changes the value you write to them.
Use an array that holds the PWM values and an array that holds PWM pins.
Then in a loop write the PWM value of each array element to the corresponding PWM pin.
Then next time round the loop you offset the read / write pointer by 1, and then by 2 and so on.
Make sure you wrap round the array pointer when it overflows, or have a PWM pin array twice as long, that is two sets repeated.

You probably will not be able to do that in one go, so write what you can, post the code and ask on the bits you are stuck on.
If the mean time look at how arrays are used as a look up table, like here:-
http://www.thebox.myzen.co.uk/Tutorial/Arrays.html

frankarditi:
thanks lot fungus, that's it. I found it before, and thought "that's what I want", but basically I don't see how to make them fade, even though the third part tries to make movement a bit smoother, but only by delaying turning off into turning on next one.

and fading one after another looks easy, but how to do it interwoven ?

It's best to separate the logic for fading the LEDs from the logic that's turning them on.

void setup() 
{ 
} 


// Where the PWM outputs are
int ledpin[] ={3,5,6,9,10,11}; //organize all PWM pins neatly.

// The brightness of each LED is stored here
int brightness[] ={0,0,0,0,0,0};

void loop()
{
  // We update 250 times a second, LEDs will take
  // about a second to fade away at this speed
  delay(4);

  // Fade all the LEDs
  for (int i=0; i<6; ++i) {
    if (brightness[i] > 0) {
      --brightness[i];
      analogWrite(ledpin[i], brightness[i]);
    }
  }

  // Light up new LEDs
  static int count=0;
  if (++count == 125) {    // This gives two LEDs per second
    count = 0;
    // Light the next LED in the sequence
    static int pos=0;
    brightness[pos] = 256;  // Turn on LED
    // Go to next LED
    if (++pos == 6) {
      pos = 0;  // Back to zero after six LEDs
    }
  }
}

It's best to separate the logic for fading the LEDs from the logic that's turning them on.

No it is absolutely not the thing to do.

Grumpy_Mike:

It's best to separate the logic for fading the LEDs from the logic that's turning them on.

No it is absolutely not the thing to do.

Because....?

Because the fade and the on / off is the same thing, have you looked at that video?

You only need to separate the fade and the switching when the fade is applied to all the LEDs.
Here there is no difference between setting a brightness level and setting on and off. Off is just a brightness level of zero, so it makes no sense at all in getting a separate function to control the on / off as it will be over ridden by the brightness value you set.

Grumpy_Mike:
Because the fade and the on / off is the same thing, have you looked at that video?

Yep. I believe the code I posted will do something very similar...

One way I've done this is with an array. With each item representing one LED "pixel" in the string (whether it's straight, in a circle, or any other shape doesn't matter.) Essentially I will tell the first index to go 100% and send that data to the LED string. Then I push the entire array to the right, take the value of what's now in the 2st index, half it, and shove it in the first index. Push it out to the LED string again. Third time, do the same, push the array to the right, take the value in the 2nd index, half it, and put it in the first index, push to the LED string. Keep repeating that till you reach the last LED in the string.

Writing it out, you get something like this:

Array at the start: {0, 0, 0, 0, 0, 0}
First loop: {100, 0, 0, 0, 0, 0}
2nd loop: {50, 100, 0, 0, 0, 0}
3rd loop: {25, 50, 100, 0, 0, 0}
4th loop: {12, 25, 50, 100, 0, 0}
5th loop: {6, 12, 25, 50, 100, 0}
6th loop: {3, 6, 12, 25, 50, 100}
7th loop: {1, 3, 6, 12, 25, 50}
8th loop: {0, 1, 3, 6, 12, 25}  // you've now effectively faded down to nothing on the first LED, time to continue pushing the array till you reach zero on the last LED.

This method takes care of both the fading, as well as the actual "moving" of the LEDs ...

You can see the result of that in my xmas lights display from last year. Go to about 30 seconds in, or about 2 minutes in for a variation of the same thing:

There are many ways to skin this cat.

KirAsh4:
You can see the result of that in my xmas lights display from last year. Go to about 30 seconds in, or about 2 minutes in for a variation of the same thing:

There are many ways to skin this cat.

Yep.

Did you really type in lists of numbers for all those LEDs in the video?

Me? I'd have written a bunch of effects called things line "fadeAllLeds()", "scrollDown()", "lightRandomLedOnTopRow()", etc. then combined them in sequences:

void sequence1()
{
  fadeAllLeds();
  scrollDown();
  lightRandomLedOnTopRow(BLUE);
}
void sequence2()
{
  setAllLEDs(RED);
  fadeToBlack();
  setAllLEDs(GREEN);
  fadeToBlack();
  setAllLEDs(BLUE);
  fadeToBlack();
}

void loop()
{
  runSequence(100,sequence1); // 100 steps of sequence 1
  runSequence(3,sequence2);    // 3xRGB pulses
  ...
}

Something like that...

fungus:
Did you really type in lists of numbers for all those LEDs in the video?

Nope, it's all done in the math. I just tell the controller how many strings there are (there were two strings per controller) and how many pixels each string has (in this case only 10 per string.) The math took care of the rest.

One main loop that checked for an RF signal and calling of a "director" loop for the various sequences. Then each sequence as a callable function. The "director" loop really did nothing but call the various sequences:

void seqDirector(int seq) {
  switch (seq) {
    case 0:
      // shut everything off
      resetAll(0);
      break;
    case 1:
      // sequence 1
      randomWhiteBlueBlink();
      break;
    case 2:
      // sequence 2
      randomStars();
      break;
    case 3:
      // sequence 3
      snowFlakes();
      break;
    etc., etc.
  }
}

This allowed for the addition of new sequences without having to do anything to the main loop, just create a new sequence, and amend the "director" loop. Each sequence also called resetAll(int type) where the value of 'type' would determine how the reset was done, whether we're fading everything top to bottom, or fade in-place, or an instant-off mode.

The whole system is written with no delays() anywhere. So the main loop runs as fast as the controller can handle it, and the various sequences run off of a comparison with millis().

Hah, I forgot I had access to the sketch from here - yay for shared folders across different networks. So the way it flowed after setup() goes something like this:

main loop()

  • check millis() against a known time lapse and determine if a 'running' LED needs to blink or not
  • check millis() against a known time lapse and determine if the TX/RX LED needs to be turned on or off
  • check millis() against a known time lapse and write it to EEPROM if needed (I kept a 15 minute heartbeat for debug purposes)
  • check EEPROM and determine if this unit is a TX or RX (there was 1 TX unit and 18 RX)
  • if TX, set unit's name (set in EEPROM) and start sending packets (each packet consisted of an RX name and sequence number)
  • if TX, after sending packet information, display same sequence (the TX unit was also part of the "show")
  • if RX, set unit's name (set in EEPROM) and start listening for packets (name was simply 'TX##' where ## was a 2 digit number)
  • IF RX, read serial data from RF and call sequence director function with sequence to display

director(int sequence_number) function

  • parse value of sequence passed and call appropriate sequence // see previous post with case switch

sequence_name() functions

  • check millis() against a known time lapse // the various light sequences only update if a certain time has lapsed, 25ms, 50ms, some random.
  • if the time has lapsed, update string with new data

This allowed the main loop to run constantly listening for RF as well as blink a 'running' LED without having to wait for anything else to finish doing what they're doing.

Yep. I believe the code I posted will do something very similar...

Have you run it? Because I believe it won't.

Grumpy_Mike:

Yep. I believe the code I posted will do something very similar...

Have you run it? Because I believe it won't.

Ha! You got me there. I typed it in without even uploading it to an Arduino (I've got an ATtiny85 connected at the moment and I couldn't be bothered to disconnect it).

I just tried it on an Uno though, and it works perfectly. The LED sequence runs a bit slower than I imagined, but it does what it's supposed to do. WHat did you think was the problem?

Why not just use math, I did somethiing similar using SIN() and made each led 30 degrees out of phase with the last, i'll dig the code out and post it

fungus:
That's in hardware. In software you can use all of them: http://arduino.cc/forum/index.php/topic,19451.0.html

thanks fungus, SoftPWM is very useful, and can be handled simply. the only problem I come across by now is the fading duration is max 4000. any idea how to make it slower changing the lib ? even 'til 8000 ?

P18F4550:
Why not just use math, I did somethiing similar using SIN() and made each led 30 degrees out of phase with the last, i'll dig the code out and post it

would really love to use "just math", but not having mental capacity for the moment ))

anywayz, thank you guys having helped, that's great.

doesn't have to be difficult

temp = 255-abs(sin(val+60)*brightness);

relates to led brightness = full on brightness - positive result of (sin(a value + phase shift in degrees) * desired brightness)

This creates a smooth wave effect

int led1 = 3;
int led2 = 5;
int led3 = 6;
int led4 = 9;
int led5 = 10;
int led6 = 11;

int brightness = 255;

void setup()
{       
  pinMode(led1, OUTPUT);    
  pinMode(led2, OUTPUT);  
  pinMode(led3, OUTPUT);  
  pinMode(led4, OUTPUT);  
  pinMode(led5, OUTPUT);  
  pinMode(led6, OUTPUT);  
}

void loop() 
{
  for(float val = 0; val<3; val+=0.01)
  {
    analogWrite(led1, 255-abs(sin(val)*brightness));  // No Phase shift
    analogWrite(led2, 255-abs(sin(val+60)*brightness));  // 60 degrees
    analogWrite(led3, 255-abs(sin(val+120)*brightness));  // 120 degrees
    analogWrite(led4, 255-abs(sin(val+180)*brightness));  // 180 degrees
    analogWrite(led5, 255-abs(sin(val+240)*brightness));  // 240 degree
    analogWrite(led6, 255-abs(sin(val+300)*brightness));  // 300 degrees
    delay(5);
  }
}