Charlieplexing 7 Segment Displays

64K5418

Intro: Charlieplexing 7 Segment Displays

This instructable describes how to charlieplex a bunch of 7-segment led displays.

Charlieplexing of discrete leds has been the topic of a few other instructables. The Charlieplexing LEDs- The theory and the How to drive a lot of LEDs from a few microcontroller pins comes to mind. They are both excellent and should be read by anyone that wants to gain a deeper knowledge of how charlieplexing really works.

Charlieplexing 7-segment displays is more or less the same as doing it with discrete leds, but with some changes to handle the fact that all the led segments have a common pin instead of being separate, and the need for buffering of the common output so the poor microcontroller can cope with the load.

STEP 1: Why

While building a quick n' dirty pulse generator that I needed to test coils for a HV power supply I decided that it'd look more funky if I used a 6-digit seven segment display instead of the ubiquitous and boring LCD display.

Due to a shortage of available i/o-pins on the Atmel Tiny26 that I've used for the pulse generator project I couldn't use the standard multiplexed way of doing this. The standard multiplex would require 14 i/o-pins - 8 for the segments (don't forget the dot) plus 6 for the common anode/cathode of each display.

By Charlieplexing the displays I only need 9 i/o-pins and the displays are still muxed in a 1:6 way acheving the same brightness as standard muxing. Charlieplexing usually only light up one led at a time thus giving a reduced brightness if you want several leds to be (visibly) lit at the same time.

Of course I could have used a BCD-to-7segment decoder chip (74LS48) plus a 1-to-8 decoder (74LS138) but that would have been cheating, and i didn't have any '48ths as hand and I really wanted to be able to fit the pulse generator in an Altoids-like box.

STEP 2: Disclaimer for Bad Design Practices

Normally you must connect leds via a current limiting resistor in order to keep them alive for more than a few milliseconds.

Here I'm not using any resistors since the display is connected to the output pins of a microcontroller that normally can't sink or source more than a few times the current the leds/displays can handle continuously. Since we're multiplexing the displays they will only be on for 1/6'th of the time and can handle much more current than if they were on all the time.

In the following schematics and in my construction I've left out the current limiting resistors, both for the leds themselves and also the base resistor for the transistors.

Please note the following
It is a really bad construction practice to skip the current limiting and rely on luck and that duty cycle combined with the relatively low sink capability of the processor and the probable underrating of the leds maximum specs.

In anything that you do professionally, or just want to keep running for an extended period of time (longer than your first test run) one should adhere to good construction practices, read the datasheets and to the maths.

And read rgbphils comment about running leds over the rated current in the comments section of this instrucatble.

STEP 3: Normal Multiplexed Displays

The displays I'm using here is of the Common Anode -type. That means that all the segments have a common positive pin. In order to light one segment you connect the common pin to plus and one or more of the segment pin(s) to minus.

A normal multiplexed display have all A-segments connected together in one line, and then all B-segments and so on. The common pins are then connected individually to the microprocessor. This makes eight lines for the segments and one line for the anode on each individual display.

STEP 4: Charlieplexed Displays

As shown in the previous step we needed 14 (or 16 if we had 8 displays) connections to the microcontroller to control 6 displays.

If we instead use the Charlieplexing technique we can reduce the connection count to just 9, this regardless if we have 2, 3, 4, 5, 6 ,7 or even 8 displays.

The drawback of using Charlieplexing is that the connections to the displays is a bit more complex and the software that will scan each display one by one will also become somewhat more complex. But hey! If you can save 7 output pins on the microcontroller I think a couple of more lines of code is a cheap price. As you can see in the software step in this instructable the scanning software isn't really that complex and can easily be implemented in your language of choice.

The hardware is actually the same as in the standard multiplex example only some of the connections are changed.

The major change is that an additional line for the segments is added. On the first display the new line is connected to the A-segment, on the second display the B segment and so on. All other segments are connected as usual. All A's together, All B's together (with the exception of previously mentioned specials)...

The transistor for the first display is then connected to the the line where the A-segment should have been. The transistor for the second display is connected to the line where the B-segment should have been and so on.

To address on of the displays now the processor have to first output a high value on the line that its transistor is connected to, then output a low value on the lines that are connected to the segments that should be lit and disconnect (high impedance) the lines for the segments that should be off.

The last part is the most important here, because if the processor would output a high level for the segments that should be off the transistors connected to those segments would also be activated and cause some other displays to be activated at the same time. And that is not a good thing. Multiplexing always relies on that only one display at a time is activated. One by one in a rapid fashion so the brain/eyes gets fooled and thinks that they are all on at the same time.

Since each display is connected in a slightly different way than the others the scanning software must handle this by special code for each display.

STEP 5: The Software

Here's the code written in C for the Atmel Tiny26-processor. It should be really easy to adapt to any other Atmel processor. I don't think that there would be any major obstacles to convert to some Basic dialect for the Microchip PIC processors either. I leave that as an exercise for the readers :-)

You might notice that I've allocated the i/o-ports for the display a bit strange, the reason for that is that the ports not used here is used for other purposes in the project that I'm using this display for. If you want to rearrange the ports it's really easy, just change the #defines remembering to update the A/B-suffix on the names so you won't miss to move them between the groups later on in the code.
It might sound a bit strange and hard to understand what I've just said, but look at the code and ask me if you need any help. I'd be glad to help.

