Channels ▼

Al Williams

Dr. Dobb's Bloggers

Charlie's (LED) Angel

June 10, 2011

I don't know what embedded systems programming will be like in 100 years. But I am convinced of one thing: It will, as it does today, involve trying to get more of something out of less of something else.

Let me explain. The first system I got paid to design was a CPU board based around the 6805 that went into a leak detection system. Since the government was paying us to do the board, we wanted to make it general purpose enough to reuse it (which we did). The problem is that the EPROM and RAM chips available back then were positively minuscule. The 6805's address space was only good for about 8K anyway (although later versions of the part could sort of address more).

We wound up spending a lot of time trying to shave some code down by 9 or 10 bytes so it would fit in the 4K main EPROM. Oh, and to make things easier, you could only read from the EPROM. If you wrote, you actually addressed an LCD display. We figured if you timed it right, you never actually needed to read from the display. That wasn't the only multiplexing going on. One of the part's I/O bits selected between another 4K EPROM (the math library) and a UART. So you could talk over the modem, or do math, but not both at the same time.

Today, cramming things into memory isn't as common as it used to be since many parts have lots of memory onboard and most have no provision for external memory. So you pick a part that will hold what you want to do and that's usually sufficient. But the fact that there is little room for I/O expansion is what really drives most of my cramming these days. I'm always on the lookout for a way to get more inputs or outputs on fewer pins.

Of course, there are the bus answers. You can use I2C, Dallas/Maxim OneWire, or SPI to talk to "smart devices" on the bus. That's fine, if you have smart devices. But what about something simple like plain old-fashioned LEDs?

The common solution, of course, is to multiplex. The 7-segment displays in calculators and clocks are usually done this way. You drive all the digits together (7 outputs) and then have one output per digit that you make active to enable any particular digit. If you activate each digit often enough, your eye will see a slightly dimmer display but will still think all the digits are on at once. So for, say, 4 7-segment displays you need 7+4=11 output pins.

Can you do better? If you can turn output pins off (not to zero, but really off), the answer is yes. Most modern microcontrollers can set a pin high, low, or set the pin as an input. If the input state is effectively "off" you can use this capability to drive more LEDs (or other outputs). The technique is called "charlieplexing", ostensibly named after Charlie Allen at Maxim who appears to be the first to publish such a scheme.

Consider two LEDs back to back. You can even buy two-color LEDs like this. Say one LED is X and the other is Y. The anode of X and the cathode of Y connect to a port; call it A. Then the cathode of Y and the anode of X connect to port B.

This arrangement means that if you place pin A high and pin B low, one LED will light. If you reverse the pins (that is, put pin A low and pin B high) the other LED will light. Big deal, right? You could just use the two pins to light the two LEDs independently, so what's the benefit?

The benefit is when you add another pin and the ability to set any of the pins to one of three states: high, low, or input. Consider this schematic:

And this truth table (where H=high, L=Low, and I=Input, and * indicates a lit LED)

So with only 3 pins, you can control 6 LEDs. In theory, N pins can control up to N(N-1) outputs. Of course, if you want more than one on at a time, you'll need to refresh them.

You can use the same scheme to multiplex input signals. You can place a switch (or something that looks like a switch) in series with each LED. You can read more about charlieplexing on the Maxim website.

What's your favorite trick to save memory or I/O pins? Drop me a note and let me know.

Related Reading


More Insights






Currently we allow the following HTML tags in comments:

Single tags

These tags can be used alone and don't need an ending tag.

<br> Defines a single line break

<hr> Defines a horizontal line

Matching tags

These require an ending tag - e.g. <i>italic text</i>

<a> Defines an anchor

<b> Defines bold text

<big> Defines big text

<blockquote> Defines a long quotation

<caption> Defines a table caption

<cite> Defines a citation

<code> Defines computer code text

<em> Defines emphasized text

<fieldset> Defines a border around elements in a form

<h1> This is heading 1

<h2> This is heading 2

<h3> This is heading 3

<h4> This is heading 4

<h5> This is heading 5

<h6> This is heading 6

<i> Defines italic text

<p> Defines a paragraph

<pre> Defines preformatted text

<q> Defines a short quotation

<samp> Defines sample computer code text

<small> Defines small text

<span> Defines a section in a document

<s> Defines strikethrough text

<strike> Defines strikethrough text

<strong> Defines strong text

<sub> Defines subscripted text

<sup> Defines superscripted text

<u> Defines underlined text

Dr. Dobb's encourages readers to engage in spirited, healthy debate, including taking us to task. However, Dr. Dobb's moderates all comments posted to our site, and reserves the right to modify or remove any content that it determines to be derogatory, offensive, inflammatory, vulgar, irrelevant/off-topic, racist or obvious marketing or spam. Dr. Dobb's further reserves the right to disable the profile of any commenter participating in said activities.

 
Disqus Tips To upload an avatar photo, first complete your Disqus profile. | View the list of supported HTML tags you can use to style comments. | Please read our commenting policy.
 


Video