Ceiling/roof digital RGB led strip into LED profiler & remote control ir

Hi all,

i m new into arduino but i don't own anything yet.

My plan is:

I want to buy these LED aluminium profilers: https://www.ledokosmos.gr/%CF%84%CE%B1%CE%B9%CE%BD%CE%B9%CE%B5%CF%82-led/%CF%80%CF%81%CE%BF%CF%86%CE%AF%CE%BB-%CE%B3%CE%B9%CE%B1-%CF%84%CE%B1%CE%B9%CE%BD%CE%AF%CE%B5%CF%82-led/%CE%B8%CE%AE%CE%BA%CE%B7-%CE%B3%CE%B9%CE%B1-led-%CF%84%CE%B1%CE%B9%CE%BD%CE%AF%CE%B1-%CE%B1%CF%80%CE%BF-%CE%B1%CE%BD%CE%BF%CE%B4%CE%B9%CF%89%CE%BC%CE%AD%CE%BD%CE%BF-%CE%B1%CE%BB%CE%BF%CF%85%CE%BC%CE%AF%CE%BD%CE%B9%CE%BF-%CE%BC%CE%BF%CE%BD%CF%84%CE%AD%CE%BB%CE%BF-back.html

these are the inner dimensions of the profiler in cm https://www.ledokosmos.gr/image/cache/data/Profiles/Back/back7-500x500.jpg

(sorry for this bad url encoding :) )

I want to buy at least 12 meters / 472 inches (maybe less depending the power consumption) and create a rectangular "box" (4m * 3m), put some ropes/wires and hang it at the roof of my living room.

Inside the profiler i want to put this 60 led/m digital RBG strip: http://www.adafruit.com/products/1138.

I will need 10-12 meters of led strip and i want to add an IR sensor on Arduino and program this remote control http://www.ledbrite.co.uk/655-thickbox/rgb-led-controller-12volt-with-44-way-remote.jpg to operate the LEDs. This is possible if i follow this guide: http://pkmc.uk.com/blogs/tutorials/14169197-tv-remote-to-control-neomatrix in order to operate the brightness, colors, etc... I want smooth color transitions like this video: http://www.instructables.com/id/Color-changing-box-shelves-with-LED-strips-and-Ard/

Questions:

  1. What arduino do i need in order to drive the LEDs? Arduino Mega is efficient?
  2. What power supply is best for this setup and how i should connect the strips on it?
  3. If in the future i want to expand the strips and add more meters (this led profile supports 2 led strips, one heading vertically and one horizontaly) what i should do? Just adding another PSU will work just fine and just connect the strips on arduino?

Thanks

Hi.

  1. Uno/Nano3/Micro/Pro Micro will be fine. Mega would have no advantages for the project, as you describe it, that I can think of.

  2. Use a 5V switch-mode power supply. Lots of amps! Each metre will need 3.6A, so that could be 50A! Not sure these strips can handle that, so you may need to provide separate 5V and Ground power lines to each strip.

  3. For expansion, yes I think extra PSUs can be used to drive more strips. Grounds must all be connected. Data out from each strip feeds data in from previous strip. Arduino feeds data to first strip. Update rate will slow down as you add more strips, but should still be OK.

Paul

Thanks for the reply!

I m trying to implement fade of the strip (analog, the digital ones havn’t arrived yet from e-shop) but the fade won’t last, it just blinks very fast. I don’t know too much about millis function and how to use the loop without delay.

Here’s the sketch, any help is much appreciated:

/*
*  Control remoto de LED RGB 
*  Ejemplo de como hacer variar el color y el brillo con un led RGB  
*  con un mando a distancia.
*  Se utiliza un receptor de infrarrojos del tipo TSOP1738 
*  Autor: Jose Daniel Herrera
*  Fecha: 28/08/2012
*  http://arduino-guay.blogspot.com.es
*/
 
#include <IRremote.h>
#include <RGBMood.h>

 
int RECV_PIN = 11;
int R_PIN = 6;
int G_PIN = 5;
int B_PIN = 3;

int value, value2;
long time=0;
int periode = 2000;
int displace = 500;


RGBMood m(R_PIN, G_PIN, B_PIN);
 
