4 LED PWM Chaser Help

Current code has fade on and fade off finish before going on to next LED. I would like to have the fade off continue a little bit in to the next LED. Here is current code:

int ledPin = 3;  
int ledPin2 = 5;
int ledPin3 = 6;  
int ledPin4 = 9;

void setup() {
  pinMode(ledPin, OUTPUT);   
  pinMode(ledPin2, OUTPUT);   
  pinMode(ledPin3, OUTPUT);   
  pinMode(ledPin4, OUTPUT);
}

void loop() {
  // fade in from min to max in increments of 5 points:
  for (int fadeValue = 0 ; fadeValue <= 255; fadeValue = fadeValue+5) {
    // sets the value (range from 0 to 255):
    analogWrite(ledPin, fadeValue);
    delay(2);
  }

  // fade out from max to min in increments of 5 points:
  for (int fadeValue = 255 ; fadeValue >= 0; fadeValue = fadeValue-5) {
    // sets the value (range from 0 to 255):
    analogWrite(ledPin, fadeValue);
    delay(2);
  }

  // fade in from min to max in increments of 5 points:
  for (int fadeValue = 0 ; fadeValue <= 255; fadeValue = fadeValue+5) {
    // sets the value (range from 0 to 255):
    analogWrite(ledPin2, fadeValue);
    // wait for 30 milliseconds to see the dimming effect
    delay(2);
  }

  // fade out from max to min in increments of 5 points:
  for (int fadeValue = 255 ; fadeValue >= 0; fadeValue = fadeValue-5) {
    // sets the value (range from 0 to 255):
    analogWrite(ledPin2, fadeValue);
    delay(2);
  }

  {
  // fade in from min to max in increments of 5 points:
  for (int fadeValue = 0 ; fadeValue <= 255; fadeValue = fadeValue+5) {
    // sets the value (range from 0 to 255):
    analogWrite(ledPin3, fadeValue);
    delay(2);
  }

  // fade out from max to min in increments of 5 points:
  for (int fadeValue = 255 ; fadeValue >= 0; fadeValue = fadeValue-5) {
    // sets the value (range from 0 to 255):
    analogWrite(ledPin3, fadeValue);
    delay(2);
  }

  // fade in from min to max in increments of 5 points:
  for (int fadeValue = 0 ; fadeValue <= 255; fadeValue = fadeValue+5) {
    // sets the value (range from 0 to 255):
    analogWrite(ledPin4, fadeValue);
    delay(2);
  }

  // fade out from max to min in increments of 5 points:
  for (int fadeValue = 255 ; fadeValue >= 0; fadeValue = fadeValue-5) {
    // sets the value (range from 0 to 255):
    analogWrite(ledPin4, fadeValue);
    delay(2);
  }

  }
}
const int ledPins[] = { 3, 5, 6, 9 };
const int numPins = sizeof(ledPins) / sizeof(ledPins[0]);

void setup() {
  for (int i = 0; i < numPins; i++) {
    pinMode(ledPins[i], OUTPUT);
  }
}

// Function to fade LEDs in and out
void fade(int startPin, int endPin, int start, int end, int step, long delayTime) {
  // Loop through the specified brightness range
  for (int value = start; value != end; value += step) {
    // Loop through the range of pins
    for (int pin = startPin; pin <= endPin; pin++) {
      // Set the analog output (brightness) for the current pin
      analogWrite(pin, value);
      delay(delayTime);
    }
  }
}

void loop() {
  for (int i = 0; i < numPins - 1; i++) {
    fade(ledPins[i], ledPins[i + 1], 0, 255, 5, 2); // Fade in
    fade(ledPins[i], ledPins[i + 1], 255, 0, -5, 2); // Fade out
  }
}

Thank you for replying.

Your code is almost what I would like, but each LED in it never turn off totally. I'd like Pin 3 to be off by the time it gets to Pin 6 and Pin 5 to be off by the time Pin 9 is reached.

Hello misterbee1

Consider:

//https://forum.arduino.cc/t/4-led-pwm-chaser-help/1189880
//https://europe1.discourse-cdn.com/arduino/original/4X/7/e/0/7e0ee1e51f1df32e30893550c85f0dd33244fb0e.jpeg
#define ProjectName "4 LED PWM Chaser Help"
#define NotesOnRelease "A"
// -- some useful text replacements used because I'm lazy with typing --
#define is ==
#define analog(x,y) analogWrite(x,y)
// make structures
struct LEDCHASER
{
  uint8_t pin;
  uint8_t value;
  uint8_t upDown;
  uint32_t interval;
  uint32_t now;
  void chase (uint32_t currentMillis)
  {
    if (currentMillis - now > interval)
    {
      now = currentMillis;
      if ((value is 0) or (value is 255)) upDown = upDown ? LOW : HIGH;
      analog(pin, upDown ? value++ : value--);
    }
  }
};
LEDCHASER ledchasers []
{
  {6, 64, LOW, 10, 0},
  {9, 128, LOW, 10, 0},
  {10, 64, LOW, 10, 0},
  {11, 32, LOW, 10, 0},
};
// make application
void setup()
{
  Serial.begin(115200);
  Serial.print("Source: "), Serial.println(__FILE__);
  Serial.print(ProjectName), Serial.print(" - "), Serial.println(NotesOnRelease);
  for (auto &ledchaser : ledchasers) pinMode(ledchaser.pin, OUTPUT);
  Serial.println(" =-> and off we go\n");
}
void loop()
{
  uint32_t currentMillis = millis();
  for (auto &ledchaser : ledchasers) ledchaser.chase(currentMillis);
}

