Sunday, 14 October 2012

Multiplexing and Charlieplexing of LEDs in Arduino



Multiplexing

Multiplexing is a very common way of driving LEDs, particularly when they are assembled as either a dot matrix display or a number of seven-segment/numeric displays. Multiplexing relies on the fact that if a light source is switched on and off fast enough, the human eye perceives it as being continuously lit even though it is in fact only on for a brief period.


Figure 16-2 shows a two-digit seven-segment display connected to an Arduino. Note that the seven segments are connected directly to the Arduino output pins and the “common cathode” of the display (all the LED cathodes) are connected through a transistor to ground. These bases of the transistors are, in turn, connected to an output pin on the Arduino.


In order to display two different numbers on each display, we use a procedure much like the following:
repeat {
Set Outputs 3 to 9 as required for first digit;
Turn Output 1 On;
Delay;
Turn Output 1 Off;
Set Outputs 3 to 9 as required for second digit;
Turn Output 2 On;
Delay;
Turn Output 2 Off;
}
If we repeat this rapidly enough, our eye will perceive both displays as being continually lit showing the digits we want. The general idea can, of course, be expanded to more digits—four or six for a clock, for example, and this is precisely how most LED clocks work.
Multiplexing doesn’t come entirely free. Because the LEDs aren’t on all the time, they appear dimmer. In our example, the duty cycle (ratio of “on” time to “off” time) for each display is 50%. For a four-digit display, it would be 25%, and so on.
To get around this, we can increase the current being sent to each display, this being where the peak current rating of the display becomes important. For a typical seven-segment display, it’s likely to be acceptable to increase the current to 50mA per segment. Higher than that, start checking datasheets and doing some calculations to ensure you don’t overstress the devices. By driving the LEDs with a higher peak current, they output more LED for the time they are on so they appear brighter. They also have time to cool during the off time, hence avoiding damage.
There is a caveat with driving LEDs at their peak, rather than constant, current rating: it’s very important that your software doesn’t inadvertently leave them on too long, or the device can be damaged. This can be problematic during development/debugging if your code crashes with the LEDs in an on state. It is prudent to do initial coding with the LED or display run with resistors chosen to keep it at its constant current rating.
The next issue with multiplexing is that, of course, the ATMega must update the state of the LED or display at regular intervals. This reduces the amount of processor time available for other tasks. With careful design, the impact of this can be minimized, but should be taken into account. Consider using a periodic interrupt to do the display updates.

Charlieplexing

Charlieplexing is a technique that can be used to maximize the number of LEDs or switches that a microcontroller can address with a limited number of pins. It makes use of the fact that a modern microcontroller (ATMega/Arduino obviously included) can actually set its pins to one of three states: High, Low, or Input (“Hi-Z” as it is sometimes called). We’ll confine our remarks here to driving LEDs. The Practical Arduino web site has links for references on this topic, if you wish to read up on more exotic setups, as well as links to the original articles on the topic.
Figure 16-3 shows two LEDs connected between a pair of Arduino output pins through a dropping resistor. Note that the LEDs are connected with opposite polarity. Two pins to drive two LEDs is hardly remarkable, but bear with us a moment and we’ll illustrate the basic principle. 






To turn LED1 on, we would make Output1 High, and Output2 Low. For LED2 we’d do the opposite: Output1 Low and Output2 High. To turn the LEDs off, we can either set the pins to be inputs or the outputs to be the same state (both Low or both High)
Figure 16-4 shows a more interesting arrangement. Here we drive six LEDs from just three pins by making use of the Arduino’s ability to set a pin to be an input or an output in a high or low state.
Referring to the diagram, to turn LED1 on, we’d set DIO1 to be an output and to be high, DIO2 to be an output and low, and DIO3 to be an input. LED2 would be turned on by DIO1 being an output and set low, DIO2 being an output and set high, DIO3 still being an input. Jumping around, LED4 you’d set DIO1 to be an input, DIO2 to be low, and DIO3 to be high. LED6 would call for DIO1 to be low, DIO2 to be an input, and DIO3 to be high, and so on. A bit of thought and careful programming will allow you to create a general-case piece of code that can turn on any LED required.


You’d be correct to wonder why when LED6 is on, LED1 and LED3 aren’t. They’re connected between the same pins, after all, and with the correct polarity. The answer here is the forward voltage drop—there isn’t a high enough voltage across the two LEDs when connected in series to allow them to light because it’s below the threshold or Vf level.
If, as is often the case, you want to have more than one LED on at a time, you can use a multiplexing arrangement, switching to each LED in turn in rapid succession. Avoid the temptation to simply skip an LED that is off. If you do so, then the brightness of any LED that is on will change depending on how many LEDs are on at any one time. Of course, if the number of LEDs that are on is constant—as would be the case for hands on a clock, say—that would be acceptable. LEDs that are off can be skipped completely in such a case. As noted in the previously, you’ll need to consider running the LEDs at higher currents to keep the brightness up, and the same caveats about duty cycle come into play.
Finally, note that the current-limiting resistors are half the value you’d normally expect to use. This because the LED being driven is always being powered by the Arduino through two pins and, hence, two dropping resistors.
If you’re curious, the general case for the number of LEDs that you can drive from n pins is n2 – n. For example, eight DIOs yield 56 LEDs; 12 DIOs yield 132 LEDs; and so on. That’s a lotta LEDs!

0 comments:

Post a Comment