Leds not coming on at the same time

Hello, I am a newbie to the Arduino world and C programming as well. I have been going for the last few days building a circuit, designing what I want from it, then improving and adding new features. I have one large program that I am trying out smaller sections of first as their own. In this example, I have 5 Leds, and at the press of a button up to two will be randomly selected and turn on. Just turning on is fine and they turn on at the same time, but when I put in the code to have them fade up from 0 to 255 it happens one Led at a time.
I know what is wrong, it is going through the For loop for each Led at a time. How would I go about having them fade up at the same time?

//quickly fading the Leds on
void randomLedUpdate(int ledPin)
{
  for (int i = 0; i<=255; i++) 
  {
    analogWrite(ledPin, i);
    delay(1);
  }
}

and then later..

 //if button is pressed, then turn on the two random Leds
  if ((buttonState == HIGH) && (firstLoop == 0))
  {
    digitalWrite(randomLed1, LOW);   //first turn off any previously lit Leds
    digitalWrite(randomLed2, LOW);
    
    randomLed1 = ledArray[random(0,5)];  //assign the two Random leds from 
    randomLed2 = ledArray[random(0,5)];  //two available from the Led Array

    randomLedUpdate(randomLed1);  //send these random values to the randomLedUpdate
    randomLedUpdate(randomLed2);  //function to have them fade on

    firstLoop = 1;  //set it so that the 2nd and every other time the loop repeats, it does not
  }                 //get new random numbers.

I see that I am sending one Led to fade up, then the 2nd is going to the function to fade up, how would I put it so that they are both fading up at the same time?

edit And as soon as I posted this I realized where I was going wrong. I sent both randomLed1 & 2 up to the function, and just added another analogWrite line for ledPin2.

void randomLedUpdate(int ledPin1, int ledPin2)
{
  for (int i = 0; i<=255; i++) 
  {
    analogWrite(ledPin1, i);
    analogWrite(ledPin2, i);
    delay(1);
  }
}

To make your life easier, put the LEDs in an array

Then it will be a lot easier and clearer to see that you need to update all the LEDs within your dimmer loop.

As you get more experience, you can swap out the delay() and use millis() to trigger the level changes - one at a time, or simultaneously.

Good thinking!

If you want to talk more like a programmer, you would say you passed both randomLed1 & 2 to the function.

And you could say you rewrote the function to take two arguments, the two LEDs to fade up.

Or you added another argument to the function.

And this

I am trying out smaller sections of [one large program] first as their own.

is so nice to see. So many ppl just throw everything together and wonder why it doesn't work...

a7

your for loop "blocks" (or uses) the programm until it is finished.
you might consider to use a classical "BlinkWithoutDelay"
you could combine that with the "State Change Detection"
Everything is in the IDE.

some steps further you might declare some objects, and come up with a sketch - making everything very expandable, still readable and easy to maintain.

I would try following:

  • a class for smooth LEDs
  • a class for buttons
  • two arrays for the pins
    that's more or less all you need.
/*
  Dim several LEDs in parallel
  https://forum.arduino.cc/t/leds-not-coming-on-at-the-same-time/899626
  by noiasca
*/

// a dimmable Led
class SmoothLed {
    const byte ledPin;                   // a GPIO for the LED
    uint16_t currentBrightness = 0;      // actual brightness of Pin
    const uint16_t maxBrightness = 255;  // native PWM is only 8 bit
    uint8_t interval = 15;               // delay for each step
    unsigned long previousMillis;        // last timestamp
    byte state = 0;                      // 0 off, 1 on

  public:
    SmoothLed(byte ledPin) : ledPin(ledPin)
    {}

    void begin() {
      pinMode(ledPin, OUTPUT);
    }
    void on() {                    // switch smooth on
      state = 1;
    }
    void off() {                   // switch smooth off
      state = 0;
    }
    void toggle() {               // switch on or off
      state = !state;
    }
    void setInterval(uint8_t newInterval)
    {
      interval = newInterval;
    }
    void update() {
      if (state == 1 && currentBrightness < maxBrightness && millis() - previousMillis > interval)
      {
        currentBrightness++;
        analogWrite(ledPin, currentBrightness);
        previousMillis = millis();
      }
      else if (state == 0 && currentBrightness > 0 && millis() - previousMillis > interval)
      {
        currentBrightness--;
        analogWrite(ledPin, currentBrightness);
        previousMillis = millis();
      }
    }
};

class Button                          // a simple class for buttons based on the "state change detection" example
{
    const byte buttonPin;
    const byte debounceDelay = 50;    // the debounce time; increase if the output flickers
    bool lastButtonState = HIGH;      // the previous reading from the input pin
    byte lastDebounceTime = 0;        // the last time the output pin was toggled - we check only ONE byte, so I didn't mess around with unsigned long

  public:
    Button(byte attachTo) : buttonPin(attachTo) {}

    void begin() {
      pinMode(buttonPin, INPUT_PULLUP);
    }

    // returns HIGH if button was clicked since last call - debounce
    bool wasPressed() {
      bool buttonState = LOW;                  // the current reading from the input pin
      byte reading = LOW;
      if (digitalRead(buttonPin) == LOW) reading = HIGH;              // if we are using INPUT_PULLUP we are checking invers to LOW Pin
      if (((millis() & 0xFF ) - lastDebounceTime) > debounceDelay)    // If the switch changed, AFTER any pressing or noise
      {
        if (reading != lastButtonState && lastButtonState == LOW)     // If there was a change and and last state was LOW
        {
          buttonState = HIGH;
        }
        lastDebounceTime = millis() & 0xFF;
        lastButtonState = reading;
      }
      return buttonState;
    }
};

SmoothLed smoothLed[] {3, 5, 6, 9};  // PWM pins UNO are 3, 5, 6, 9, 10, 11
Button button[] {A0, A1, A2, A3};    // button connects pin with GND, "active LOW"

const size_t noOfLeds = sizeof(smoothLed) / sizeof(smoothLed[0]);  // how many LEDs are used

void setup() {
  Serial.begin(115200);
  for (auto &i : smoothLed) i.begin();
  for (auto &i : button) i.begin();

  smoothLed[0].setInterval(5);   // just as demo how to set a different speed/interval
  smoothLed[1].setInterval(10);
  smoothLed[0].on();             // switch LED on smoothly
  randomSeed(analogRead(A6));
}

void loop() {
  if (button[0].wasPressed())
  {
    byte rnd = random(2); // 0 or 1
    smoothLed[rnd].toggle();
  }
  if (button[2].wasPressed()) smoothLed[2].toggle(); // check  button index 2 if necessary, toggle the LED
  if (button[3].wasPressed()) smoothLed[3].toggle(); // check  button index 3 if necessary, toggle the LED

  for (auto &i : smoothLed) i.update();  // call each LED for update
}
1 Like

Wow. Thanks guys, I see a lot in your examples I haven't come across as yet, but I can see the ideas in it. I will have to practice with them.