Arduino RGB LED smooth transition speed control

Hey guys!

I am looking for a solution to control the speed of my RGB lamp. I got 2 push buttons and an RGB LED soldered together on a piece of perfboard. With a press of a button i want the color transition to change speed. With two buttons i would be able to speed it up or slow it down. But i cant get it to work. The transition works with a simple for cycle. While the cycle is running, it wont perceive the buttons so i cant change its speed. I have tried several codes, but i think the problem is with the for cycle itself. I would be glad if someone sent me a full program that works.

Looking for your answers

Looking for your code. Please post it between code tags.

While the cycle is running

Apparently, the "cycle" is blocking code. Don't write the code that way.

I would be glad if someone sent me a full program that works.

But you wouldn't learn anything.

The loop() function loops. Take advantage of that, and do NOT use any for loops or delay() calls in your code.

Read the "Using millis() for timing" sticky post.

I have tried with an other code, it does not contain for cycle. It wont work either.

int redPin = 11;
int grnPin = 10;
int bluPin = 9;

int black[3] = { 0, 0, 0 };
int white[3] = { 100, 100, 100 };
int red[3] = { 100, 0, 0 };
int green[3] = { 0, 100, 0 };
int blue[3] = { 0, 0, 100 };
int yellow[3] = { 40, 95, 0 };
int dimWhite[3] = { 30, 30, 30 };

int redVal = black[0];
int grnVal = black[1];
int bluVal = black[2];

int wait = 5;
int hold = 0;
int decSpeed = 14;
int incSpeed = 15;
int prevR = redVal;
int prevG = grnVal;
int prevB = bluVal;

void setup()
{
pinMode(redPin, OUTPUT);
pinMode(grnPin, OUTPUT);
pinMode(bluPin, OUTPUT);
pinMode(decSpeed, INPUT);
pinMode(incSpeed, INPUT);

}

void loop()
{
crossFade(red);
crossFade(green);
crossFade(blue);
crossFade(yellow);

if(digitalRead(decSpeed) == LOW) {
wait=wait+5;
if(wait > 255) {
wait=255;
}

else if(digitalRead(incSpeed) == LOW) {
wait=wait-5;
if(wait < 0) {
wait=0;
}
}
}
}

int calculateStep(int prevValue, int endValue) {
int step = endValue - prevValue;
if (step) {
step = 1020/step;
}
return step;
}

int calculateVal(int step, int val, int i) {

if ((step) && i % step == 0) {
if (step > 0) {
val += 1;
}
else if (step < 0) {
val -= 1;
}
}

if (val > 255) {
val = 255;
}
else if (val < 0) {
val = 0;
}
return val;
}

void crossFade(int color[3]) {

int R = (color[0] * 255) / 100;
int G = (color[1] * 255) / 100;
int B = (color[2] * 255) / 100;

int stepR = calculateStep(prevR, R);
int stepG = calculateStep(prevG, G);
int stepB = calculateStep(prevB, B);

for (int i = 0; i <= 1020; i++) {
redVal = calculateVal(stepR, redVal, i);
grnVal = calculateVal(stepG, grnVal, i);
bluVal = calculateVal(stepB, bluVal, i);

analogWrite(redPin, redVal);
analogWrite(grnPin, grnVal);
analogWrite(bluPin, bluVal);

delay(wait);

}
prevR = redVal;
prevG = grnVal;
prevB = bluVal;
delay(hold);
}

Ok. There are some goos things in there that will be useful in the final code. But there is still a whacking great for() loop.

The main thing is to let loop() loop. A reasonably simple loop() will run many times in each millisecond. You can check all your button inputs that quickly. Then check if enough time has passed since the color-stepper took a step. If so, then step the color and output that to the LEDs.

But now loop() needs to remember which color it is moving towards. It also has to detect when it has reached that color and decide which color is next.