Tri-state Multiplexing

After several false starts attemping to drive a 10 segment bargraph with 50mA as brightly as at 100mA by using the supplied voltage more efficiently and running the LEDs in series when possible, this is what I've come up with. I've built a test circuit with four LEDs, tested each possible configuration of lit LEDs, and it seems to behave as expected.

Here is the circuit:

The way it works is by using the tri-state logic of the microcontroller. Pins can be set to high, low, or input, and in the input state they are effectively disconnected from the circuit. In the above circuit, using this tri-state logic, you can light a single led, or a pair of leds in series. And by multiplexing the display on a 50% duty cycle, you can make all four appear lit at once.

The advantage to doing this comes from the fact that when running the leds in series, the voltage is used more efficiently, so the same 20mA will light two leds instead of one, at the same brightness.

So let's say we have a 10 segment display, and want to put 10mA through each led, for a total of 100mA... but we have only 50mA to work with. No problem. Using the above circuit, we can divide the bargraph into five pairs of leds, and feed each pair of leds with 10mA.

But wait! We can only light half the leds at a time. The display has to be multiplexed on a 50% duty cycle. And that means each pair of leds will, on average, recieve only 5mA, and thus appear half as bright as an individual led fed 10mA.

Not a problem. We select resistors which would feed an led 20mA normally, and now our average for each pair of leds is back up to 10mA... and the average for our entire bargraph is 50mA, just like we wanted.

Here's how the resistor values are selected:

Let's say you have a 5v arduino, and your LEDs are 2.1 forward volt. If you wanted to put 10mA through a single LED, you would need a 330 ohm resistor. If on the other hand, you wanted to put 10mA through two LEDs in series, you would need a 82 ohm resistor.

We can see in the circuit above that when we light two leds in series, the current will pass through R1 and R3. These need to add up to 82 ohms. 82/2 = 41, for which 47 is our closest standard resistor value (or what I had at hand anyway), so that is the value of the smaller resistor. But when we want to light a single LED, we need 330 ohms of resistance. We've already got 47 ohms of resistance in the circuit though. So we subtract 47 from 330, and since a 283 ohm resistor is a little hard to come by, we choose a 270 ohm resistor instead.

(Note: I have not taken multiplexing into account here. I should have calculated "10mA on average through an led on a 50% duty cycle". So using the above resistors, the leds would be lit as if with 5mA each or 50mA total, but using only 25mA, because what I really should have done is put 20mA through the leds on a 50% duty cycle to make them appear as bright as a 10mA led.)

Now that we've got our resistors selected, it's time to light the LEDs.

Here's where the multiplexing comes in. The way the circuit is wired, you can only light one pair of LEDs at a time. So to make all four LEDs appear lit, you must multiplex the display on a 50% duty cycle, lighting half of them at a time.

In the following list, on the left we have the pin states, where "-" represents the input state. On the right we have the states said pin states will put the leds into.

1-0 = 1100
0-1 = 0011
10- = 1000
-10 = 0100
-01 = 0010
01- = 0001

I think that about covers it. It's a little hard to understand, but easy to implement. Basically, decide how many mA you need to light a single LED at the brightness you want. Double that. Calculate the resistors you need for a single led at that current, and two leds in series at that current. Divide the smaller one in half, then subtract if from the larger one. Use those two new values in the above circuit for your resistors. Then multiplex the display, using the pin states in the list above, lighting half the leds at a time.

Oh, and the number of pins you'll need is ceil(LEDS/4) * 3, so for 8 leds you need 6 pins, and for 10 leds as in my bargraph example, you'll need 9. Also, you're unlikely to be able to use this method to drive blue LEDs because their forward voltage will be too high.

Nice, but I think you should read up on charlieplexing :wink:

Charlieplexing is a way to reduce the number of pins you need to drive an array of leds. What I'm doing is a way to reduce the amount of current needed to drive an array of leds. Charliplexing does not reduce the current needed, as you can only ever drive one led at a time. With my method, leds are wired in series, so power is used more efficiently.

Charlieplexing is similar to what I'm doing, and was my inspiration for this, but it's not the same thing.

Charlieplexing is similar to what I'm doing, and was my inspiration for this, but it's not the same thing.

I realise there is a difference. But since your method was so similar to charlieplexing and no mention of it, i thought you weren't aware of it. Thats all.

But if you're lighting the LED's w/ a 50% duty cycle, they're on only half the time, so aren't you getting just half the brightness?
Or does the nonlinearity of the eye make it appear brighter than 50%?

lincomatic:
But if you're lighting the LED's w/ a 50% duty cycle, they're on only half the time, so aren't you getting just half the brightness?

No.

Let's say you have an array of 8 LEDs, lit the traditional way. You put 10mA through each LED, and use a total of 80mA.
Now let's say you wired that same array with each pair of LEDs in series. You'd still put 10mA through each LED, but now you're using only 40mA.

So far so good.

Now let's put 20mA through each pair of LEDs in the array wired in series. You're now using a total of 80mA, just like the traditional array, but each LED sees 20mA, so they're twice as bright.

Makes sense right?

But we can't animate the array wired in series. Not if it's wired the traditional way. So we wire it using the method I outlined above. And as a consequence of that, we have to multiplex it on a 50% duty cycle, with each pair of LEDs lit half the time. That halves our brightness. But it also halves our current usage.

So you're now using a total of 40mA, and each LED sees an average of 10mA. Half the current as the traditional array. But the same brightness.
Or, to put it another way... twice the brightness of a traditional array using that same 40mA, with each LED seeing only 5mA.

Or does the nonlinearity of the eye make it appear brighter than 50%?

No, that's not what's at play here.

Aren't you assuming that there is no drop across each LED ?

defsdoor:
Aren't you assuming that there is no drop across each LED ?

The drop across each LED is why there's two different values of resistor used.

Imagine the above circuit without LEDs 3 & 4.

There are then three possible paths (when the input state is used to disconnect certain pins) for current to take:

  1. Pin1 to Pin2 through LED1, where there is a total of 317 ohms of resistance.
  2. Pin 2 to Pin3 through LED2, where there is a total of 317 ohms of resistance.
  3. Pin 1 to pin 3 through LEDs 1 & 2, where there is a total of 94 ohms of resistance.

Now go to the LED array wizard:
http://led.linear1.org/led.wiz

Enter 5v source, 2.1fv, 10mA, and 1 LED. It tells you you need a 330 ohm resistor.
Now enter the same, but for 2 LEDs. It tells you you need an 82 ohm resistor.

Both these cases will light the LEDs with 10mA. Both cases will be just as bright. But in the case of 2 leds, more power is used to generate light, and less power is wasted in the form of heat, in the resistor.

To get the values in the above circuit, I did 82/2 = 41 and chose the closest value resistor I had on hand, 47 ohms.
I then subtracted 47 ohms from 330 ohms, and got 283 ohms. The closest value to that being 270.