# Hacking the CharlieCube

5,635

34

15

Posted

## Introduction: Hacking the CharlieCube

This instructable, is about the charliecube, and its about hacking, and how I used a spreadsheet to hack an LED cube.

To start I guess I need to explain what a charliecube is. A charliecube is a 4x4x4 3D RGB LED cube, or 64 RGB LEDs arranged in a 3D cube. Its a particularly interesting way to make an LED cube because it uses very few parts, mostly just the LEDs and microcontroller, it needs no LED drivers, and it even lacks current limiting resistors (LEDs often require resistors to prevent overcurrent damage.)

The charliecube was created by Asher Glick and Kevin Baker, and it is a radically different approach to LED cube design. It does have some inherent flaws, like the lack of current limiting resistors, which may or may not be slowly damaging the LEDs and or microcontroller. This also causes some strangeness in the cube, because red LEDs have a much lower forward voltage, they tend to light when setup this way with other LEDs. You can, and I have built the cube with 16 resistors on the microcontroller pins, this brings things to a much saner current level, but does make the cube notably dimmer.

I have spent quite a bit of time building and programming several of these, Ive figure out a few things along the way, and trying to document things on my LED cube website.

Here are some links to my site, and other helpful sites for background on charliecube and charlieplexing.

I have 2 instructables about the charliecube

https://www.instructables.com/id/Charliecube-Charli...

and

Asher Glicks website about the charliecube:

http://aglick.com/charliecube.html

Charlie Allen, and Charlieplexing:

https://en.wikipedia.org/wiki/Charlieplexing/

## Step 1: Start by Observing, and Exploring...

Observations, facts, and interesting things discovered while hacking about the code.

Charlieplexing generally lights only one LED at a time, multiplexing never lights all at one time, but usually a whole row, or plane can be light at a time. Charlieplexing also requires tri-state logic (5v, ground, or input), where multiplexing only needs binary (5v, or ground).

It can only light one voxel at a time, but it can light up any combo of the 3 LEDs inside each voxel. Most cubes light a whole plane of LEDs at one time, and that sets its duty cycle (4x4x4 are 25%, 8x8x8 is 12.5%, ...)
Every LED can be individually controlled by using the correct two microcontroller pins (with the correct polarity)

Since there are 64 voxels, this gives it a duty cycle of 1/64 at brightest.

There are 3 ways to relate to any specific LED, It can be referenced sequentially from 1 to 192, by it X, Y Z axis co-ordinates, or by the 2 microcontroller pins required to light it up.

There are a couple tables of information that work together in a way that is similar to DNS in computer networks, its a simple translation so that when you say light r123 (red LED at location x=1,y=2=3), the correct microcontroller pins are activated. This table is an ideal place to make changes if you have made a wiring mistake, and its where I made changes to adjust the cube height, but I also had to make many changes to convert the cube to common anode.

Inverting the pins in the program call did not light the cube as you might expect, it was not that simple, but it did get most of the LEDs, which made it easier for me to test, document, and fix the ones that were not right. Out of 192 LEDs, it got all but 48 right. This has to do with the way the cube is wired, the 4 layers of circuitry. It is interesting that inverting the polarity fixed 3/4 of the pins, but not all, and not none.

The sequence of 192 LEDs are organized by color, then in X, Y, and Z co-ordinates, and simple equation can decode this like this: (((color)%3)*64)+(x*16)+(y*4)+z So that you input that you want to light the red LED at the xyz co-ordinates 123, and it knows that red is the last group, so add 2*64 + 1*16 + 2*4 + 3, and that totals 91, it looks up the 91st entry in a table and gets the pin number for high, and low, to turn on only the right LED.

When you test a spire, you can tell that its an ideal number of LEDs controlled with that few number of control pins. Four pins control twelve LEDs. The way it does it is quite simple. you connect on common lead, and the other three are the R, G, and B. leads. If you change the common lead, that will control a different LED (physically higher or lower on the spire), and the other 3 leads will do the R, G and B. You can rotate the spire 4 time, and each time you rotate the spire, it changes height.

When you are going through the sequence, you can see patterns of numbers in groups of four. Each of these 4 numbers are the wires connected to a single spire. I took advantage of this several times fixing mistakes transposing data in the table. I could see how the pattern would be interrupted right at the LED number that wasnt working right. Probably the most interesting patterns are the miswires from inverting pins. Another way to put it would be the the ones that didnt light up right, after swapping common anodes for cathodes.

