# Control WS2812b panel current consumption

With the 16×16 123RGB panel base on WS2812b, I have 256leds able to consume up to 50mA each. I want to use this with a limited current under 3A and want to ensure using software, this limit will not be reached. This article detailed my code for doing this.

Each led value is stored in a int array where each value is containing rvb values.

To start, I have to store panel led values :

```// Maximum supported LED (this can be changed)
#define MAX_lEDS  256

// ---------------------------------------------------
// Raw data representing pixels each value format is
// --------bbbbbbbbrrrrrrrrgggggggg
// --------012345670123456701234567
// led matrix is 16x16, direction change each line
uint32_t rgb123_256_pixels[MAX_lEDS];
int max_x=0;  // number of Leds on a line
int max_y=0;  // number of Leds```

Then, to set and get a pixel in this table we have two functions:

```// ---------------------------------------------------
// set a pixel in the coordinate [0-15][0-15]
void rgb123_256_setPixel(uint32_t x, uint32_t y, uint32_t r, uint32_t g, uint32_t b) {
if ( x >= max_x || y >= max_y ) return;

int v = 0;
for ( int i = 0 ; i < 8 ; i++ )
v = ( v | (( b >> i ) & 1) ) << 1;
for ( int i = 0 ; i < 8 ; i++ )
v = ( v | (( r >> i ) & 1) ) << 1;
for ( int i = 0 ; i < 8 ; i++ )
v = ( v | (( g >> i ) & 1) ) << 1;
v = v >> 1;

uint32_t _x = (y & 1 != 0)?(max_x-1)-x:x;
rgb123_256_pixels[max_x*y+_x] = v;
}

// --------------------------------------------------
// get r,g,b values from the matrix
// @TODO - check it works
void rgb123_256_getPixel(uint32_t x, uint32_t y, uint32_t * r, uint32_t * g, uint32_t * b) {
if ( x >= max_x || y >= max_y ) return;
uint32_t _x = (y & 1 != 0)?(max_x-1)-x:x;
int v = rgb123_256_pixels[max_x*y+_x];

*g=0;
*r=0;
*b=0;
for ( int i = 0 ; i < 8 ; i++ )
*g = ( *g | (( v >> i ) & 1 )) << 1;
*g = *g >> 1;

for ( int i = 8 ; i < 16 ; i++ )
*r = ( *r | (( v >> i ) & 1 )) << 1;
*r = *r >> 1;

for ( int i = 16 ; i < 24 ; i++ )
*b = ( *b | (( v >> i ) & 1 )) << 1;
*b = *b >> 1;
}```

```// --------------------------------------------------
// evaluate current consumption of the 16x16 matrix
// per pixel : ma = 1 + R/16 + G/16 + B/16
// @TODO - finish it !
int rgb123_256_estimateCurrent() {
int ma = 0;
uint32_t r,g,b;
for ( int y = 0 ; y < max_y ; y++ ) {
for ( int x = 0 ; x < max_x ; x++ ) {
rgb123_256_getPixel(x,y,&r,&g,&b);
ma += 1 + (r >> 4) + ( g >> 4) + ( b >> 4 );
}
}
return ma;
}```

And manage the limitation like this:

```int max_i=-1;

// --------------------------------------------------
// setIntensityLimit - 5% error
void rgb123_256_setIntensityLimit(int _m) {
max_i=(_m - _m/20 );
rgb123_256_limitIntensity();
}

// --------------------------------------------------
// setIntensityLimit
void rgb123_256_limitIntensity() {
int _initialI = rgb123_256_estimateCurrent();
if ( _max_i > 0 && _initialI > max_i ) {
// ratio computation, the fixed part can't be reduce and is substracted from max_i
int ratio = ( (max_i - max_x*max_y) << 10 ) / (_initialI - max_x*max_y);

uint32_t r,g,b;
for ( int y = 0 ; y < max_y ; y++ ) {
for ( int x = 0 ; x < max_x ; x++ ) {
rgb123_256_getPixel(x,y,&r,&g,&b);
r = (( r * ratio ) >> 10);
g = (( g * ratio ) >> 10);
b = (( b * ratio ) >> 10);
rgb123_256_setPixel(x,y,r,g,b);
}
}

}
}```

This is giving pretty good result and as much as I have tested at this time the produced light with a 2500mA constraint is good enough for my project ! good news !

The complete sketch is here ; it works with RFDuino (16 Mhz arm cortex M0 only)

test_rfduino_rgb_pw_control.ino

## 4 thoughts on “Control WS2812b panel current consumption”

1. i adopt Array shook hands with WS2812B led strip www pt ledlightmake pt com / rgb-addressable-led-strip-c-80_87 / led-ws2812b-addressable-digital-stripsmd5050-strips-60-pcsm-p-216.html. always get the Pointer Overflow.
the Array is static const.Be similar as you define.
static const uint8_t ledTable = {
0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 3,
3, 3, 3, 3, 4, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8,
9, 9, 9, 10, 10, 10, 11, 11, 12, 12, 12, 13, 13, 14, 14, 15, 15, 15, 16,
16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 22, 22, 23, 23, 24, 25, 25, 26,
26, 27, 28, 28, 29, 30, 30, 31, 32, 33, 33, 34, 35, 36, 36, 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, 67, 68, 69, 70, 71, 72, 73, 75,
76, 77, 78, 80, 81, 82, 83, 85, 86, 87, 89, 90, 91, 93, 94, 95, 97, 98,
99, 101, 102, 104, 105, 107, 108, 110, 111, 113, 114, 116, 117, 119,
121, 122, 124, 125, 127, 129, 130, 132, 134, 135, 137, 139, 141, 142,
144, 146, 148, 150, 151, 153, 155, 157, 159, 161, 163, 165, 166, 168,
170, 172, 174, 176, 178, 180, 182, 184, 186, 189, 191, 193, 195, 197,
199, 201, 204, 206, 208, 210, 212, 215, 217, 219, 221, 224, 226, 228,
231, 233, 235, 238, 240, 243, 245, 248, 250, 253, 255 };
Do you know why that is?get a clues to me thanks!

This site uses Akismet to reduce spam. Learn how your comment data is processed.