RGB led fade

Hello everyone,

I have a question about RGB LEDs.

Can I make an RGB LED fade without changing the colour?

For example, I have the RED=200, BLUE= 170 and GREEN=40 in 0 to 255 values.

Can I make the LED fade without chaging these colours?

Thanks.

Try a different colour space, like HSV.

What is HSV?

But if I want to treat the data from an app that sends rgb values to the arduino. Then I don't know how to treat the rgb values to hsv on the app.

An when the arduino reads the values, what do I have to do? Note that I've done some code for the rgb model, but know nothing about the hsv one.

#include <softwareserial.h>
#include <wire.h>//Include libraries: SoftwareSerial & Wire
SoftwareSerial BT(0,1); //Define PIN11 & PIN12 as RX and TX pins
 
//RGB LED Pins
int PIN_RED = 3;
int PIN_GREEN = 5;
int PIN_BLUE = 6;
//RED LED at Pin 13
int RED_LED = 13;
String RGB = ""; //store RGB code from BT
String RGB_Previous = "255.255.255)"; //preserve previous RGB color for LED switch on/off, default White
String ON = "ON"; //Check if ON command is received
String OFF = "OFF"; //Check if OFF command is received
boolean RGB_Completed = false;
 
void setup() {
  Serial.begin(9600); //Arduino serial port baud rate:9600
  BT.begin(9600);//My HC-05 module default baud rate is 9600
  RGB.reserve(30);
 
  pinMode(RED_LED, OUTPUT); 
  //Set pin13 as output for LED, 
  // this LED is on Arduino mini pro, not the RGB LED
}
 
void loop() {
  // put your main code here, to run repeatedly: 
  
  //Read each character from Serial Port(Bluetooth)
  while(BT.available()){
    char ReadChar = (char)BT.read();
 
    // Right parentheses ) indicates complet of the string
    if(ReadChar == ')'){
      RGB_Completed = true;
    }else{
       RGB += ReadChar;
    }
  }
  
  //When a command code is received completely with ')' ending character
  if(RGB_Completed){
   //Print out debug info at Serial output window
      Serial.print("RGB:");
      Serial.print(RGB);
      Serial.print("     PreRGB:");
      Serial.println(RGB_Previous);
      
      if(RGB==ON){
          digitalWrite(13,HIGH);
          RGB = RGB_Previous; //We only receive 'ON', so get previous RGB color back to turn LED on
          Light_RGB_LED();          
 
      }else if(RGB==OFF){
          digitalWrite(13,LOW);
          RGB = "0.0.0)"; //Send OFF string to turn light off
          Light_RGB_LED();
      }else{
          //Turn the color according the color code from Bluetooth Serial Port
          Light_RGB_LED();   
          RGB_Previous = RGB;     
      }
      //Reset RGB String  
 
      RGB = "";
      RGB_Completed = false; 
  } //end if of check if RGB completed
  
} // end of loop
 
void Light_RGB_LED(){
 
  int SP1 = RGB.indexOf('.');
  int SP2 = RGB.indexOf('.', SP1+1);
  int SP3 = RGB.indexOf('.', SP2+1);
  String R = RGB.substring(0, SP1);
  String G = RGB.substring(SP1+1, SP2);
  String B = RGB.substring(SP2+1, SP3);
 
  //Print out debug info at Serial output window
  Serial.print("R=");
  Serial.println( constrain(R.toInt(),0,255));
  Serial.print("G=");
  Serial.println(constrain(G.toInt(),0,255));
  Serial.print("B=");
  Serial.println( constrain(B.toInt(),0,255));
  //Light up the LED with color code
 
//Because these RGB LED are common anode (Common positive)
//So we need to take 255 to minus R,G,B value to get correct RGB color code
  analogWrite(PIN_RED,  (255-R.toInt()));
  analogWrite(PIN_GREEN, (255-G.toInt()));
  analogWrite(PIN_BLUE,  (255-B.toInt()));
 
}

Convert from RGB to HSV. Then reduce the V parameter then convert back from HSV to RGB and write that to the LED.

A simpler way to dim an RGB value is to multiply the red, green and blue component values by the same percentage. For example

Red: 240 * 50% = 120
Blue: 170 * 50% = 85
Green: 40* 50% = 20

When the dimming reaches the lowest levels, the colour may change, but there is nothing that can easily be done about this, because the Arduino's PWM control is normally only 8 bit.

Red: 240 * 5% = 12
Blue: 170 * 5% = 8 <-- ideally this would be 8.5 to maintain the same colour
Green: 40* 5% = 2

PS.

  //Print out debug info at Serial output window
  Serial.print("R=");
  Serial.println( constrain(R.toInt(),0,255));
  Serial.print("G=");
  Serial.println(constrain(G.toInt(),0,255));
  Serial.print("B=");
  Serial.println( constrain(B.toInt(),0,255));

The above may appear to limit the r, g & b values to the range 0 to 255. But in reality it does nothing...