The tools that I used to accomplish this task (besides the cube, arduino, IDE, computer), were a text editor (like Im using now), and a spreadsheet program (open office calc).

My cube is not aligned like the original cube data, To get my cube to start at the right height, I had to start with 4 different flushbuffer tables (height shift on each, to tune the cube height), I started by changing the pin1, and pin2 order in calling the program, but when that didnt make the anode cube work right, I new I had to build custom maps, but over half was already right, so it wouldnt be as huge of a task as doing them all one by one.

I wrote a program to light up the LEDs in a sequence, based on the way the drawLED program works, looping x, y, and z, then cycling colors. I started with a program to light up a random LED in the cube, stripped out all the random stuff, and plopped in 3 nested loops (x, y, and z), then used a function built-in to the charlieplex.h file to color cycle.

I used this program to watch what LEDs lit, and made notes of the ones that lit in the wrong places, and what places they lit. After I compiled a list, I went through and confirmed each of those lit up the wrong thing with my test program. I used this data, and made a little conversion table. At this point I had all the info to fix everything, I just had to make some tables, swap some data, and test.

I started the process, and got things mostly fixed, and unknowingly bent a wire on the cube just enough to make it short with another wire. It caused a lot of havoc, it made about a dozen LEDs light other extra LEDs, and it made a few LEDs fail to ever light. I re-did my whole process using a spreadsheet, and flipping columns of data, and hand swapping 48 of the 192 data points in the table. and found I was having a lot of problems again. I was almost convinced that I needed to change the physical wiring to get the conversion to work. I noticed that the LEDs that failed to light were all on one spire, and I understood how the spire works, so I considered that it might have some problem. I examined it thoroughly to make sure that all the LEDs were in the right position, and so were all the other spires that were connected to it. I checked the wiring to make sure that I didnt have wires touching, because there are many wires that cross over other wires, that could touch. I found one of the stiffer wires was soldered right next to another stiff wire, and I bent that wire just enough so that it no longer made contact, and the problem when away.

That one short cost me a couple days of wasted work, but ultimately it doenst matter, because in less than a weeks time, Ive hacked this cube and have a working common anode charliecube.

## Step 2: Start Hacking the Code...

To modify the code meant converting arduino code, into a spreadsheet,
separating specific data out, manipulating tables, then putting things back together, and pasting back into a text editor. To pad with leading zeros to keep columns lined up, you need to format some columns to use leading zeros, then later you have to swap those zeros for spaces, or the compiler will squeak at you. You also have to be careful when pasting information in the spreadsheet. Sometimes you need to make sure that you only paste the data, not the formula or link. Other times you need to be careful to copy the relationships down a row,column, or matrix. I ended up making several processes, and several spreadsheet sheets for all the data. I needed 8 maps of data (4 for common cathode, and 4 for common anode). I will probably end up changing it to 2 maps, and a line to adjust the starting z value(z=z+1,2,3), and another to inhibit overflow issue(over 192 then z=z-192).

There are several files that contain various bits of code that make this LED cube work, and there are a few tables of information that you could manipulate to change how it works. The cubeplex.h file contains the flushbuffer table, which is what I chose to modify.
Here are a couple sample lines of the flush buffer.

if (_cube_buffer[ 0] != 0)flushElement(copy_frame, 4, 8,_cube_buffer[ 0]);

if (_cube_buffer[ 1] != 0)flushElement(copy_frame,16, 4,_cube_buffer[ 1]);

if (_cube_buffer[ 2] != 0)flushElement(copy_frame,12,16,_cube_buffer[ 2]);

if (_cube_buffer[ 3] != 0)flushElement(copy_frame, 8,12,_cube_buffer[ 3]);

You can see each line is serialized at both ends, but in the middle of the line, there are a pair of numbers that are unique to each line. You may also notice that there are spaces padding the numbers, so that things line up nicely, this is important when you manipulate the data later on.

This table of code sets up a relationship between pairs of number, and the sequence to light each LED. The numbers in the pairs represent the microcontroller pins, but later get translated to port addresses for speedy lighting.
Every LED can be controlled in this table, and no number combinations will be repeated. The sequence should stay the same, but the number pairs that represent microcontroller pins will need to be re-arranged to work with common anode LEDs with the original (common anode) code and wiring. I normally use a text editor for writing programs, but in this case, a text editor wouldnt work very well for manipulating the data. Since I was dealing with a table of numbers, 2 columns by 192 rows, a spreadsheet seem the most appropriate.

