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.
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.
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?
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.
}