multiple fading leds in sequence

hello members, i’m new here and trying to figure out the answer for my question, but i’m left with more questions than answers.

I am wanting to create a wavelike effect with four led channels. I found this code

int led_1 = 6;
int led_2 = 9; 
int led_3 = 10;
int led_4 = 11;
int brightness = 0;
int fadeAmount = 5;
// the setup routine runs once when you press reset: 
void setup() {
}
void loop() {
  //fade in from min to max in increments of 5 points:
  for(int fadeValue = 0 ; fadeValue <= 255; fadeValue +=5){
    //sets the value (range from 0 to 255):
    analogWrite(led_1, fadeValue);
    //wait for 30 milliseconds to see the dimming effect
    delay(005);
  }
  //Fade out from max to min in increments of 5 points:
  for(int fadeValue = 255 ; fadeValue >= 0; fadeValue -=5){
    // sets the value (range from 0 to 255):
    analogWrite(led_1, fadeValue);
    //wait for 30 milliseconds to see the dimming effect 
    delay(005);
  }
  for(int fadeValue = 0 ; fadeValue <= 255; fadeValue +=5) {
    //sets the value (range from 0 to 255):
    analogWrite(led_2, fadeValue);
    //wait for 30 milliseconds to see the dimming effect 
    delay(005);
  }
  for(int fadeValue = 255 ; fadeValue >= 0; fadeValue -=5){
    //sets the value (range from 0 to 255):
    analogWrite(led_2, fadeValue);
    //wait for 30 milliseconds to see the dimming effect 
    delay(005); 
  }
  for(int fadeValue = 0 ; fadeValue <= 255; fadeValue +=5) {
    // sets the value (range from 0 to 255):
    analogWrite(led_3, fadeValue);
    // wait for 30 milliseconds to see the dimming effects 
    delay(005); 
  }
  for(int fadeValue = 255 ; fadeValue >= 0; fadeValue -=5) {
    //sets the value (rance from 0 to 255):
    analogWrite(led_3, fadeValue);
    //wait for 30 milliseconds to see the dimming effect 
    delay(005); 
  }
  for (int fadeValue = 0 ; fadeValue <= 255; fadeValue +=5){
    //sets the value (range from 0 to 255):
    analogWrite(led_4, fadeValue);
    //wait for 30 milliseconds to see the dimming effect 
    delay(005); 
  }
  for(int fadeValue = 255 ; fadeValue >=0; fadeValue -=5) {
    //sets the value (range from 0 to 255):
    analogWrite(led_4, fadeValue);
    //wait for 30 milliseconds to see the dimming effect 
    delay(005);
  }

on the forum which is great but I want to overlap the fades to get away from blackouts in between the diodes. i’m attempting to get the same effect as the wave Christmas lights.

I see information about timing and schedule coding but when I read up on them the information is quite vague and not sure how it works in this situation.

Im not sure how to amend or change this code to get the desired effect. Essentially what i am looking for is that each lamp is in the process of lighting up or fading out.
it would be broken into quarters where it would look like this

Led 1 0% 25% 50% 75% 0% …
Led 2 25% 50% 75% 0% 25% …
Led 3 50% 75% 0% 25% 50% …
Led 4 75% 0% 25% 50% 75% …

I need a trigger function that when led 1 is at 25% Led 2 will be at 50% and Led 3 will be at 75% and Led 4 will be at 0%. This should create the wave effect i am desiring.

thank you in advance for your time and expertise. any information is greatly appreciated.

martiabr1990:
I need a trigger function that when led 1 is at 25% Led 2 will be at 50% and Led 3 will be at 75% and Led 4 will be at 0%. This should create the wave effect i am desiring.

here is something to study (or run with your Serial console opened at 115200 bauds)

const uint8_t ledBrightness[] = {0, 25, 50, 100};
const uint8_t nbLeds = sizeof(ledBrightness) / sizeof(ledBrightness[0]);
uint8_t currentLedIndex = 0;

void tickLeds(boolean forceStep = false)
{
  unsigned long tickDuration = 1000UL; // 1 second
  static unsigned long chrono = millis();

  if (forceStep || (millis() - chrono) >= tickDuration) {
    currentLedIndex = (currentLedIndex + 1) % nbLeds;
    for (uint8_t ledIndex = 0; ledIndex < nbLeds; ledIndex++) {
      Serial.print(F("led["));
      Serial.print(ledIndex);
      Serial.print(F("]="));
      Serial.print(ledBrightness[(currentLedIndex + ledIndex) % nbLeds]);
      Serial.print(F("%\t"));
    }
    Serial.println();
    if (forceStep) chrono = millis();
    else chrono += tickDuration;
  }
}

void setup()
{
  Serial.begin(115200);
  Serial.println();
  tickLeds(true);
}

void loop() {
  tickLeds();
}

(typed here but should work)

the idea is to use an array holding your fixed values 0% 25% 50% and 100% and use a variable to say where you should be in this array for the leds.

Using modulo (%) to ensure we stay within the right range for the array.

Karma added for using code tags in your first post!

Try this:

#define PWM_UPDATE_INTERVAL     3906ul  //uS    uS between PWM updates (off to full on in ~1-second)
#define NUM_LEDS                4       //#     number of LEDs

#define MAX_PWM                 255     //#     maximum value for PWM
#define MIN_PWM                 0       //#     minimum value for PWM

//LED pin definitions
const byte led_1 = 6;
const byte led_2 = 9;
const byte led_3 = 10;
const byte led_4 = 11;

typedef struct structLEDStruct
{
    const byte      pinLED;             //pin for this LED
    unsigned long   timeLED;            //this LED's time value (uS count)
    byte            valPWM;             //this LEDs current PWM value
    bool            bDir;               //true=counting up, false=counting down
    
}LEDStruct;

//create an array of LED "objects" that can be treated independently of each other but
//virtually simultaneously
//the initialization of the array entries occurs here
LEDStruct LEDControl[NUM_LEDS] = 
{
    {
        .pinLED = led_1,
        .timeLED = 0,
        .valPWM = 0,        //init 0%
        .bDir = true        //true=counting up
    },
    {
        .pinLED = led_2,
        .timeLED = 0,
        .valPWM = 64,       //init 25%
        .bDir = true        //true=counting up
    },
    {
        .pinLED = led_3,
        .timeLED = 0,
        .valPWM = 128,      //init 50%
        .bDir = true        //true=counting up
    },
    {
        .pinLED = led_4,
        .timeLED = 0,
        .valPWM = 192,      //init 75%
        .bDir = true        //true=counting up
    }
    
};

unsigned long
    timeNow;
    
void setup() 
{
    pinMode( led_1, OUTPUT );
    pinMode( led_2, OUTPUT );
    pinMode( led_3, OUTPUT );
    pinMode( led_4, OUTPUT );
    
}//setup

void loop() 
{
    static byte
        ledIndex = 0;       //tracks which LED we're working on each pass through loop

    //get the microseconds count now
    timeNow = micros();

    //does this LED need an update?
    if( timeNow - LEDControl[ledIndex].timeLED >= PWM_UPDATE_INTERVAL )
    {
        //yes; save the microseconds count with the LED for the next comparison
        LEDControl[ledIndex].timeLED = timeNow;

        //counting PWM value "up"?
        if( LEDControl[ledIndex].bDir == true )
        {
            //yes; bump the PWM value
            LEDControl[ledIndex].valPWM++;
            //if we max out, set to reverse counting direction
            if( LEDControl[ledIndex].valPWM == MAX_PWM )
                LEDControl[ledIndex].bDir = false;
        }//if
        else
        {
            //logic generally the same as the "up" logic
            LEDControl[ledIndex].valPWM--;            
            if( LEDControl[ledIndex].valPWM == MIN_PWM )
                LEDControl[ledIndex].bDir = true;
        }//else            

        //update this LED's pin
        analogWrite( LEDControl[ledIndex].pinLED, LEDControl[ledIndex].valPWM );
        
    }//if

    //next pass through we'll work on the next LED
    ledIndex++;
    //make sure we limit our index to the number of LEDs we have
    if( ledIndex == NUM_LEDS )
        ledIndex = 0;

}//loop

It's a way of doing multiple things at the same time (i.e. not focusing solely on one LED for a long time.)

Note: This compiles but is not tested. YMMV.