#define ON                0xF4F37A66
#define OFF               0x1363ADB4
#define BRIGHTNESS_UP     0xE6721691
#define BRIGHTNESS_DOWN   0xE9721B48
#define FLASH             0xFFF00F
#define STROBE            0xFFE817
#define FADE              0x39ED1255
#define SMOOTH            0xFFC837
 
#define RED               0x9D561314
#define GREEN             0XCB8E93A5
#define BLUE              0xC88E8EEC
#define WHITE             0x16DBBEE3
 
#define ORANGE            0xFFB04F
#define YELLOW_DARK       0xFFA857
#define YELLOW_MEDIUM     0xFF9867
#define YELLOW_LIGHT      0xFF8877
 
#define GREEN_LIGHT       0XFF30CF
#define GREEN_BLUE1       0XFF28D7
#define GREEN_BLUE2       0XFF18E7
#define GREEN_BLUE3       0XFF08F7
 
#define BLUE_RED          0XFF708F
#define PURPLE_DARK       0XFF6897
#define PURPLE_LIGHT      0XFF58A7
#define PINK              0XFF48B7
 
#define INCREMENTO 30
 
unsigned long rgb = 0;
byte r,g,b;
 
IRrecv irrecv(RECV_PIN);
 
decode_results results;
 
 
void setup()
{
  irrecv.enableIRIn(); // Inicializamos el receptor
  Serial.begin(9600);
  m.setMode(RGBMood::RANDOM_HUE_MODE);  // Automatic random fade.
  m.setHoldingTime(4000);  // Keep the same color for 4 seconds before fading again.
  m.setFadingSteps(150);   // Fade with 150 steps.
  m.setFadingSpeed(50);    // Each step last 50ms. A complete fade takes 50*150 = 7.5 seconds
  m.setHSB(random(359), 255, 255); // Random hue mode only change the hue so we first set the saturation and brightness to what we want.
  pinMode(R_PIN, OUTPUT);   
  pinMode(G_PIN, OUTPUT);   
  pinMode(B_PIN, OUTPUT);   
}
 
 
void variar (byte* color, char valor) {
    if (valor > 0) {
        if ( *color + valor <= 255) {
            *color += valor;
        } else {
            *color = 255;
        }
    } else { 
        if (*color + valor >= 0) {
            *color += valor;
        } else {
            *color = 0;
        }
  }
}
 
void RGB(unsigned long valor) {
   r = valor >> 16; 
   g = (valor >> 8) & 0xFF; 
   b = valor & 0xFF; 
}


void loop() {
  if (irrecv.decode(&results)) {
    
      switch (results.value) {
           case BRIGHTNESS_UP : 
               variar (&r, INCREMENTO);
               variar (&g, INCREMENTO);
               variar (&b, INCREMENTO);
               break; 
           case BRIGHTNESS_DOWN : 
               variar (&r, -INCREMENTO);
               variar (&g, -INCREMENTO);
               variar (&b, -INCREMENTO);
               break; 
           case OFF :
               r = g = b = 0;
               break;    
           case RED           : RGB(0x00FF0000); break;
           case GREEN         : RGB(0x0000FF00); break;
           case BLUE          : RGB(0x000000FF); break;
           case WHITE         : RGB(0x00FFFFFF); break;
           case ORANGE        : RGB(0x00FF7F00); break;
           case YELLOW_DARK   : RGB(0x00FFAA00); break;
           case YELLOW_MEDIUM : RGB(0x00FFD400); break;
           case YELLOW_LIGHT  : RGB(0x00FFFF00); break;
           case GREEN_LIGHT   : RGB(0x0000FFAA); break;
           case GREEN_BLUE1   : RGB(0x0000FFFF); break;
           case GREEN_BLUE2   : RGB(0x0000AAFF); break;
           case GREEN_BLUE3   : RGB(0x000055FF); break;
           case BLUE_RED      : RGB(0x00000080); break;
           case PURPLE_DARK   : RGB(0x003F0080); break;
           case PURPLE_LIGHT  : RGB(0x007A00BF); break;
           case PINK          : RGB(0x00FF00FF); break;
           case FADE          : 
         time = millis();
  value = 128+127*cos(2*PI/periode*time);
  value2 = 128+127*cos(2*PI/periode*(displace-time));
    m.tick();
    delay(5000);
  
            break;
      }
      Serial.println(results.value, HEX);
      Serial.println(r,DEC);
      Serial.println(g, DEC);
      Serial.println(b, DEC);
      analogWrite(R_PIN,r);
      analogWrite(G_PIN,g);
      analogWrite(B_PIN,b);
    
    irrecv.resume(); // Receive the next value
  }
}

