WS2812 Color Output

I have previously mentioned that I have been in the process of integrating the WS2812 RGB led with built-in PWM controller into a line of lighting products. You can see one of the prototype boards that we are currently testing now. The board is arranged in an 8×8 matrix and is meant to fit into a larger panel of similar matrix boards.

8x8 Matrix

These chips are really awesome and have an extremely small form factor, require very few additional passives to make them function properly, are extremely bright, and finally very inexpensive compared to their traditional counterparts. Adafruit and PJRChave done a lot of work to ensure that these leds are easy to control. There is a ton of documentation on how make them work despite their peculiar single pin timing control schema.

Some great images of these chips was taken by Seth Hardy at his blog Propane and Electrons .
SideBySideWS2812
PWM to Light Output

In testing with this 8×8 Matrix I wanted to be charecterize the pwm settings of the leds and their light response. As it stands an 8 bit byte defines each of the leds brightness. What is not known is whether these leds have a subsequently linear light response. To solve this question, I turned to the Taos TCS34717 and the associated breakout board from Tautic Electronics. This sensor and board coupled with this great OS Source Code makes integrating the sensor with the Arduino environment very easy. This sensor has 16 bit registers to measure Clear, Red, Green, and Blue light levels. Using this great app note the possibility to translate the sensor registers into real data was extremely valuable.

TCS34717

I constructed very simple light enclosing box with the 8×8 matrix on one end and the color sensor on the other. The box was sealed up to prevent ambient light from ruining the measured data. The brightness of these leds simply cannot be understood until you see them in person.

LightBox

Using an mBed and an Arduino to drive the 8×8 Matrix and the Color Sensor through a Rs-232 serial interface using Matlab I was able to control the brightness of the matrix leds and then measure the light received by the color sensor in an automated fashion. Using this method saved a ton of time and made analyzing the results alot easier. From the image below, a test was conducted that linearly ramped the RGB registers of the WS2812 from 0-255 simultaneously. This produced a “white light” that was observed by the color sensor. You can see that for the most part the output is fairly linear over the full 8 bit pwm range of the WS2812.
FullRGB

Using the equations from the Taos App Note the data from the test was post processed to determine the Illumination and Color Temperature of the 8×8 matrix was performed. The matlab code that was used to perform these calculations is presented below. For this test the Max Illumination was 335.1 Lux and the Color Temperature was determined to be 5810.89 Kelvin. This puts us in the bright white category of light as shown below. Overall I am very impressed with these results.ColorTempChart

clc,clear,close all

%% Load Test
[FileName,PathName,FilterIndex] = uigetfile('*.mat','Open Mat File');
File = FileName(1:findstr(FileName,'.')-1);
Ext = FileName((findstr(FileName,'.')+1):length(FileName));

load([PathName FileName]);
h=figure;
plot(Samples, Clr,'k.-',Samples, Red,'r.-',Samples, Grn,'g.-',Samples, Blu,'b.-')
xlabel('Sample #');ylabel('Integer Response');title(File)
legend('Clr','Red','Grn','Blu','Location','NorthWest');
xlim([1 256]);
ylim([0 max(Clr)]);
grid on
print(h,'-djpeg',['C:UsersohararpDocumentsISISWS2811TaosBlowWriteup' File]);
%% RGB
n=256;
RGB=[Red(n) Grn(n) Blu(n)]';
RGB=[Red; Grn; Blu]
%% Correlation Matrix
COR =[-0.14282 1.54924 -.95641;...
-0.32466 1.57837 -.73191;...
-0.68202 0.77073 0.56332];

XYZ=COR*RGB;
X=XYZ(1,:);
Y=XYZ(2,:);
Z=XYZ(3,:);

%% 3:2 Transform (4-5) - chromaticity coordinates
x = X./(X+Y+Z);
y = Y./(X+Y+Z);

%% Illuminance
Ill=[-0.32466 1.57837 -0.73191]*RGB; % Lux

%% CCT (6) - McCamy’s formula
n = (x - 0.3320) ./ (0.1858 - y);
CCT = 449*n.^3 + 3525*n.^2 + 6823.3*n + 5520.33; %degrees Kelvin (K)

%% Max
fprintf('Max Illumination = %f (Lux)n',max(Ill))
fprintf('Max CCT = %f (K)n',max(CCT))

Gamma Correction

Now that we know that we can reliably trust that the output of the RGB led is linear we can now apply gamma correction to account for the non-linear perception of brightness by the human eye. This is detailed very well at NeuroElec and is depicted in the figure below.

A very simple equation can be used to provide Gamma Correction

 GammaE=255*(res/255).^(1/.45) 

Coupling this equation with some linear math and some fprintf commands in matlab produces the wonderful lookup table below that can used to correct for the human eye’s non-linearity.

GammaEq

int GammaE[] = 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2,
2, 2, 2, 3, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5,
6, 6, 6, 7, 7, 7, 8, 8, 8, 9, 9, 9, 10, 10, 11, 11,
11, 12, 12, 13, 13, 13, 14, 14, 15, 15, 16, 16, 17, 17, 18, 18,
19, 19, 20, 21, 21, 22, 22, 23, 23, 24, 25, 25, 26, 27, 27, 28,
29, 29, 30, 31, 31, 32, 33, 34, 34, 35, 36, 37, 37, 38, 39, 40,
40, 41, 42, 43, 44, 45, 46, 46, 47, 48, 49, 50, 51, 52, 53, 54,
55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70,
71, 72, 73, 74, 76, 77, 78, 79, 80, 81, 83, 84, 85, 86, 88, 89,
90, 91, 93, 94, 95, 96, 98, 99,100,102,103,104,106,107,109,110,
111,113,114,116,117,119,120,121,123,124,126,128,129,131,132,134,
135,137,138,140,142,143,145,146,148,150,151,153,155,157,158,160,
162,163,165,167,169,170,172,174,176,178,179,181,183,185,187,189,
191,193,194,196,198,200,202,204,206,208,210,212,214,216,218,220,
222,224,227,229,231,233,235,237,239,241,244,246,248,250,252,255};