Slowly increase PWM on many pins, but reading Serial frequently

Hello, I'm facing a hard task for my skill today. I came up with a fancy led project, and I aim to use Arduino to control some led strips. I'll have at least 5 independent strips to control, which means 5 pins to control.
This is easy enough, despite the fact I cannot just analogWrite those pins because I have to do some fading to reach the desired value.
Also, the desired brightness (value to pwm) and the desired time for the fading is sent through Serial to the Arduino.

In simpler words, what I need is to continuously check the serial for new settings, while managing the brightness on many pins. These should be able to change all together in the worst scenario.

To better let you understand the fading process, here a code that actually fades a single pin, but does not allow to change anything until it's finished.

void draw(int x0, int x1, int T) {
  for (int i = 0; i < T; i = i + stepSize)
  {
    double x = ((double)i / T) * (x1 - x0) + x0;//Increased each cycle
    //Serial.println(x);
    analogWrite(ledPin, x);
    delay(stepSize);
  }
  analogWrite(ledPin, x1);
  return;
}

As far as I know interrupts are the key, but I'm not really sure how to use them, neither if I should run the serial reading or the fading program in the routine.

Thank you really for any help, suggestion, useful reading.

You need to post the complete program.

I suspect the first obstacle is your use of delay() because the Arduino can do nothing until a delay() completes.

And I think the second obstacle is your use of a FOR loop() because the Arduino can do nothing until that completes.

Have a look at how millis() is used to manage timing without blocking in Several Things at a Time.

And see Using millis() for timing. A beginners guide if you need more explanation.

Also note how each function runs very briefly and returns to loop() so the next one can be called. And there may be dozens of calls to a function before it is actually time for it to do anything.

Finally, I don't believe there will be any need to use interrupts.

...R

You don't need interrupts but if you're "stuck in a loop" you'll need to check/read the serial port inside the loop.

A short delay() is probably OK. For example, you can read the serial port between steps, but you probably don't want to wait until the fade is completed.

You'll need to make separate brightness variables for each LED strip... Don't use "x".... Maybe Brightness1, Brightness2, etc.

You might want to work on fading two strips differently (at the same time) before working on the serial read. Then work on the serial read separately before putting everything together and adding more strips.

You'll probably need some if-statements to stop the fading when you reach the maximum, minimum, or the target brightness.

Ok thanks, I know millis, and I know it is useful. I'll try tomorrow to write down some lines using that approach, which might work pretty good actually. But still, I was wondering if it is possible to implement some general function to avoid repeating the work as many times as the leds are.

Take mine as an academic question if you like. Imagine I had not 5, but N pins to manage. Is it possible to set up an efficient solution to manage them all as I described? That would be great!
Imagine I decide to add some more led, it would be just a one-minute-work to plug them in correctly this way!
Is it possible?

Thank you anyway for now, I'll wait your reply!

Yaxit:
Take mine as an academic question if you like. Imagine I had not 5, but N pins to manage.

The code snippet in your Original Post only seems to have one led so I'm not sure how you are thinking of managing 5.

The usual way to deal with multiple similar things is to put them in an array. The you could have something like

void loop() {
  analogWrite(ledPin[ndx], ledValue[ndx]);
  ndx++;
  if (ndx > 20) {
     ndx = 0;
   }
}

...R

I posted the code snippet with the only aim to give you an idea of what i was talking about when I said that the led had to "fade".

@Robin2 I could and I probably will in case it comes handy.

I'll try something now, and let you know, thank you for now.

Yaxit:
I posted the code snippet with the only aim to give you an idea of what i was talking about when I said that the led had to "fade".

That is certainly an element of the project. But I got the impression from your Original Post that the key question was how to manage several LEDs.

what I need is to continuously check the serial for new settings, while managing the brightness on many pins.

...R

You will have to use millis() based timing for every pin. You set some variables that govern the fading - best is to calculate how many ms until the next single step increase/decrease of your fade, and a final value. As you have five LED strips to handle, use an array for each.

It'd look a bit like this:

uint8_t nStrips = 5;
uint32_t fadeDelay[nStrips];
uint32_t previousStep[nStrips];
uint8_t targetLevel[nStrips];
uint8_t currentLevel[nStrips];
uint8_t stripPin[nStrips] = {1, 2, 3, 4, 5}; // the pin numbers.
void loop() {
  for (uint8_t i = 0; i < nStrips; i++) {
    if (millis() - previousStep[i] > fadeDelay[i]) { // Time to fade this one.
      previousStep[i] += fadeDelay[i]; // Time when the next step is to be taken.
      if (currentLevel[i] < targetLevel[i]) {
        targetlevel[i]++; // Fade brighter as we're below target.
      else if (currentLevel[i] > targetLevel[i] {
        targetlevel[i]--; // Fade dimmer as we're above target.
      }
      analogWrite(stripPin[i], currentLevel[i]);
    }
  }
  // Now read a character from Serial if available, and store it in a buffer.
  // When the buffer contains a complete command (e.g. you receive a \n), process it.
}