Fading Arduino RGB LED from one color to the other?

后端 未结 7 1885
攒了一身酷
攒了一身酷 2021-02-03 12:15

I\'ve currently managed to get my LED to cycle through eight colors that I\'ve selected. Everything is working correctly, except that I want to go for a more natural feel, and w

7条回答
  •  情深已故
    2021-02-03 12:26

    This is probably what you are looking for. Whenever we want to shift color over the spectrum and trasition the colors in a circular and smooth motion, what we are really doing is shifting light using HUE in the HSI/HSV (Hue, Saturation, Intensity/Value) color space.

    Take if you will this figure:

    We will attach a value from 0-360 for hue because hue has 360 degrees of color. A value of 0.00 - 1.00 for saturation, and a value of 0.00 -1.00 for intensity/value

    Here is my circuit on the MEGA 2560:

    Here is video of this code running:

    So lets build a function that we can pass the hue value and a for loop inside our loop function to call that value 360 times to shift over the full rainbow of color.

    //Define the pins we will use with our rgb led
    int redPin = 9;
    int greenPin = 10;
    int bluePin = 11;
    
    //define that we are using common anode leds
    #define COMMON_ANODE
    
    void setup()
    {
      pinMode(redPin, OUTPUT);
      pinMode(greenPin, OUTPUT);
      pinMode(bluePin, OUTPUT);
    }
    
    int rgb[3];
    //Arduino has no prebuilt function for hsi to rgb so we make one:
    void hsi_to_rgb(float H, float S, float I) {
      int r, g, b;
      if (H > 360) {
        H = H - 360;
      }
      // Serial.println("H: "+String(H));
      H = fmod(H, 360); // cycle H around to 0-360 degrees
      H = 3.14159 * H / (float)180; // Convert to radians.
      S = S > 0 ? (S < 1 ? S : 1) : 0; // clamp S and I to interval [0,1]
      I = I > 0 ? (I < 1 ? I : 1) : 0;
      if (H < 2.09439) {
        r = 255 * I / 3 * (1 + S * cos(H) / cos(1.047196667 - H));
        g = 255 * I / 3 * (1 + S * (1 - cos(H) / cos(1.047196667 - H)));
        b = 255 * I / 3 * (1 - S);
      } else if (H < 4.188787) {
        H = H - 2.09439;
        g = 255 * I / 3 * (1 + S * cos(H) / cos(1.047196667 - H));
        b = 255 * I / 3 * (1 + S * (1 - cos(H) / cos(1.047196667 - H)));
        r = 255 * I / 3 * (1 - S);
      } else {
        H = H - 4.188787;
        b = 255 * I / 3 * (1 + S * cos(H) / cos(1.047196667 - H));
        r = 255 * I / 3 * (1 + S * (1 - cos(H) / cos(1.047196667 - H)));
        g = 255 * I / 3 * (1 - S);
      }
      rgb[0] = r;
      rgb[1] = g;
      rgb[2] = b;
    
    }
    void setColor(int red, int green, int blue)
    {
      #ifdef COMMON_ANODE
        red = 255 - red;
        green = 255 - green;
        blue = 255 - blue;
      #endif
      analogWrite(redPin, red);
      analogWrite(greenPin, green);
      analogWrite(bluePin, blue);
    }
    
    
    ///here we have our main loop and the for loop to shift color
    void loop()
    {
    //the for loop counts to 360 and because its in our control loop it will run forever
    // We will use int i to increment the actual desired color 
    for (int i=0; i<=360;i++){
      hsi_to_rgb(i,1,1);
      setColor(rgb[0],rgb[1],rgb[2]);
      //Changing the delay() value in milliseconds will change how fast the
      //the light moves over the hue values 
      delay(5);
      }
    
    
    }
    

提交回复
热议问题