Also, when i m pressing brightness up the color turns to white after some buttons.

Hi,

I'm not familiar with those libraries, but I would not be surprised if one or both of them disable interrputs as part of their operation. This affects how the millis() function works. It can no longer be used to accurately measure time. I recently had the same problem building a clock that uses a ws2812b led strip. I wanted to change the fade patterns every second, but I could not use millis() because the NeoPixel library disables interrupts. I fixed this by connecting the sqw/int pin from the rtc to an Arduino input, set it to 1Hz and polled for a change on the input. Unfortunately I don't think that idea will help you much.

I can understand why the colour changes to white when you press brightness +. As each of the red/green/blue values hit 255 they can no longer keep the same ratio to the other 2 values and the colour is lost. I suggest you change your sketch to use the HLS system instead of RGB.

Paul

Thanks for you guidance, this is the code so far:

#include <TimerOne.h>
#include <IRremote.h>
#include <RGBMood.h>

int RECV_PIN = 2;  // IR-Receiver PIN
int led = 13;       // Satus-LED PIN
int modus;          // Modus for Interrupt-Querry 
int ledr = 11;       // RGB LED red PIN
int ledg = 12;       // RGB LED green PIN                       
int ledb = 13;       // RGB LED blue PIN
int SerialBuffer = 0; 

RGBMood m(ledr, ledg, ledb);

int timerwert = 20;   // Timer time for Interrupt in ms
  
String readString;

// Color arrays
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 brightness = 0;    // how bright the LED is
int fadeAmount = 5;    // how many points to fade the LED by
// etc.

// Set initial color
int redVal = black[0];
int grnVal = black[1]; 
int bluVal = black[2];

int wait = 10;      // 10ms internal crossFade delay; increase for slower fades
int hold = 0;       // Optional hold when a color is complete, before the next crossFade
int DEBUG = 1;      // DEBUG counter; if set to 1, will write values back via serial
int loopCount = 60; // How often should DEBUG report?
int repeat = 3;     // How many times should we loop before stopping? (0 for no stop)
int j = 0;          // Loop counter for repeat

// Initialize color variables
int prevR = redVal;
int prevG = grnVal;
int prevB = bluVal;

#define ON                0xF4F37A66
#define OFF               0x1363ADB4
#define BRIGHTNESS_UP     0xE6721691
#define BRIGHTNESS_DOWN   0xE9721B48
#define FLASH             0xFFF00F
#define STROBE            0xFFE817
#define FADE              0x39ED1255
#define SMOOTH            0xFFC837
 
#define RED               0x9D561314
#define GREEN             0XCB8E93A5
#define BLUE              0xC88E8EEC
#define WHITE             0x16DBBEE3
 
#define ORANGE            0xFFB04F
#define YELLOW_DARK       0xFFA857
#define YELLOW_MEDIUM     0xFF9867
#define YELLOW_LIGHT      0xFF8877
 
#define GREEN_LIGHT       0XFF30CF
#define GREEN_BLUE1       0XFF28D7
#define GREEN_BLUE2       0XFF18E7
#define GREEN_BLUE3       0XFF08F7
 
#define BLUE_RED          0XFF708F
#define PURPLE_DARK       0XFF6897
#define PURPLE_LIGHT      0XFF58A7
#define PINK              0XFF48B7


IRrecv irrecv(RECV_PIN);
decode_results results;

void setup()
{
  pinMode(ledr, OUTPUT); // Set RGB LED Pins as Output
  pinMode(ledg, OUTPUT); // Set RGB LED Pins as Output
  pinMode(ledb, OUTPUT); // Set RGB LED Pins as Output
  pinMode(led, OUTPUT); // set Status-LED as Output 
  m.setMode(RGBMood::RANDOM_HUE_MODE);  // Automatic random fade.
  m.setHoldingTime(4000);  // Keep the same color for 4 seconds before fading again.
  m.setFadingSteps(150);   // Fade with 150 steps.
  m.setFadingSpeed(50);    // Each step last 50ms. A complete fade takes 50*150 = 7.5 seconds
  m.setHSB(random(359), 255, 255);
  
Serial.begin(9600);
 
  irrecv.enableIRIn(); // Start of IR-Recive
     
  Timer1.initialize(timerwert); // Initialisation of Timer-Interrupts
  Timer1.attachInterrupt(leseIR); // IR-Read from Interrupt
}