Have a nice day and enjoy coding in C++.

Thank you both for replying. Your codes are helpful, but not exactly what I would like so here is a video of what I currently have:

I would like the exact sequence, but with the previous LED fading in to when the very next one turns on and so on. Preferably, I would like Pin 3 to be off by the time Pin 6 is reached and 5 off by the time 9 is gotten to. I suppose what I am requesting is very similar to "Cyclon" chasers, but with only 4 LEDs and in one direction.

const int ledPins[] = { 3, 5, 6, 9 };
const int numPins = sizeof(ledPins) / sizeof(ledPins[0]);
const long delayValue = 500;

// Array to store the state of each pin
int pinStates[numPins];

void setup() {
  for (int i = 0; i < numPins; i++) {
    pinMode(ledPins[i], OUTPUT);
    // Initialize the state of each pin to 0 (off)
    pinStates[i] = 0;
  }
}

// Function to set the state of a pin
void setPinState(int pin, int state) {
  pinStates[pin] = state;
  analogWrite(ledPins[pin], state);
}

// Function to fade LEDs in and out
void fade(int startPin, int endPin, int start, int end, int step, long delayTime) {
  // Loop through the specified brightness range
  for (int value = start; value != end; value += step) {
    // Loop through the range of pins
    for (int pin = startPin; pin <= endPin; pin++) {
      // Set the analog output (brightness) for the current pin
      analogWrite(pin, value);
    }
    delay(delayTime);
  }
}

void loop() {
  for (int i = 0; i < numPins; i++) {
    int nextPin = (i + 1) % numPins; // Use the modulus operator to obtain the next pin

    // Fade out the previous LED
    fade(ledPins[i], ledPins[nextPin], 255, 0, -5, 2);
    delay(delayValue);

    // Fade in the next LED
    fade(ledPins[i], ledPins[nextPin], 0, 255, 5, 2);

    // Turn off the previous LED completely
    setPinState(i, 0);
  }
}

The delay value may need adjustment based on your preferences for the fading effect.

That is VERY close to what I would like. If only pin 9 would turn off all the way. The others do.

Hello misterbee1

consider:

//https://forum.arduino.cc/t/4-led-pwm-chaser-help/1189880
//https://europe1.discourse-cdn.com/arduino/original/4X/7/e/0/7e0ee1e51f1df32e30893550c85f0dd33244fb0e.jpeg
#define ProjectName "4 LED PWM Chaser Help"
#define NotesOnRelease "B"
// -- some useful text replacements used because I'm lazy with typing -- 
#define is ==
#define mod %
#define analog(x,y) analogWrite(x,y)
// make variables
constexpr uint8_t chaserSequence[] {64,128,255,128,64,0};
constexpr uint8_t LedPins[] {6,9,10,11};
// make application
void setup()
{
  Serial.begin(115200);
  Serial.print("Source: "), Serial.println(__FILE__);
  Serial.print(ProjectName), Serial.print(" - "), Serial.println(NotesOnRelease);
  for (auto LedPin:LedPins) pinMode(LedPin,OUTPUT);
  Serial.println(" =-> and off we go\n");
}
void loop()
{
  uint32_t currentMillis = millis();
  static uint32_t interval=100;
  static uint32_t now; 
  if (currentMillis - now >= interval) 
  {
    now=currentMillis;
    static uint8_t ledCounter=0;
    static uint8_t chaseCounter=0;
    chaseCounter=(chaseCounter+1) mod sizeof(chaserSequence);
    if (chaseCounter is 0) 
    ledCounter=(ledCounter+1) mod sizeof(LedPins);
    analog (LedPins[ledCounter],chaserSequence[chaseCounter]);
  }
}

Have a nice day and enjoy coding in C++.

With that code, the fade turns off before the next LED fades up. I'd like it stay on top of fade cycle while going into the next LED. But, thank you again.

Indeed, the transition from the last pin to the first one is not happening due to how I iterate in the loop() function. I've edited the code and used the module operator to address this.

That video is also an important lesson about how not to use breadboards! It's clear that the Nano and all the other components would fit onto the larger breadboard. The smaller breadboard only makes the circuit messy and fragile.

Would you like to know how to solve this type of problem yourself instead of relying on others?

If so, begin by drawing a graph/chart to show how the sequence should go. The X axis of the graph will be time, the Y axis will be brightness. Draw lines in 4 different colours to show how the brightness of the 4 LEDs should change over time.

Thank you PaulRB.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.