This isnt the first time I've done this, this is the second time that I've done this, it was a bit easier this time. The other time that I did this was to create 4 table to compensate for how the cube is oriented with the cube wiring. Depending on how you connect the wires, there are 4 common ways to do it, each table works with each of the 4 ways you can set up those wires.
To make a common anode cube work with the common cathode software, you would naturally assume that inverting the pins would do exactly what you want, but if you look at how complex large numbers of charlieplexed LED schematics look, you would assume that inverting the pins may not do the right thing at all.

When you examine one the the LED spires, you find that it uses 4 pins to light 12 LEDs, this is ideal in that every possible combination of ways to hook up a singe positive, and a single negative lead, will result in an LED being lit. The formula for calculating how many LEDs can be lit from an given number of microcontroller pins, is N squared minus N, or N times (N-1). A single spire has 4 leads, so the maximum it can control is 12 LEDs (4x4 =16, 16 - 4 =12, or 4 times 3 = 12. 4 RGB LEDs means a total of 12 LEDs. The cube is less than ideal, in that it uses 16 pins to control 192 LEDs, yet the max number of LEDs should be a 240, if they were wired in an idea fashion.
When you look at the code, you can see that every 4 lines is a group, because those microcontroller 4 pins control a single spire.

Now lets look at how to go about manipulating the data with a spreadsheet and a text editor, to get the desired results.

## Step 3: Work the Data

Its important to start with good table, and the original table is nicely padded with spaces for leading zeros (zeros dont work with the arduino code, but spaces are ignored), On a spreadsheet, space wont transfer over, but we can fix those columns to use 2 leading zeros, which will keep the data lined up nicely.

You can see how the data is nicely lined up in the first image, select the whole table of data (and just the 192 lines of code), and copy that data (ctrl-c)

Open your spreadsheet program, and paste into blank document. You may need to do paste-special, or some other method if it trys to paste the data into one column or cell. I used this window to tell it how to paste the data. I dont want it to automatically figure out that its tab or space delimited, I want to set it to fixed, to line up with my data, then set fixed points around my data, so that I can manipulate the parts that I want, without messing up the numbering (although the numbering could be re-created pretty easily if you make a mistake...)

The second image should show you the import text dialog box, this is where you set it to fixed width, and set the points where you make columns.

Now you have pasted the data, and everything looks great, except for one thing, those spaces that we used to make nice data columns are gone, but we can easily add leading zeros, which do the exact same thing. Start by selecting the 3 columns that make the number pairs, then right click on the column header and select format cells.

You should see something like the third image, where you can select how many leading zeros in the column, change it to two, and click ok. while the columns are selected, go ahead and copy those columns, and paste them into a new column to the right. Now we have all the data in the spreadsheet, we can actually make 8 different sheets (4 for common anode, 4 for common cathode). Lets start by making the 4 common cathode maps.

Each 4 rows represents a spire. to shuffle the data in each group of 4 rows. Its a pretty simple task to do this in a spreadsheet, using those 2 columns that pasted to help.
Select B1, and then click the = sign, or type the = sign in the input line, then click the cell (or type in the cell location, in this case H2). Do this again with D1, and I2 This will change the first line to look like the second line.

Now that the first line is linked to the right cells, we can repeat this down a couple times to get the first 3 lines relative links, because that is what we want.
The 4th picture shows how you select the 3 cells, click the tiny square at the lower right corner, and drag down 2 rows to copy the relative links down.
The fourth row is just like doing the first row, except for doing one row down, you do 3 rows up (B4=H1), and D4=I1)
Now you should have the first 4 rows adjusted, we just need to repeat this pattern all the way down to 192, and it will complete this table. Select the 12 cells (B1-D4), click on the square in the lower right corner, and drag down to the bottom of the spreadsheet (192 cells) see the 5th image

Now we have created a whole new table that will work if your wiring is off by 90 degrees. We need to do this 2 more times to make the other 2 tables. You can start with the original, and shift 2, then shift 3 for the last one. You could just take this one, and make a new sheet and do the exact same procedure on it to shift it one cell. Either way, and you should end up with 4 tables, each table works for each of the 4 ways the cube can be wired.

Note: when you paste the data, be very careful to only paste-special, and select numbers and text, but nothing else. see the sixth image.

To put the tables back, I had to do a bit of messing about to replace the leading zeros for spaces. text editors are good at that sort of thing, so I did it in a new text document, before pasting it into the cubeplex.h.