void leseIR(){
  if (irrecv.decode(&results)){
     irrecv.resume();  // Receive the next value
    switch (results.value)  {
     
      case FADE: // Modus Fade (DIY 4)
        modus = 1;  
      break;
      
      case 0xFF906F: // Modus pcambi (DIY 5)
        modus = 2;  
      break;
     
      case ON:  //Power
       modus = 0;
        crossFade(white);         // RGB LEDs Off 
      break;
            case OFF:  //Power
       modus = 0;
        crossFade(black);         // RGB LEDs Off 
      break;
       
      case BLUE:  //Blau 0,0,255
        modus = 0;
      crossFade(blue);
      break;
      
      case RED: //Rot
        modus = 0;
        crossFade(red);
      break;
      
      case GREEN://Grün
        modus = 0;
        crossFade(green);
      break;  
      
      case WHITE: //Weiss
        modus = 0;
        crossFade(white);
      break;
      
      case BRIGHTNESS_UP: //DIMMING
        modus = 0;
        // fade in from min to max in increments of 5 points:
  for(int fadeValue = 0 ; fadeValue <= 255; fadeValue +=5) { 
    // sets the value (range from 0 to 255):
    analogWrite(ledg, fadeValue);    

  }
        
      break;
      
       case BRIGHTNESS_DOWN: //orange
        modus = 0;
      for(int fadeValue = 255 ; fadeValue >= 0; fadeValue -=5) { 
    // sets the value (range from 0 to 255):
    analogWrite(ledg, fadeValue);    
      }

      break;
      
      case 0xFFAA55://Grün mitrtel
        modus = 0;
 
      break;  
      
      case 0xFF926D: //blau mittel
        modus = 0;

      break; 
      
      case 0xFF12ED: //rosa
        modus = 0;

      break;      
     
     
     }             // Switch END

  }               

}                  

void loop() {
if(modus==1){    // Querry pb Modus:1 
m.tick();
}

      Serial.println(results.value, HEX);
      Serial.println(DEC);
      Serial.println(DEC);
      Serial.println(DEC);
   
  } 
  
  
  int calculateStep(int prevValue, int endValue) {
  int step = endValue - prevValue; // What's the overall gap?
  if (step) {                      // If its non-zero, 
    step = 1020/step;              //   divide by 1020
  } 
  return step;
}

/* The next function is calculateVal. When the loop value, i,
*  reaches the step size appropriate for one of the
*  colors, it increases or decreases the value of that color by 1. 
*  (R, G, and B are each calculated separately.)
*/

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

  if ((step) && i % step == 0) { // If step is non-zero and its time to change a value,
    if (step > 0) {              //   increment the value if step is positive...
      val += 1;           
    } 
    else if (step < 0) {         //   ...or decrement it if step is negative
      val -= 1;
    } 
  }
  // Defensive driving: make sure val stays in the range 0-255
  if (val > 255) {
    val = 255;
  } 
  else if (val < 0) {
    val = 0;
  }
  return val;
}

/* crossFade() converts the percentage colors to a 
*  0-255 range, then loops 1020 times, checking to see if  
*  the value needs to be updated each time, then writing
*  the color values to the correct pins.
*/

void crossFade(int color[3]) {
  // Convert to 0-255
  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(ledr, redVal);   // Write current values to LED pins
    analogWrite(ledg, grnVal);      
    analogWrite(ledb, bluVal); 

    delay(wait); // Pause for 'wait' milliseconds before resuming the loop

 
  }
  // Update current values for next loop
  prevR = redVal; 
  prevG = grnVal; 
  prevB = bluVal;
  delay(hold); // Pause for optional 'wait' milliseconds before resuming the loop
}

it’s working like a charm, the fade operates smoothly using timer1, the colors appear correct on led, BUT, i cant fix the brightness part. Can you or someone else provide a sample code to do this?

if anyone else wants to use the code, i m using an Arduino Mega 2560, please use the same PINs as mine since timers works only on 11,12,13 on this Arduino. (see TimerOne link below for more info on other boards)

