These are chat archives for Makuna/NeoPixelBus

7th
Jun 2015
sticilface
@sticilface
Jun 07 2015 00:06
Sure thing. I'll do that. Green flickering is reduced a lot!!! Still does it when I hit up a web page, but I've not checked my other pages of code for the uninits...
sticilface
@sticilface
Jun 07 2015 16:33

How interested would you be in a function that was able to dim pixels, but maintain constant brightness between them... I was using your Darken function but it really doesn't play nicely with mixed colour palettes.. ie.. rainbow... I've managed to mash together a functions copied from other clever people into one that takes an RgbColor object, and a byte 0-255, then converts the RGB colour into HSV space, alters the brightness component and converts back to RGB.. and it works like a treat.. you can dim mixed colours and they will maintain the same brightness and colour... the only issue might be CPU cycles as there is a bit of maths in there...

I've done a few preliminary tests and it seems to spit out the same colour mix you put in if the brightness is set to max... 255

Michael Miller
@Makuna
Jun 07 2015 17:00
Yeah, and the other thing is the blend between colors. I am using a linear blend between numbers, which really isn't good with colors. It should be curve in color space, again lots of math. I have been wanting to add these as options to the rgb object, which for the esp8266 is really lightweight but for the AvR is very heavy.
Send me the code and I will look for optimizations and include the functions.
sticilface
@sticilface
Jun 07 2015 17:20
ok, here is where i got the original lib... for credit etc... https://github.com/ratkins/RGBConverter
There are several ways of doing this, another lib i found didn't work as it used trigonometry... this somehow manages to keep it all using int.... which is very clever...
here is the function I've generated..
RgbColor dimbyhsv(RgbColor color, byte dim) {

// takes RGB ------- > HSV

    double rd = (double) color.R/255;
    double gd = (double) color.G/255;
    double bd = (double) color.B/255;
    double max = threeway_max(rd, gd, bd), min = threeway_min(rd, gd, bd);
    double h, s, v = max;

    double d = max - min;
    s = max == 0 ? 0 : d / max;

    if (max == min) { 
        h = 0; // achromatic
    } else {
        if (max == rd) {
            h = (gd - bd) / d + (gd < bd ? 6 : 0);
        } else if (max == gd) {
            h = (bd - rd) / d + 2;
        } else if (max == bd) {
            h = (rd - gd) / d + 4;
        }
        h /= 6;
    }

    v = (double) dim/255;   //  this  is where the brightness is adjusted.....  

//////  takes HSV -----> RGB

    double rD, gD, bD;

    int i = int(h * 6);
    double f = h * 6 - i;
    double p = v * (1 - s);
    double q = v * (1 - f * s);
    double t = v * (1 - (1 - f) * s);

    switch(i % 6){
        case 0: rD = v, gD = t, bD = p; break;
        case 1: rD = q, gD = v, bD = p; break;
        case 2: rD = p, gD = v, bD = t; break;
        case 3: rD = p, gD = q, bD = v; break;
        case 4: rD = t, gD = p, bD = v; break;
        case 5: rD = v, gD = p, bD = q; break;
    }

    color.R = rD * 255;
    color.G = gD * 255;
    color.B = bD * 255;

return color;  // send back the dimmed product... 


}
I just deployed this on all 3 lamp / strip set ups and it works great...
I thought about applying it to the blend as well... as i noticed that the blend transitions through white a lot of the time... i noticed it first as if my whole lamp goes white white... then it draws more than the 6A my power supply can handle.. 144 LEDs.. and it goes crazy.... I've also been wanting to incorporate a power limit function... ie... it'll write a 0,0,0 to an LED once certain power output has been reached...
I think your darken feature works really well when fading in and out from black though.. very smooth on/off with the lamp
sticilface
@sticilface
Jun 07 2015 17:29
The only thing i forgot to mention, is that if you are using the latest pulls of esp arduino somewhere the min,max functions have gone.. so it won't compile... a version I'm using from a week or so ago i fine though..
Michael Miller
@Makuna
Jun 07 2015 17:55
I had seen your issue on the min max, I might look into that while I also look into this. Still waiting for my leven adjusters.
sticilface
@sticilface
Jun 07 2015 18:25
cool... whats a leven adjuster... (u mean level adjuster to step up 3.3 to 5V)?
sticilface
@sticilface
Jun 07 2015 18:58
I may have just got a a different color blender to work using this code as well...
sticilface
@sticilface
Jun 07 2015 19:12
my understanding is not great... but the initial functions i found return different brightness values... i'll look into it.... the effect is very nice though! blends through colours and not through white..

RgbColor HsvFADErgb(RgbColor color1, RgbColor color2, byte progress) {


// COLOUR 1  ----->  HSV

    double r1d = (double) color1.R/255;
    double g1d = (double) color1.G/255;
    double b1d = (double) color1.B/255;
    double max = threeway_max(r1d, g1d, b1d), min = threeway_min(r1d, g1d, b1d);
    double h1, s1, v1 = max;

    double d1 = max - min;
    s1 = max == 0 ? 0 : d1 / max;

    if (max == min) { 
        h1 = 0; // achromatic
    } else {
        if (max == r1d) {
            h1 = (g1d - b1d) / d1 + (g1d < b1d ? 6 : 0);
        } else if (max == g1d) {
            h1 = (b1d - r1d) / d1 + 2;
        } else if (max == b1d) {
            h1 = (r1d - g1d) / d1 + 4;
        }
        h1 /= 6;
    }


// COLOUR 2  ----->  HSV

    double r2d = (double) color2.R/255;
    double g2d = (double) color2.G/255;
    double b2d = (double) color2.B/255;
    max = threeway_max(r2d, g2d, b2d);
    min = threeway_min(r2d, g2d, b2d);
    double h2, s2, v2 = max;

    double d2 = max - min;
    s2 = max == 0 ? 0 : d2 / max;

    if (max == min) { 
        h2 = 0; // achromatic
    } else {
        if (max == r2d) {
            h2 = (g2d - b2d) / d2 + (g2d < b2d ? 6 : 0);
        } else if (max == g2d) {
            h2 = (b2d - r2d) / d2 + 2;
        } else if (max == b2d) {
            h2 = (r2d - g2d) / d2 + 4;
        }
        h2 /= 6;
    }


double h = map_double ((double) progress, 0, 255, h1,h2);
double v = map_double ((double) progress, 0, 255, v1,v2);
double s = map_double ((double) progress, 0, 255, s1,s2);

//////  takes HSV -----> RGB

RgbColor color; 

    double rD, gD, bD;

    int i = int(h * 6);
    double f = h * 6 - i;
    double p = v * (1 - s);
    double q = v * (1 - f * s);
    double t = v * (1 - (1 - f) * s);

    switch(i % 6){
        case 0: rD = v, gD = t, bD = p; break;
        case 1: rD = q, gD = v, bD = p; break;
        case 2: rD = p, gD = v, bD = t; break;
        case 3: rD = p, gD = q, bD = v; break;
        case 4: rD = t, gD = p, bD = v; break;
        case 5: rD = v, gD = p, bD = q; break;
    }

    color.R = rD * 255;
    color.G = gD * 255;
    color.B = bD * 255;

return color;

} // end of HsvFADErgb

double map_double(double x, double in_min, double in_max, double out_min, double out_max)
{
  return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
}