18 Comments

Would you mind posting the actual code as a document or file, making sense of this one massive strand is more work than it's worth...
Once upon a time the code was nicely formatted in this instructable, but it seems that they've made changed in their system so code looks like crap nowdays.

I've noew added a zipfile with an AVR Studio 4 project with recovered code....
matseng, this is a cool manual and very useful for multi-display projects. I'll need to use one myself soon, so thank you for the schematics you posted. Even if you're generally familiar with how this works, it's almost impossible to put this together properly without constantly looking at the schematics. I'll be sure to have yours printed and pinned to the board while I'm doing it.

There is only one critical comment I have thought: this is not Charlieplexing! I don't mind calling this approach Matsengplexing for future references, but actual Charlieplexing requires you to switch polarities of the LEDs around thus achieving an enormous amount of LEDs connected to limited amount of I/Os, such as 4 I/O to 12 LEDs. Switching polarities is not possible in LED matrices like  these 7-segs where all 8 LEDs share a common cathode (or was it anode?) .  Using actual Charlieplexing you would be able to light 72 LEDs from 9 I/Os, meaning more than 10 digits and two digital points. But of course, noone makes 7 segment indicators with all LEDs separately pinned on the back, so it's purely theoretical. Matsengplexing is the only approach possible.

Great job!
Yo dude, I have a TI MSP430 with 8 I/O pins n I'm trying to control (4) 7-segment displays. I only need the 7 segments (no dot) and it seems according to this way of charlieplexing that it might be possible after all. Could you help me understand how exactly the charlieplexing works in simpler terms. It seems to me that if you power one of the segments with another segment's transistor on the same wire, you'd get some unwanted results, unless i'm totally confused.
Hi DuFFxP93,

I was quite confused at first, but I think I've got it. The real trick is to realize that the uCPU lines are actually tri-state: high, low, and high-impedance (disconnect). This design takes advantage of all 3 states. Using this matseng has used HIGH to select a display and LOW to select a segment:

1. The "sink" on each display is connected to a DIFFERENT line (look very closely at the diagram). You drive this line HIGH to select the display.

2. Now, the actual segments are wired almost like normal, except that one of them will no be connected to the new data line (the one that would have been connected to the line you just drove high). You need to drive the segments you want on LOW.

3. Unlike a standard design, you MUST set the segments you don't want enabled to high-impedance (singe high would select a 2nd display, and low would select another segment).

PS: matseng - very clever, and useful!
where did you get or buy that breadboard its really cool give me a link if you can
It's not organized and hard to understand may be u could organize it more to be easily read with adding empty lines between each instruction :-) I use PIC and it's hard for me to recognize ur code :)
Code is jumbled. Oh and Microchip PIC s do infact support C.
As soon as I saw the wall of code I felt like I could cry.
FYI on the current limiting; I just completed my first Charlieplex of 6 7-seg displays. I thought I would need current limiting, but after testing and measurments they were not needed so I took those Rs out. The LEDs as multiplexed are abit dim with only a few mA on each segment. It seems the code ensures power limits are in place! My project to be posted soon.
Genius! Did you get this idea from somewhere, or think it up yourself?
Awesome 'ible! Have you thought of using a demultiplexor for LED alphanumeric display selection?
Very clear Instructable - Thanks. Suppose I have a mutli-digit LED display where the inputs are already arranged in a segment/grid pattern. Is it possible to "piggyback" charlieplexing on top of it? I'm looking at it but don't quite see how. Thanks,
Good idea, hadn't thought of that... maybe i can use that 7 segment after all... thanks drew
hi, nice instructable. Makes a lot of sense to charlieplex a seven segment display rather than use a special chip. The only comment I would make is that it is a bit of a myth to only look at the average current going into an LED and neglect to use limiting resistors. I'll explain in a second. Firstly, in this case, the natural output current limitations of the microcontroller and the small size of the LEDs in the displays will limit the current, so the following is more of an issue for high power LEDs. You might want to check the effect of high current pulses on the micro and PCB tracks and any effect it has on the rest of your circuitry though. An LED will fail because the plastic surrounding the LED die gets heated/cooled repeatedly, slightly softening (depending on current, perhaps melting) then hardening which expands and contracts making mechanical pressures on the LED die/wire bond. In time this wiggles the wire bond off making an open circuit. If you have a high current pulse of short duration, but low average consumption the LED will not be measurably warm because of the much larger thermal mass surrounding the LED. However the die/wire bond will quickly heat up/cool down because of the small area at the bond has a tiny thermal mass. I think I read somewhere you need a pulsewidth of sub millisecond to alleviate this (ie >1kHz refresh rate). So, particularly for high power LEDs, always keep the current under the datasheet maximum....even if the average current is less, even if you don't feel the LED getting warm. It is the pulse current width that matters, not the average current. Odds are this circuit will keep running for years because the LEDs are low power......but you never know.
Hi Phil, interesting writeup about the reason for pulsed leds to fail due to overcurrent. I haven't reflected on it earlier, but it makes a lot of sense. It is a really bad construction practice to skip the current limiting and rely on luck and that duty cycle combined with the relatively low sink capability of the processor and the probable underrating of the leds maximum specs. In anything that you do professionally, or just want to keep running for an extended period of time (longer than your first test run) one should adhere to good construction practices, read the datasheets and to the maths. I'll amend the "disclaimer" section of the instructable a bit....