RGB mood library: http://forum.arduino.cc/index.php/topic,90160.0.html
TimerOne library: GitHub - PaulStoffregen/TimerOne: TimerOne Library with optimization and expanded hardware support
IR Library: https://github.com/shirriff/Arduino-IRremote

i m using a small Xbox 360 IR control, some HEX codes are left intact from the original sketch found on internet.

Thanks Paul, Here’s the code that has brightness control only when solid colors are selected: (not rbg mood fade):

#include <TimerOne.h>
#include <IRremote.h>
#include <RGBMood.h>

int RECV_PIN = 2;  // IR-Receiver PIN
int led = 13;       // Satus-LED PIN
int modus;          // Modus for Interrupt-Querry 
int ledr = 11;       // RGB LED red PIN
int ledg = 12;       // RGB LED green PIN                       
int ledb = 13;       // RGB LED blue PIN
int SerialBuffer = 0; 
int c[3];


//RGB Pins Array
int CH[3] = {11, 12, 13};
int val[3] = {0, 0, 0}; // led brightness 0-255


RGBMood m(ledr, ledg, ledb);

int timerwert = 20;   // Timer time for Interrupt in ms

String readString;

// Color arrays
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 brightness = 100;    // how bright the LED is
int fadeAmount = 5;    // how many points to fade the LED by
// etc.

// Set initial color
int redVal = black[0];
int grnVal = black[1]; 
int bluVal = black[2];

int wait = 10;      // 10ms internal crossFade delay; increase for slower fades
int hold = 0;       // Optional hold when a color is complete, before the next crossFade
int DEBUG = 1;      // DEBUG counter; if set to 1, will write values back via serial
int loopCount = 60; // How often should DEBUG report?
int repeat = 3;     // How many times should we loop before stopping? (0 for no stop)
int j = 0;          // Loop counter for repeat


// Initialize color variables
int prevR = redVal;
int prevG = grnVal;
int prevB = bluVal;

#define ON                0xF4F37A66
#define OFF               0x1363ADB4
#define BRIGHTNESS_UP     0xE6721691
#define BRIGHTNESS_DOWN   0xE9721B48
#define FLASH             0xFFF00F
#define STROBE            0xFFE817
#define FADE              0x39ED1255
#define SMOOTH            0xFFC837

#define RED               0x9D561314
#define GREEN             0XCB8E93A5
#define BLUE              0xC88E8EEC
#define WHITE             0x16DBBEE3

#define ORANGE            0xFFB04F
#define YELLOW_DARK       0xFFA857
#define YELLOW_MEDIUM     0xFF9867
#define YELLOW_LIGHT      0xFF8877

#define GREEN_LIGHT       0XFF30CF
#define GREEN_BLUE1       0XFF28D7
#define GREEN_BLUE2       0XFF18E7
#define GREEN_BLUE3       0XFF08F7

#define BLUE_RED          0XFF708F
#define PURPLE_DARK       0XFF6897
#define PURPLE_LIGHT      0XFF58A7
#define PINK              0XFF48B7
#define MAX 255 

IRrecv irrecv(RECV_PIN);
decode_results results;

void setup()
{
  pinMode(ledr, OUTPUT); // Set RGB LED Pins as Output
  pinMode(ledg, OUTPUT); // Set RGB LED Pins as Output
  pinMode(ledb, OUTPUT); // Set RGB LED Pins as Output
  pinMode(led, OUTPUT); // set Status-LED as Output 
 //initiate rgb pins output
    for (int i=0; i<3; i++)
  {
    pinMode(CH[i], OUTPUT);
  }

  m.setMode(RGBMood::RANDOM_HUE_MODE);  // Automatic random fade.
  m.setHoldingTime(4000);  // Keep the same color for 4 seconds before fading again.
  m.setFadingSteps(150);   // Fade with 150 steps.
  m.setFadingSpeed(50);    // Each step last 50ms. A complete fade takes 50*150 = 7.5 seconds
  m.setHSB(random(359), 255, 255);

Serial.begin(9600);

  irrecv.enableIRIn(); // Start of IR-Recive

  Timer1.initialize(timerwert); // Initialisation of Timer-Interrupts
  Timer1.attachInterrupt(leseIR); // IR-Read from Interrupt
}