Start by copying the new table of data, then past that into a new blank text editor. It will look horrible, dont worry, we will fix that up real quick. First do a search and replace, and replace all the tabs ("\t") with nothing (leave the replace blank), that will help a lot! now we need to replace some spaces with zeros. Change the ""\t" to ",0", and replace that with ", ", this should take out the leading zeros, and put spaces in. This will keep all the numbers lined up, in case you need to do this again. Now you can copy the whole document, and paste it into the cubeplex.h file. You will need to repeat this process for the other 2 sheets, put them all in the cubeplex.h file, and comment out the ones you dont use. (only use one flushbuffer table, comment any other ones out.

Now we can move on to the real interesting part, making the common anode maps. What I did was use the map that works with my cubes orientation. I had to try each of the 4 new tables, and I used the fountain program, and slowed it down a lot, so I could see it light the first sequence of 4 steps. You can see where it starts, if its not the bottom, use a different map, until it starts at the bottom. It should start at the bottom, then go up one, then two, then the top then start working down around the outside and down.

Once you have the right map for your cube, go back to your spreadsheet, and find that map, start a new sheet, and copy that maps data (just the text and numbers, no formula or anything). Copy column B and paste it to an empty column to the left, copy column D, and paste it into column B, copy the the copy of column B, into column D. Now you have a table for common anode LEDs, but they are only 3/4 right, and we dont know which ones are wrong. Since most are right, its a real good start, we should be able to tell when we try out this code. You need to copy the data to the cubeplex.h file using the same procedure we did before.

To figure out which pairs were wrong, I wrote a simple program that sequences turning on and and off each LED 1 through 192, but the program that lights up the LEDs uses X, Y and Z co-ordinates. So I looked for a program that was close to what I wanted to do, and modified it to suit my needs. There is a program called chaseTheDot, that comes with the cube software, I changed it to SeqTheDot, and removed the random, and plugged in nest of 3 loops
to sequence the X, Y, and Z, and added a few features. Here is my test code:

/******************************** Sequence THE DOT ****************************\

| |

| |

| Hacked up by hippynurd@gmail.com to suit his testing needs. |

| Inspired By: Jonah Glick |

| Written By: Asher Glick |

\******************************************************************************/

void SeqTheDot() {
continuePattern = true;

int animationSpeed = 200; // change this to speed up or down.

// color= green; // change this to set a specific color or comment it out to cycle.

int xpos = 0;

int ypos = 0;

int zpos = 0;

while (continuePattern) {
// switch(random(0,6)) {

// Instead of random, we want to sequence, so we increment x each loop

// and increment each y at max x, and reset x to 0, at each y max we

// increment the z and reset the y, and the x.

for (xpos; xpos < 4; xpos++) {

for (ypos; ypos < 4; ypos++) {

for (zpos; zpos < 4; zpos++) {

// drawLed(color,1,1,3); // use this one to light up a specific LED

drawLed(color,xpos,ypos,zpos);

flushBuffer();

clearBuffer();

delay(animationSpeed);

} zpos=0;

} ypos=0;

} xpos=0;

} color=nextColor(color); }

The program will go through each LED 1 time, each time it gets to the end of the cube, it changes colors, it does the 7 colors that are built in (red, purple, teal, yellow, blue, green, and white). When it does the secondary colors, its mixing 2 LEDs. when it does white, its only

Now upload the sketch to your cube, and take notes when it fails to light the correct LED. Note the position and color that it lights, We will use this info later to edit the table.

Go back to the spreadsheet, it should have the last sheet still open in it. Delete the extra column if you havnt already, then copy the 3 columns of data, and paste them off to the side. If we make a mistake (its real easy to do...) you can always copy the data in these columns back, and start over. Remember, when doing this copy only text and numbers, just the data.

Now go to that list, start at the top, your list should have where it was supposed to light, and where it did light, note where it was supposed to light, scroll down to that line in the code, and copy the 3 columns of data on the right in that row. Scroll down to that LEDs sequence number and paste it into column B (it should fill in B, C, and D). There are 48 of them, take your time with each one, its easy to mess it up.

When you are done, you should have everything mapped out correctly, copy the new table to your cubeplex.h file, using the same method as previously used, comment out the others, and upload the sketch. If you did everything right, it should work, I didnt do everything right and I had to repeat the process a couple times before I got them all lighting up the right LEDs in the right sequence.

Once I had it right, I was able to make 4 tables like I did for the common cathode versions, then I was able to use the program diff to find the difference between the two files, and have a complete list of the changes.

