Twistyplexing: a new topology for LED multiplexing

by argonblue

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:

5x5 row-column matrix

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:

5x5 row-column matrix with major diagonal points shorted

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:

typical 4x5 charlieplexed matrix

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:

4x5 twistyplexed matrix

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.