void leseIR(){
  if (irrecv.decode(&results)){
     irrecv.resume();  // Receive the next value
    switch (results.value)  {

      case FADE: // Modus Fade (DIY 4)
        modus = 1;  
      break;

      case 0xFF906F: // Modus pcambi (DIY 5)
        modus = 2;  
      break;

      case ON:  //Power
       modus = 0;
        crossFade(white);         // RGB LEDs Off 
      break;
            case OFF:  //Power
       modus = 0;
        crossFade(black);         // RGB LEDs Off 
      break;

      case BLUE:  //Blau 0,0,255
        modus = 0;
      crossFade(blue);
      break;

      case RED: //Rot
        modus = 0;
        crossFade(red);
      break;

      case GREEN://Grün
        modus = 0;
        crossFade(green);
      break;  

      case WHITE: //Weiss
        modus = 0;
        crossFade(white);
      break;

      case BRIGHTNESS_UP: //DIMMING UP
        modus = 0;
    brightness += 5;
    if (brightness > 255) brightness = 255;
    c[0] = prevR; c[1] = prevG; c[2] = prevB;
    analogWrite(ledr, redVal * brightness / 255);   // Write current values to LED pins
    analogWrite(ledg, grnVal * brightness / 255);      
    analogWrite(ledb, bluVal * brightness / 255);

      break;

       case BRIGHTNESS_DOWN: //DIMMING DOWN
         modus = 0;
    brightness -= 5;
    if (brightness < 0) brightness = 0;
    c[0] = prevR; c[1] = prevG; c[2] = prevB;
    analogWrite(ledr, redVal * brightness / 255);   // Write current values to LED pins
    analogWrite(ledg, grnVal * brightness / 255);      
    analogWrite(ledb, bluVal * brightness / 255);


      break;

      case 0xFFAA55://Grün mitrtel
        modus = 0;
      break;  

      case 0xFF926D: //blau mittel
        modus = 0;

      break; 

      case 0xFF12ED: //rosa
        modus = 0;

      break;      


     }             // Switch END

  }               
}                  

void loop() {
if(modus==1){    // Querry pb Modus:1 
m.tick();
}
if(modus==2){    // Querry pb Modus:1 

}
        Serial.println(prevR);
        Serial.println(prevG);
        Serial.println(prevB);
//      Serial.println(results.value, HEX);
//      Serial.println(DEC);
//      Serial.println(DEC);
//      Serial.println(DEC);
//      Serial.print("channel 1,2,3 values:");              // sends  brightness values to the serial monitor
    //  for(int i=0; i<3; i++){                             // every time the remote is pressed
    //  Serial.print(CH[i]);
//      Serial.print("   ");
    // } 
  } 


  int calculateStep(int prevValue, int endValue) {
  int step = endValue - prevValue; // What's the overall gap?
  if (step) {                      // If its non-zero, 
    step = 1020/step;              //   divide by 1020
  } 
  return step;
}

/* The next function is calculateVal. When the loop value, i,
*  reaches the step size appropriate for one of the
*  colors, it increases or decreases the value of that color by 1. 
*  (R, G, and B are each calculated separately.)
*/

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

  if ((step) && i % step == 0) { // If step is non-zero and its time to change a value,
    if (step > 0) {              //   increment the value if step is positive...
      val += 1;           
    } 
    else if (step < 0) {         //   ...or decrement it if step is negative
      val -= 1;
    } 
  }
  // Defensive driving: make sure val stays in the range 0-255
  if (val > 255) {
    val = 255;
  } 
  else if (val < 0) {
    val = 0;
  }
  return val;
}

/* crossFade() converts the percentage colors to a 
*  0-255 range, then loops 1020 times, checking to see if  
*  the value needs to be updated each time, then writing
*  the color values to the correct pins.
*/

void crossFade(int color[3]) {
  // Convert to 0-255
  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(ledr, redVal);   // Write current values to LED pins
    analogWrite(ledg, grnVal);      
    analogWrite(ledb, bluVal); 

    delay(wait); // Pause for 'wait' milliseconds before resuming the loop


  }
  // Update current values for next loop
  prevR = redVal; 
  prevG = grnVal; 
  prevB = bluVal;
  delay(hold); // Pause for optional 'wait' milliseconds before resuming the loop
}

geometrikal at arduino.stackexchange.com helped me also:

link