You could use the cube the way it is, but I did not notice that the common anode cube is upside down from the common cathode cube, Most people wont notice that its upside down, but I do, so I had to change that, with the spreadsheet, it was quick and easy. Make a new sheet, copy the last table over, then copy the 3 columns like we have done so many times before. Now what we want to do is re-order each group of 4, so that instead of 4,3,2,1, it does 1,2,3,4. To accomplish this, select cell B1, click the =, click the cell H4, hit enter, then click the corner square and drag over 2 cells to copy the formula over, or click D1, and click the =, then click I4, and hit enter. Now we can do the same with B2, and H3, then B3, and H2, B4, and H4. Click the corner on each and drag the formula over, or do the D column cells one at a time. At that point you should have the right formula in the first 4 rows. now select those 12 cells, click the corner square, and drag all the way down. This should put things in the right order, now copy the data, and paste it to the cubeplex.h file using the method previously mentioned. Repeat that process for each of the common anode data sets, and copy them over using the same method previously mentioned. Now you have a total 0f 8 sets of data, 4 for common anode, 4 for common cathode.

## Step 4: Now Enjoy Your Common Anode Charliecube.

Here is the common anode cube running the test program.

## Step 5: Time Lapse Video of Making a Charliecube Spire...

Just for fun im including this quick little time lapse video of me making a charliecube spire. I wish I could really make them this fast.

## Recommendations

• ### 3D CAM and CNC Class

353 Enrolled

• ### Microcontroller Contest

We have a be nice policy.

## Questions

Please provide a schemetaic - thx.

I dont have a schematic. I do have a few other instructables with more info about building them. I did make a schematic for a spire, but I cant find it right now.
Some folks made a PCB, I havent tried it, but you can probably find a schematic from here:
http://fritzing.org/projects/pcb-for-4x4x4-rgb-charliecube

Thank you so much for doing all the work to massage all these tables and especially for the common anode ones, you saved me a ton of work! I ordered my LEDs before making the decision to go the charlieplexed route and many of the tutorials I had seen used constant current sink LED driver chips, therefore needing CA LEDS.

I'm pretty sure I found the reason 48 of those values (of the 192 total) needed tweaked manually. I built my 16 spires and wrote a small sketch to cycle each of them (with only one spire at a time on a breadboard), so I knew they were all assembled correctly. Then I plugged all 16 into my breadboard and wired exactly according to http://aglick.com/charliecube.html. I even flipped Asher's wiring diagrams so they show a top-side view for easier wiring on the breadboard.

Once I plugged in your cubeplex.h and uncommented the first CA section I wrote a small sketch similar to your SeqTheDot, but cycling in the opposite manner, i.e. with z-axis as the outer loop and x-axis the inner one. So this would scan each horizontal plane in turn. Of course I expected it to go in an orderly fashion but got a surprise instead!

It seemed that for each color (my test sketch had the outer-most loop go through red, green, blue) there were two planes exactly right and two others with 8 errors each! So 16 errors per color for a total of (yes you guessed it) 48!

So after a bit of head scratching I double-checked my wiring and then it came to me... the errors all had to do with wires 13 & 14. But wait a minute, aren't those two inverted on Asher's wiring diagram? Yes! So after swapping wires 13 & 14 at the arduino the test sketch worked like a champ, hurrah!

OK so what about wires 15 & 16, they are also inverted on the wiring diagram! Luckily those must have been placed correctly else the errors would have been much more...

So now to ask a favor (or two). My cube is upside down using the 3 off (CA4) table, even though the comment says "New not upside down table..." So how easy is this to fix?

Also I would really like to eliminate Digital 13 and use Digital 18 (A4) in its place. The reason is, for any LED which uses this pin I get flicker on some red LEDs. I believe this is due to the built-in LED and resistor on the arduino board, but I don't want to alter the board e.g. by cutting traces. I may use it again for other projects and would prefer to keep it intact. What would I change to make this switch? I'm guessing its in mappings.h but I can't figure out how those pin mappings work.

Sorry for the overly long post, and thanks for all your great work and any advice you can provide!

8 replies

OK I got the CA4 table inverted by following your excellent
instead of sliding three down and the fourth up to the top. BTW the
zeroes when copying back from the spreadsheet!

I still want to
replace Digital 13 with Digital 18 (A4) to see if it fixes my red LED
dim glow on Wire 12, any help is really appreciated!

Thats great info, thanks for your contribution.

