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.