# What's the maximum number of outputs you can control from a microcontroller with n outputs?

Been pondering this for a while, and I think it's $2^{(n-1)}$ outputs.

If I have 5 outputs, I'll use 1 as the signal, and the other 4 as control lines to cascaded decoders, which gets me 16 outputs. This grows exponentially, so it's fine with microcontrollers with more than say 4 outputs.

But what about microcontrollers with limited outputs (eg. 4). Are you limited to only 8 outputs here?

Edit:

The project is to drive a variable brightness (PWM controlled) LED array of 32 x 4 from a single microcontroller with a limited number of outputs (4). I am wondering whether the complexity involved in this is not worth the effort, and whether to instead use a microcontroller with more outputs.

-
If I'm understanding this correctly and you only need one output on at a time you could also use a 4-to-16 line decoder for 16 outputs, or leave one disconnected for 15 outputs if you need the possibility of them all being off. – PeterJ Jul 8 '14 at 13:30
Yes, only one output is required at a time - edited my question – tgun926 Jul 8 '14 at 13:34

It depends on what you mean by "control". Are you confining yourself to simple combinatorial logic, or are serial protocols allowed?

In theory, you could control an arbitrary number of outputs from a single pin by using something like the Dallas/Maxim 1-wire (serial) protocol to drive a set of I/O expander chips. Similar approaches can be used with I2C, SPI, or simple shift registers, each of which would require a minimum of 2 pins.

-
I have edited my question. I limited my question to combinatorial logic because I wanted to drive a large array of LEDs, and thought speed would be an important factor. – tgun926 Jul 8 '14 at 13:39
@tgun926, if you're controlling LEDs, persistence of vision is much slower than digital ports can go, so speed isn't generally important (unless you're PWMing the brightness!) – Scott Seidman Jul 8 '14 at 13:43
In that case, the key concept you're looking for is Charlieplexing. With no external logic, you can control N*(N-1) LEDs from N pins. With a straight binary decoder, you can control 2^N - 1 LEDs. – Dave Tweed Jul 8 '14 at 13:47
Depends how you PWM it, if you need PWM control of each individual LED it's a lot harder, but PWMing by row/column or just overall could be done more easily. – John U Jul 8 '14 at 14:41
There are RGB LEDs with PWM circuits built in, such as these:sparkfun.com/products/12877. Why do it the hard way? – Jeanne Pindar Jul 8 '14 at 17:34

If you can easily use a microcontroller with more outputs - and it should be fairly easy, unless you've already got a lot of other outputs committed to another purpose - then do so.

If you can't, then you can usually economise by using shift registers: http://wiringpi.com/extensions/shift-register-74x595/

You could have five 8-bit shift registers, four across the 32 bit width and one for the 4 bit height. Use your four pins as data, clock, latch, and chip select.

-

That depends on how fast you need to control them. If you need high speed then your equation holds. If you can stand a bit of delay then you can use either I2C expanders (2 GPIOs) or '595s (3 outputs), hubbed or cascaded as required.

-

You could use one bit plus a shift bit to control an arbitrary number using daisychained serial shift registers, and your output could be ANY number, not just a 1-of-16 pattern or something like that.

-

If you just want to control LED's you can also use CharliePlexing. Using this method, n outputs can drive (n^2 - n) segments or LEDs.

http://en.wikipedia.org/wiki/Charlieplexing

-

As noted, by using shift registers, it's possible to control any number of outputs using a small number of CPU pins. With regard to your specific requirements, you don't specify the number of brightness levels you require, but you could probably achieve a reasonable number of brightness levels if you have the shift registers' "register latch" pin tied to an output-enable. Assume you want 128 brightness levels at a 60Hz or better refresh rate, and it takes 100us to clock out the bits to select and load a row.

Clock out bit 0 of the brightness for each light in row 0, then pulse the latch/output enable for 20us. Then clock out bit 1 the brightness for each light in row 0 and pulse the latch/output enable for 40us. Then bit 2 and pulse for 80us. For bits 3-6, the pulse lengths will keep doubling but you'll be able to clock in the next bit of data during the "on" part of the cycle (since you'll want the enable to be active for longer than it takes to shift through the bits). The first three bits will take about 100+20+100+40+100+80 microseconds (440us in total). The next four bits will take about 160+320+640+1280 (2400us), for a total of about 2840us. Doing that for all four rows will take under 12ms, so an 60Hz refresh rate should be no problem.

One slight limitation with this approach is that you should make sure that you don't try to change the brightness of the lights on a row while that row is being processed. Otherwise, if e.g. a light's brightness changes from 63 to 64 between the times bits 5 and 6 are output, the light may be turned on during the first 6 bit times (since bits 0-5 are all set, even though bit 6 is clear), and then on for the last bit time (since bit 6 will be set, even though bits 0-5 are clear), thus causing it to appear briefly at full brightness. If you latch the brightness for the lights in a row before scanning that row, however, such difficulties should be avoided.

-