Twistyplexing: a new topology for LED multiplexing
Twistyplexing is a new topology that I discovered that improves upon the charlieplexing method of LED multiplexing. It makes it easier to map LED coordinates to pairs of microcontroller pins using modular arithmetic. It also eases construction and debugging.
Various authors have written about charlieplexing as a way to drive a large number of LEDs using a small number of microcontroller pins. A typical presentation for a charlieplexed rectangular matrix starts with an ordinary row-column multiplexed matrix and replaces each LED on the major diagonal with a short circuit. To restore the matrix to a rectangular form, this approach shifts the upper triangle left by one column.
In the following description, each matrix uses a common cathode wire for each row, regardless of the rest of the matrix topology. An ordinary 5×5 row-column multiplexed LED matrix looks like this:
This is an ordinary row-column multiplex with five rows and five columns, with each LED on the major diagonal replaced with a short circuit:
Now that each row is connected to a corresponding column, a circuit needs only five microcontroller pins to drive this matrix, assuming line drivers with individually selectable high-impedance states (tri-state). The layout, however, is missing a diagonal line of LEDs. Here are the pin numbers for the anode of each LED, with “X” representing a location where a short circuit between a row wire and a column wire takes the place of an LED:
row 0: X 1 2 3 4 row 1: 0 X 2 3 4 row 2: 0 1 X 3 4 row 3: 0 1 2 X 4 row 4 : 0 1 2 3 X
Shifting the upper right triangle left by one column removes the diagonal gap in the layout, but leaves gaps in the wiring:
Each column wire now “jogs” sideways by one column as it passes the location of the missing major diagonal. The anode pin numbers are:
row 0: 1 2 3 4 row 1: 0 2 3 4 row 2: 0 1 3 4 row 3: 0 1 2 4 row 4: 0 1 2 3
There is a gap in the pin number sequence for the LEDs in each row. That makes it somewhat more difficult to use modular arithmetic to determine what pair of pins to use to light up a given LED. Most authors of charlieplex software resort to using lookup tables to map LED coordinates to pin numbers.
I had the idea that since there is a gap in the pin number sequence, why not twist or shift each row so that the gap falls “out of frame”? The result is that the sequence of each row’s anode pin assignments is a length N-1 subsequence of a cyclic permutation of the sequence of integers from 0 to N-1. The anode pin number assignments now look like:
row 0: 1 2 3 4 row 1: 2 3 4 0 row 2: 3 4 0 1 row 3: 4 0 1 2 row 4: 0 1 2 3
The circuit schematic looks like:
The common cathode wires are still rows, but the common anode wires are now diagonals. The anode pin number for an LED is now simply anode = (row + column + 1) % N. That’s two additions and one remainder operation. (The remainder operation obviously becomes an even cheaper bitmask operation if N is a power of 2.) There’s no need to spend precious microcontroller memory on tables of pin pairs.
Constructing a twistyplexed matrix is easier than constructing a charlieplexed matrix, because each common anode wire is a diagonal wire, instead of a vertical wire with a sideways jog in the middle. Debugging is easier, because all LEDs that share a common anode wire lie in a straight line (possibly wrapped around toroidally).
To be fair, there is a way to use modular arithmetic to map LED coordinates to pin numbers with the traditional charlieplexed matrix, but it requires more operations and is somewhat trickier to implement. A slightly different topology by McLaren in the comments to this Instructable still tries to maintain the ordinary row-column matrix structure, while inserting a single diagonal “floating row”, which would still lead to complications in pin mapping.
[…] something I’ve been working on that is an example of the twistyplexing […]
Did it work?
Hi Tom. Very interesting article and method. Thank you.
I don’t think the pin mapping for my “floating row” topology is any more complicated than the pin mapping for your “twistyplexing” topology, and may actually be less complicated. For example, when wiring up Charlieplexed 7-segment displays.
Also, I suspect ‘twistyplexing’ may actually have more computational overhead than the “floating row” method. Unless I’m mistaken, to turn any individual LED on or off, you’d need to calculate “row = led_number / 4”, “column = led_number % 4”, and then “anode_pin = (row + column + 1) % 5”. By comparison, the “floating row” method maps row and column directly to I/O pins and requires “row = led_number / 4”, “column = led_number % 4”, and a simple comparison to select the floating row pin; “if(column == row) row = 4” (where ‘4’ is the float pin).
If you or your readers are interested, there’s a simple Arduino example sketch and schematic here; http://forum.allaboutcircuits.com/threads/knight-rider-style-light-chaser.67803/#post-571226
Cheerful regards, Mike