Actual microcontrollers have powerful bidirectional I/O ports, and you can use different techniques to fully exploit such capabilities. Recent Design Ideas described the “Charlieplexing” method as an effective way to drive M=N×(N–1) LEDs using only N bidirectional I/O ports and N resistors (reference 1 and reference 2). Unfortunately, using Charlieplexing allows you to drive only one LED at a time, so, when using a large number of LEDs, only a tiny slice of time is available to multiplex each LED: TDRIVE=T/M, where T is the PWM excitation period. As a consequence, to obtain a given average current and bright LEDs, you must excite them with a current M times higher, and you can’t usually obtain such peak currents from the microcontroller port.
This Design Idea describes “Chipiplexing,” a method in which you need to add only N cheap, bipolar transistors. This circuit uses PNP types, but you can also use NPN devices. (The term Chipiplexing comes from my nickname, Chipi.) The benefits pay the additional cost because you can simultaneously drive N–1 LEDs, thereby reducing peak currents N–1 time.
shows how there are now nine possible combinations of the three microcontroller ports: the six available when using Charlieplexing to drive one LED at a time and three new combinations to drive two LEDs at a time. The microcontroller port grounds the transistor’s base. This action fixes a junction-drop voltage at the emitter and collects and sinks all the LED currents to ground without overconstraining the microcontroller port, which has to sink only the transistor’s base current plus 0.7V per resistor. Each of the other ports set to the battery voltage needs to source only one LED current.
For more detail: Chipiplexing efficiently drives multiple LEDs using few micro controller ports