how can I change RGB values according to percentage

633 Views Asked by At

I want to change RGB values according to the percentage. means 0% should show Red , 50% should green and 100% will Blue color.I am working on fastled.I tried like this but didnt get the best result.can anyone suggest some good stuf??

int R,G,B;
int p = percentage;
if(p >= 0 and p <= 50){
    R = abs(p - 100);
    G = p*2;
}
if(p > 50 and p <= 100){
    G = abs(p - 100);
    B = p*2;
}

>! also tried

R = abs(p-100);
G = p/2;
B = p;

leds[0] = CRGB(R,G,B);
FastLED.show();
2

There are 2 best solutions below

0
doug On BEST ANSWER

From your problem statement, you probably want something like this which generates RGB colors counter-clockwise around the sRGB color gamut from red to blue.

#include <array>
#include <string>
#include <cmath>
#include <iostream>

std::array<uint8_t, 3> getcolorpercent(double percent)
{
    std::array<uint8_t, 3> rgb{};
    int segment{static_cast<int>(percent/25)};
    double percent_f = .01 * (percent - 25 * segment);
    double col0{ 1 }, col1{ 1 };
    if (segment % 2 == 0)
        col1 = sqrt(4 * percent_f);
    else
        col0 = sqrt(1 - 4 * percent_f);
    rgb[(segment / 2) % 3] = static_cast<uint8_t>(std::round(255*col0));
    rgb[(1 + segment / 2) % 3] = static_cast<uint8_t>(std::round(255 * col1));
    return rgb;
}

int main()
{
    auto print = [](const std::array<uint8_t, 3> rgb, std::string descr) {
        // note: 0+... is to convert uint8_t to int to precent interpreting as char
        std::cout << descr << " red:" << 0+rgb[0] << " green:" << 0+rgb[1] << " blue:" << 0+rgb[2] << '\n';
    };

    std::array<uint8_t, 3> rgb_red = getcolorpercent(0);
    std::array<uint8_t, 3> rgb_orange = getcolorpercent(15);
    std::array<uint8_t, 3> rgb_yellow = getcolorpercent(25);
    std::array<uint8_t, 3> rgb_cyan = getcolorpercent(75);
    std::array<uint8_t, 3> rgb_violet = getcolorpercent(130);
    print(rgb_red, "red=");
    print(rgb_orange, "orange=");
    print(rgb_yellow, "yellow=");
    print(rgb_cyan, "cyan=");
    print(rgb_violet, "violet=");
}

Output:

red= red:255 green:0 blue:0
orange= red:255 green:198 blue:0
yellow= red:255 green:255 blue:0
cyan= red:0 green:255 blue:255
violet= red:255 green:0 blue:228

This creates a (reversed) rainbow type from red to blue for 0% to 100%. Additionally, this has been expanded to allow percentages to exceed 100 which can be used to produces colors going from blue->violet->purple and back to red. Here's an image created from this going from percent 0 to 100:

rainbow

0
David R Tribble On

You need to convert percentage values to 8-bit binary values, i.e., convert values in the range [0,100] into values in the range [0,255] (which is [0x00,0xFF] in hex).

A simple scaling operation does this:

int r = pR * 255 / 100;    // percentage red to hex

or equivalently:

int r = pR * 0xFF / 100;   // percentage red to hex

The opposite conversion, from hex value to percentage, is just the reverse operation.

Note that since there are only 101 percentage values, you won't get all of the 256 possible 8-bit hex values when you do this conversion, but it should be close enough.