fading 2 leds at different rates

hi!

I am trying to fade in and out 2 Leds from my led strip at different rates

#include <FastLED.h>
#define NUM_LEDS 9
#define DATA_PIN 37

CRGB leds[NUM_LEDS];

int fadeAmount = 1;
int brightness = 0;

void setup() { 
       FastLED.addLeds <WS2811, DATA_PIN, BRG>(leds, NUM_LEDS);
       }
   
void loop() {
      led1();           
      led2();      
}      

void led1() {
      leds[0] = CHSV( 255, 255, brightness);
      
      brightness = brightness + fadeAmount;
      
      if (brightness == 0 || brightness == 255) {
      fadeAmount = -fadeAmount ; 
      }

      delay(1);          

      FastLED.show(); 
}  

void led2() {
      leds[1] = CHSV( 186, 255, brightness);
      
      brightness = brightness + fadeAmount;

      if (brightness == 0 || brightness == 255) {
      fadeAmount = -fadeAmount ; 
      }     
    
      delay(2);          

      FastLED.show(); 
}

I wrote one void for each Led since when I was writing everything inside the void loop it was not working, but this is also not working. The delay wrote in each “void led” affects both behaviours.

how can I sort this out?

thanks!

Small point on the jargon. The things you are calling "voids" are actually "functions". Void is just the type of value returned by the function - i.e. nothing.

Having separate functions for the different LEDs is good.

The problem is using the delay() function because it stops everything else until it finishes.

Look at how to use millis() to manage timing in the demo several things at a time

...R

The short answer is don’t use delay. It is completely useless if you try do more than one single task since it is blocking the cpu. But this does not help to solve the problem. One way to to that is using my State machine library which supports concurrent machines.
I do not have a led strip but the code demonstrates the principle using analog write

#include <SM.h>

const int noFades = 2;
SM fadeLed[noFades] = {SM(fadeIn), SM(fadeIn)};
unsigned long fadeTime[noFades] = {1000, 1500};
byte brightness[noFades];
int i;//global index for selecting statemachine

void setup(){
  pinMode(11, OUTPUT);
  pinMode(10, OUTPUT);
}//setup()

void loop(){
  for(i = 0; i<noFades; i++) EXEC(fadeLed[i]);
  analogWrite(10, brightness[0]);
  analogWrite(11, brightness[1]);
}//loop()

State fadeIn(){
  brightness[i] = 255*fadeLed[i].Statetime()/fadeTime[i];
  if(fadeLed[i].Timeout(fadeTime[i])) fadeLed[i].Set(fadeOut);
}//fadeIn()

State fadeOut(){
  brightness[i] =255-255*fadeLed[i].Statetime()/fadeTime[i];
  if(fadeLed[i].Timeout(fadeTime[i])) fadeLed[i].Set(fadeIn);
}//fadeOut()

thanks guys and thanks Robin2 for the correction in terminology

I am going to be checking out millis to do this. I am really new in coding so most of the examples are really twisted to decode for me, so it will take some time.

for the same reason, I think I should learn how to use millis and not to get involved with a library. thanks anyway nilton61

I am frozen…

In the following code the led fades in and out at the rate the loop is being repeated

#include <FastLED.h>
#define NUM_LEDS 9
#define DATA_PIN 37

CRGB leds[NUM_LEDS];

int fadeAmount = 1;
int brightness = 0;


void setup() { 
       FastLED.addLeds <WS2811, DATA_PIN, BRG>(leds, NUM_LEDS);
       }
   
   
void loop() {
      leds[0] = CHSV( 255, 255, brightness);

      brightness = brightness + fadeAmount;
      
      if (brightness == 0 || brightness == 255) {
      fadeAmount = -fadeAmount ; 
      }

      FastLED.show(); 

}

How can I set this rate to 1000 milliseconds using millis()?

The blink without delay example shows you how to turn a LED on or off every second. Instead, you could use virtually the same code to increment or decrement your fade amount.

Here’s what I’d do:

unsigned long led1start, led2start, led1limit, led2limit;


void setup()
{
// Place your setup code here
led1limit = 50;
led2limit = 50;
led1start = millis();
led2start = millis();

}

void loop()
{

if ((millis()-led1start) > led1limit) updateled1;
if ((millis()-led2start) > led2limit) updateled2;

}

void updateled1()
{
// Place your update code here
led1start = millis();
}

void updateled2()
{
// Place your update code here
led2start = millis();
}

What is does is basically use millis() to figure out whether a certain time (led1limit) has passed, and if it has, it runs the updateled function for the corresponding led. The updateled function would probably have to have its own counter which tracks the current value from 1 to 255 of the LED (I’m assuming you’re working with PWM). On each cycle you’d increment the value, and if it’s at 255 you’d reset it.

Since there’s no delay() function, LED2 can update as soon as LED1 is done updating, and you get a continuous fade effect. At least up to a certain point: if your timings are extremely short or you’re updating a whole bunch of LEDs one cycle might start interfering with the others. But with 2 LEDs I doubt you’ll have that problem.

I recently used something like this for a series of 16 LEDs. 8 of them would light up knight ryder style, and the remaining 4 would blink one after the other. Except for the very rare case when the timings matched up perfectly and the cycle screwed up, it worked fine (after it screwed up it would go back to normal within 1 or 2 cycles).

thanks awol