Im pretty sure that the pin mappings are in a file called mappings.h, but they dont call them pin 1, 2, 3, 4... they use port addressing (which is a good way to do it, its faster than a digitalWrite. Sadly I dont know know port addressing. If you look at the first section of code, you will see 16 sets of 3 #defines, each one of those are probably the port addresses, you probably want to change the 13 set, but I dont know what the correct changes would be, to make it use a different pin.

You are right, its in mappings.h, but he is using the Wire numbers
to ID each group. So to change Wire 12 from Digital 13 (PB5) to Digital
18/Analog 4 (PC4) the change is:

// original mapping
//#define P12B 0x20
//#define P12C 0x00
//#define P12D 0x00

// switch Wire 12 from PB5 to PC4
#define P12B 0x00
#define P12C 0x10
#define P12D 0x00

That gets rid of my ghosting on those 4 red LEDs connected to Wire 12 completely! Apparently it was an artifact due to the Arduino board containing the built-in LED on Digital 13.

Thats great. Yes, the pin13 issue is a problem for some folks, It doesnt bother me, but I have read about people removing the LED because they are so annoyed by it.

Ideally, I would like to go through the 48 changes, and figure out a way to re-wire the cube so that it can be converted to common anode by simply inverting the pin values in DrawLED. I would also like to be able to adjust the Z value, instead of having 4 tables. Then you could setup a few variables in the beginning instead of trying out which of the 8 tables is best for your cube.

Ideally, I would like to go through the 48 changes...

Yes that would be cool, it would make more sense to keep in line with Asher's original wiring diagrams (even though he used an odd numbering especially with Wires 13-16).

...and figure out a way to re-wire the cube so that it can be converted to
common anode by simply inverting the pin values in DrawLED.

I don't think its possible. There are 3 anodes for each cathode using common cathode LEDs, and 3 cathodes for each anode using common anode LEDs. So logically simply inverting pins doesn't work in this scenario. Perhaps using some inverting logic in the hardware would make the tables simpler but that would up the parts count considerably.

I would also like to be able to adjust the Z value, instead of having 4 tables.

That might be doable, perhaps using vectors. But at a minimum I really think a separate table is needed for common cathode vs common anode.

When I embarked on this hack, I wasnt sure if it would work with common anode LEDs. I was sure that a spire works either way, but not the cube. This uses 16 pins to control 192 LEDs, which means that its not ideal, but a spire uses 4 pins to control 12 LEDs, which is ideal. By ideal, I mean that every pin is used, and there are no unused connections. With 16 pins, you could control up to 240 LEDs (n squared minus n or (n * n-1) is the formula for charlieplexing, and 16 times 15 =240, which means that if wired differently, we should be able to control more LEDs that we are, which makes this less than ideal. It may even require using extra pins to control the LEDs differently to make it possible to do both common anode, and common cathode with the exact same wiring and table with a simple single polarity shift in the code.
The way the software works, you are never lighting more than one voxel at a time, which means that its not so complex as you may think.
If you look in the Display section of the cubeplex, you can see an easy place to swap pin1 and pin2 values to do polarity swap, and if you look.
The drawLed section might be a good place to do the height( z) adjustment, but im not sure, it also requires some condition checking, and adjusting if outside the data set.

Well it stands to reason that common anode LEDs will work just as well as common cathode. After all, the entire basis of Charlieplexing is, all combinations of pins taken two at a time, and each pair having an two LEDs in opposite polarity. So with the correct pin assignments for pin1 & pin2 in his drawing routines that becomes pretty simple really. And of course I realize the limit for this scheme (using 16 Arduino pins) is 240, not 192, so that does open up certain possibilities.

That said, I feel it would be overkill and inefficient to try to adjust the wiring to get both LED types supported. It is much easier done in software, as you have already proven with your (most excellent) additional tables for flushBuffer in cubeplex.h. However its not as trivial as swapping pin1 & pin2 values in e.g. flushElement (we only wish it were!)

Since anyone brave enough to take on this project and spend all the time soldering LEDs etc will surely need to dive into the code anyway, I feel your solution to uncomment the correct table is as elegant as is needed. Remember the display section needs to be fast above all, so introducing a lot of calculations to massage the table data for LED polarity and orientation (z-axis) could end up being too slow.

BTW there are a couple of forks of Asher's original code on github... this entry by Spencer Bliven looks very cool! He seems to have worked out a way to change the pin mappings very easily using macros. Be sure to check out the Readme, I think you'll like what Spencer has done!

https://github.com/sbliven/Charliecube

Any problems with ghosting? I know charlieplexed things tend to have an inherent ghost running around in the LEDs.