Haukman Haukman - 2 months ago 19
C# Question

How to calculate RGB+A+W (Amber + White) from RGB for LEDs

I need to write a function that takes RGB (0-255) input and outputs 5 values to drive a RGBAW LED (integrated chip that has red, blue, green, amber and white individual LEDs in one module). The output from my function has to be 5x 0-255 values. My preferred language is C#, but I can probably convert from any language.

I basically have a RGB input (call it Ri, Gi, Bi) each at 0-255. The LEDs are assumed to be calibrated to the same light output. From the output I want to calculate what output I should have for each of the five LEDs (R, G, B, A, W).

I want to make sure the light output isn't washed out with white when for example doing 100% Red (Ri = 255).

The function should look something like this:

public void CalculateRGBAW(byte ri, byte gi, byte bi, out byte r, out byte g, out byte b, out byte a, out byte w)
{
r = ri;
g = gi;
b = bi;
a = XXXXXXXXXXXXXXXXXXXXXXX;
w = XXXXXXXXXXXXXXXXXXXXXXX;
}


This is the type of LED light fixture this will drive: MARQ Gamut PAR H7, the user guide is linked there too (which doesn't say anything about how these are calibrated, this light fixture isn't high end so that's probably why, I think we just need to assume they are calibrated as far as this question is concerned).

Answer

First of all you need to calibrate your LEDs to obtain normalization coefficients

  1. R,G,B

    if R=G=B the output color should be gray-scale shade. To achieve this use scale coefficients for example:

    R'=r*R
    G'=g*G
    B'=b*B
    

    where r,g,b are scale coefficients and R,G,B are your ideal input values. The R',G',B' are values send to your LED driver. This equation is assuming linear behavior if not the case you need to change equation for example to polynomial like:

    R'=r0 + r1*R + r2*R^2 + ...
    

    Now you send R'=G'=B'=10 and check for the light color. If not white decrement the color which is exceeding white-ish. do this until you got white-ish color.

    Do this for more starting values like R'=G'=B'=10 , R'=G'=B'=20 , R'=G'=B'=30 , ... and remember the values after tuning to white. For example

     R` G` B`   beg
    10 10 12    10
    20 20 24    20
    30 30 36    30
    

    so in this example the blue LED is not as shiny as the R,G so it need to be scaled. From these few points you can estimate the dependence is linear without offset so

    r=1
    g=1
    b=36/30=24/20=12/10=1.2
    

    You need integers so you can use fixed point arithmetics like

    b=(12*256)/10 = 307
    B'=(B*b)/256
    
  2. White

    You need balance white to white. Ideally you should find R,G,B values that match a W value. and create functions

    Rw(W),Gw(W),Bw(W)
    

    which will match W with RGB LEDs. that will not be easy and may be some webcam with pixel picking tool will help (but must be also balanced).

  3. Amber

    similarly you need to find

    Ra(A),Ga(A),Ba(A)
    

    which will match A with RGB LEDs. as in the #2

color mixing

After calibration you should have R,G,B,A,W values linearized so you can use arithmetics on them. So to enhance your dynamic range let assume Ri,Gi,Bi are your input color values you want to drive. Here are some dependencies for the LEDs

         R   G   B
White = (W/3,W/3,W/3)
Amber = (A  ,A/2,0  )

So White can ease up all of the R,G,B

W = min(Ri,Gi,Bi)/3
R = Ri-W
G = Gi-W
B = Bi-W

Amber can ease up R,G so find A

A = R
if (A>G*2) A=G*2
R = Ri-A
G = Gi-A/2
B = Bi

And when put all together

W = min(Ri,Gi,Bi)/3
A = Ri-W
if (A>(Gi-W)*2) A=(Gi-W)*2
R = Ri-W-A
G = Gi-W-A/2
B = Bi-W

So now you can use Ri,Gi,Bi even above <0-255> (for some colors) and still have R,G,B in <0,255>. You can also use W as brightness and A as yellow balance (warmth)