I understand completely, and I have been already checking it out. the thing is, I am really completely frozen. I spent 2 hours in front of the computer looking at different codes that use millis without being able to realize how to apply it to my needs.

thanks mmelendeze

I will check it out!

The code from Reply #6 will work very well - except that the () at the function calls are missing.

Personally I would put the millis() test into the function so it was self-contained - like this

unsigned long led1start, led2start, led1limit, led2limit;
unsigned long currentMillis;


void setup()
{
    // Place your setup code here
    led1limit = 50;
    led2limit = 50;
    led1start = millis();
    led2start = millis();

}

void loop() {
   currentMillis = millis()
   updateled1();
   updateled2();
}

void updateled1() {
   if (currentMillis - led1start >= led1limit) {
        // Place your update code here
         led1start += led1limit;
    )
}

void updateled2() {
   if (currentMillis - led2start >= led2limit) {
       // Place your update code here
       led2start += led2limit;
   }
}

Note that I have made a couple of other changes. I have captured the value of millis() into a variable called currentMillis so that the same value is used in all the tests

And I have changed the update from led1start = millis(); to led1start += led1limit; Using the first method will allow small errors to creep into the timing. This may not matter if the timing of successive blinks is not critical. The reasons are explained at length in the several things at a time Thread.

...R

Edit: Robin gave basically the same example :D

Sample: blink at different rates.

#define Led1 2
#define Led2 3

void setup()
{
  pinMode(Led1, OUTPUT);
  pinMode(Led2, OUTPUT);
}

void loop()
{
  static unsigned long prevTime1 = 0, prevTime2 = 0, currTime;
  
  currTime = millis();
  if(currTime - prevTime1 >= 500) // blink every half second
  {
    digitalWrite(Led1, !digitalRead(Led1) ); 
    prevTime1 += 500;
  }

  if(currTime - prevTime2 >= 1000) // blink every second
  {
    digitalWrite(Led2, !digitalRead(Led2) ); 
    prevTime2 += 1000;
  }
}

ey guys thanks for helping out!

I am not using PWM. I am using a library for Led strips (FastLed)

Here is the code I wrote with the info I gathered from the replies:

#include <FastLED.h>
#define NUM_LEDS 9
#define DATA_PIN 37

CRGB leds[NUM_LEDS];

int fadeAmount = 1;
int brightness = 0;

unsigned long led1start, led2start, led1limit, led2limit;
unsigned long currentMillis;


void setup() {
      FastLED.addLeds <WS2811, DATA_PIN, BRG>(leds, NUM_LEDS);
      led1limit = 5;
      led2limit = 10;
      led1start = millis();
      led2start = millis();
}

void loop() {
      currentMillis = millis();
      updateled1();
      updateled2();
}

void updateled1() {
      if (currentMillis - led1start >= led1limit) {
      
      leds[0] = CHSV( 255, 255, brightness);

      brightness = brightness + fadeAmount;
      
      if (brightness == 0 || brightness == 255) {
      fadeAmount = -fadeAmount ; 
      }

      FastLED.show(); 
      
      led1start += led1limit;
      }      
}

void updateled2() {
      if (currentMillis - led2start >= led2limit) {
      
      leds[1] = CHSV( 155, 255, brightness);

      brightness = brightness + fadeAmount;
      
      if (brightness == 0 || brightness == 255) {
      fadeAmount = -fadeAmount ; 
      }

      FastLED.show(); 
      
      led2start += led2limit;
      }      
}

From what I saw in Robin2 post and HazardsMind post, I assumed that giving a different value to both led1limit and led2limit would affect the rate of the fade, but both leds are fading at the same rate.

What did I understand wrong?

Maybe you just can’t tell the difference between 5 msecs and 10 msecs.

Try much longer values - say 100 and 500 and see what happens.

…R

I understand what you say, but actually I am also seeing some other strange behaviours:

the fade does not go from 0 to 255 all the time. the lights fade in and out irregularly. sometimes they fade but certanly not from 0 to 255, sometimes they jump in brightness from nothing to full brightness… there is something else…

this is with 10 and 20

http://youtu.be/03x2mfEnfuY

It would have been more useful to post the video of operation with 100 and 500. Then we might have time to make a diagnosis. Even slower would be better.

...R

100 and 500

it is very slow…

in the three cycles that blue (right) did, it didnt reach 255 brightness. not even close

20 and 30

I think you got the idea...

:)

http://youtu.be/EnZdFoJTxAU

Obviously changing the interval changes the speed of fading. So why are they both working at the same speed?

Try changing the 20 and 30 values to 20 and 100. I'm curious to know which is dominant value?

I don't know anything about FastLED. What about replacing that with a simple analogWrite(pin, brightness) to see what happens.

After further thought, I wonder if you have FastLED.show() in the wrong place? Try putting it as last thing in loop() - before you try anything else. And, obviously, only one copy of it. If that makes no difference try my other suggestions.

...R

you saw it robin

and as lots of time happens, it is the simplest mistakes...

FastLED.show() is the order to send the information to the led strip.

led1start += led1limit; was then not participating in the function, what made it behave so eclectic.

I really appreciate you help!!!!

now I will be studying all the process to incorporate it

All the best!!!

Why are both functions using the same brightness variable? If you are looking to fade at two different intervals, shouldn't you also have two different variables too?

Also fadeAmount, need two of those too!