# multiplex numerous strips of WS2812

From what I understand, a strip of WS2812 LEDs use PWM to adjust the brightness (and thus current draw) for a given LED. If I attach several strips in parallel, each with its own data pin from my uC, would it be possible to multiplex the strips so that each strip is only every on at a given moment? I'm hoping that by doing this, the current draw of the entire setup will be reduced.

You must understand that multiplexing and PWM both have the same effect, from the point of view of a single led. They both reduce the % of time that the current flows. Therefore the average current falls and the led is less bright. There is no magic that can keep an led as bright while the average current is less.

and

Do you mean having separate strips and show the pattern on only one strip at a time, but change what strip is showing quickly so as though it appears that all the strips are on? There are two things wrong with this:

1) The PWM rate in the strips are slow so you can not turn them on an off that quickly. So you will see flicker on the strips.

2) The strips still end up being dimmer and use exactly the same amount of current on average as if you just reduced the brightness.

Could someone please explain this in more detail?

As a thought experiment, if I had multiple strips of just a single LED, if a LED is only actually ever on a fraction of the time (PWM), and if you time things right so that each strip's "on time" is offset just a bit so that no two strips turn on at the same time, then current should be reduced. What am I missing?

Edit

Perhaps one of my assumptions is incorrect. When a LED is being PWM-ed, I'm guessing that the current draw over time looks identical to the PWM wave. Therefore, I'm wondering why you couldn't have the current draw for the other strips be timed to go on when the others are low.

• Are you trying to create some kind of interleaved scheme where you reduce current consumption, but the observer's eye perceives "solid [non-blinking]" light? Mar 10 '17 at 17:02
• The supply current must be the sum of all loads at 100% brightness. Mar 10 '17 at 17:16
• @NickAlexeev - yes that's right Mar 10 '17 at 17:48
• Why is it not acceptable to just set a lower brightness to all strips? Mar 10 '17 at 19:46
• I suppose it is, I'm just trying to understand this conceptually, perhaps within the constraints of keeping brightness the same. Mar 10 '17 at 20:03

You're missing the fact that WS2812 do their own PWM'ing. Once you have loaded data into the strips, each individual WS2812 LED driver drives its LED with PWM, asynchronously to the other LEDs in that strip, and to the other strips.

You could perhaps write 'on' data to one strip, then write 'off' data, and write 'on' to the next strip. But that seems like a hard way to get a flashing version of simply programming the LEDs to a lower brightness, which will also reduce the current draw of the entire setup.

PWM has nothing to do with this. Just set it aside for now. How the LEDs get dimmed does not matter. The brightness of each LED is programed 30 times a second where the method of dimming the LED is not relevant to the programming.

For this discussion let's say we have a set of 3 strips of 10 LEDs and 1 strip of 30.

What you are proposing is to program the 3 individual strips of 10 with three pins rather than one strip of 30 with one pin.

You can do exactly the same thing with the 30 LED strip connected to one pin as you can with 3 strips connected to three pins.

The LEDs are programmed one frame at a time.

You can program the one 30 LED strip 30 times a second.

And you can program the 3 strips of 10 in parallel 30 times a second

Which ever way you slice it you cab only program strips 30 times a send no matter the number of LEDs per strip OR the number of strips.

So either you will have one frame of 30 LEDs or you will have 3 frames of 10 LEDs. Still 30 frames per second.

So if you were to store your LED values for the 1 strip of 30 in an array you would have:

strip = {v0,v1,v2,v3,v4,v5,v6,v7,v8,v9,v10,v11,v12,v13,v14,v15,v16,v17,v18,v19,v20,v21,v22,v23,v24,v25,v26,v27,v28,v29};


If you were to store your LED values for the 3 strips of 10 in a 3 dimensional array you would have:

strip[0] = {v10,v11,v12,v13,v14,v15,v16,v17,v18,v19};
strip[1] = {v20,v21,v22,v23,v24,v25,v26,v27,v28,v29};
strip[2] = {v30,v31,v32,v33,v34,v35,v36,v37,v38,v39};


The above arrays can be accessed the same as the one dimensional array below.
{v10-v19, v20-v29, v30-v39}

strip = {v10,v11,v12,v13,v14,v15,v16,v17,v18,v19, v20,v21,v22,v23,v24,v25,v26,v27,v28,v29, v30,v31,v32,v33,v34,v35,v36,v37,v38,v39};


Let's add another dimension for the multiplexing.

strip[0,0] = {0,0,0,0,0,0,0,0,0,0};
strip[0,1] = {0,0,0,0,0,0,0,0,0,0};
strip[0,2] = {0,0,0,0,0,0,0,0,0,0};

strip[1,0] = {v10,v11,v12,v13,v14,v15,v16,v17,v18,v19};
strip[1,1] = {v20,v21,v22,v23,v24,v25,v26,v27,v28,v29};
strip[1,2] = {v30,v31,v32,v33,v34,v35,v36,v37,v38,v39};

mux[0] = {0,1,1};
mux[1] = {1,0,1};
mux[2] = {1,1,0};

while(true){
for(multiplex=0;multiplex<3;multiplex++){
for(frame=0;frame<3;frame++){
xmit(strip[mux[multiplex],frame]);
}
}
}


The above code is repeating the 3 frames below where the first 10 LEDs are off in frame 1, V20 thru v29 are off frame 2, and v30 thru v30 are off frame 3

{0,0,0,0,0,0,0,0,0,0,v20,v21,v22,v23,v24,v25,v26,v27,v28,v29,v30,v31,v32,v33,v34,v35,v36,v37,v38,v39}
{v10,v11,v12,v13,v14,v15,v16,v17,v18,v19,0,0,0,0,0,0,0,0,0,0,v30,v31,v32,v33,v34,v35,v36,v37,v38,v39}
{v10,v11,v12,v13,v14,v15,v16,v17,v18,v19,v20,v21,v22,v23,v24,v25,v26,v27,v28,v29,0,0,0,0,0,0,0,0,0,0}