The 3D LED Cube, Part Deux
Over the month of August, (besides work related travel, moving, and a lot of downtime), we continued to work on the cube, refining the hardware and doing extensive programming. This page shows some of the stuff done over the past month.
Now, on to the work completed.
Week One of August 2005
Nothing done. I was traveling to DARPATech for the week.
Week Two, August 2005
The first thing we did was a lot of programming. I wondered if we could time modulate the bicolor LEDs to get 16 levels each of red and green, giving a total of 256 colors. To do this well, it would take a double-buffered interrupt driven display, so the first thing I did was get this running, with a simple rule: color 0 is 0 slices on out of 15, color 1 is 1 slice out of 15, up to color 15 is all 15 out of 15 on. We estimated we'd need about 50 frames per second to avoid visual flickering, and each interrupt draws 8 pixels, so to get all 64 LEDs updating 50 times a second with a pattern cycle length of 15 would take 50*(64/8)*15 = 6000 interrupts a second. Since our PIC runs 8 MIPS, we'd have 2^23/6000 = 1400 cycles per interrupt (if that was all we did). After programming this, there was still weird flicker on some colors, and it took a lot of work to eliminate this (explained throughout this page). Here is the initial derivation of the coloring routines:
The initial idea was a DDA based per-pixel overflow routine that would determine when to turn on LEDs, and when to turn them off. This proved to be inadequate.
Also this week, we ordered more parts since the initial cube worked well. Gene removed the breadboard, replacing it with a smaller circuit containing some debugging LEDs and buttons. We also added 4 buttons for control and debugging purposes. Here is the resulting circuit (spread across a few perfboards).
The buttons to control the cube.
Here is the main CPU board, with plugs to run the timing board, connect to the button board, and a switch to toggle programming/running modes.
And the bottom of the board...
The board responsible for taking clock tics and control signals and lighting the LEDs.
Week Three, August 2005
I continued programming, and Gene and I were trying to remove flicker. If the interrupt ran around 20,000 times a second, flicker would disappear, but the C code interrupt was too many cycles, so it stepped on itself creating other problems. Oddly, some higher numbered colors were flickering while lower ones were not. I soon realized those with no flicker were those whose on/off pattern had a small length that divided 15 exactly. Also, the Microlab C compiler generated code that would step on itself: the solution they recommended was to look at the disassembled code, and tell the interrupt to save those locations needing maintained. This proved to be a lot of error-prone work.
We eventually deduced the flicker was coming from longer harmonics in the refresh patterns: for example, if the light was to be on 11 out of 15 cycles, the asymmetry of the on/off amount caused a 15 cycle flicker that was noticible. We looked into other patterns, trying to minimize a combination of overal cycle length and keeping short harmonics. For work like this a good tool like Mathematica is needed. Here is a screenshot while I was testing/deriving a good color cycle to meet the constraints.
This would take a long time to get smooth. Overall I wanted to minimize the time used in the interrupt overall, yet have absolutely no flicker in the resulting color.
Parts arrive for building the 8x8x8 cubes.
Unloading some bags....
... results in chips, dips, chains, whips...
The main component: TONS of LEDS!
Bags of transistors, chips, ....
... sockets, connectors ....
... resistors galore ...
... and tubes of controller chips.
We also ordered several types of wire (galvanized, stainless, ?) to make the resulting cube structure, but none of them worked flawlessly. More about this on week four.
We don't want to hand wire the controller boards for the 8x8x8, since it would be a nightmare. Soldering the 512 LEDs to make the cube (well, 1024 for TWO cubes) is already going to be a lot of work. I learned how to use PCB Express to create schematics and PCB layouts. After doing this a while we found we had access to the much better Orcad, which we switched to.
Week Four, August 2005
Wanting to try some other spacing before making 8x8x8 cubes, I created a smaller one. First a bag of LEDs.....
... is soldered into a smaller template ....
resulting in the Mini-Cube.
Gene, being the big-thinker that he is, makes an Uber-template and some of our wire, along with a wiring design we concocted, and creates a bigger spaced 4x4x4 cube. Two benefits are this design has all wires leaving the base instead of some on the sides, and it is wider spaced since we used some stiff wire instead of LED leads for connection. The downside is that it was much harder to solder this together, a problem needing solved before attempting the 8x8x8 cubes.
The Three Cubes - Papa, Mama, Baby. The big one has a new wiring mode letting all wires leave the bottom, making it look much better. Minor code changes and it's up and running.
Working from a schematic I drew, Gene creates a single board solution. We moved some of the PIC ports around to allow 4 debugging lights (bicolor - one port output), nice control buttons , etc. all on one board. Here it is (after a few minor corrections).
The board top.
At this point, I had enough information to create a mathematically optimal color cycle. I also found a much nicer algorithm to draw the pixels during the interrupt, and recoded this new method in C. Profiling the code showed the interrupt went from around 1100 cycles to 900 cycles, an improvement, but not fast enough for what we wanted. So I recoded the entire interrupt and supporting routines in assembly, getting down to about 256 cycles, which was very fast. Running the interrupt around 6000 times a second now had no flicker! It is rock-solid. So the interrupt uses about 1.5 million cycles per second, leaving about 6.5 million for computing images. At 50 frames a second, we now have 130K cycles per frame, which should allow us any level of complex visualization.
Plus, on the 8x8x8, we will need a bit more time for an interrupt, so this gives us some wiggle room.
We also are experimenting with a single chip solution, shown here from the top (this replaces everything except the power and PIC)
And the insanely wired bottom:
The LED Cube - Code Update
Just for fun here are some of the code features:
A second interrupt runs a clock for timing visualizations and profiling code.
Coordinate system is a right hand rule with a debug mode showing this to aid mis-wiring cubes.
Various symmetries can be assigned to visualizations.
Small 4x4 font support.
Uptime clock to aid in debugging.
Multiple commands from the buttons to pause, select image, lock visualization, go to next visualization.
Debugging modes - many routines button selectable for aiding coding.
Very small, fast assembly interrupt routine.
Code cross compiles and runs under Windows (with a shell) to aid debugging.
Generic path and movement routines.
Fixed point math for fast rotation/sin/cos/math routines.
Animated sprite support.
Arbitrary transformation/symmety/translation at the SetPixel level.
Transitions between visualizations.
EEPROM reading/writing for users to select visualizations to view/not view.
Ability to run images from PC.
Scripting language to allow easy development of visualizations on PC.
Better font support.
3D manipulation of images and drawing.
The LED Cube - Hardware Update
We had some power problems - it appears the circuit draws more amps than multimeters report, since multimeters seem to time average the amounts and we have spikes. After some issues, this seems solved.
Gene is designing some standalone boards programmable by a serial interface (all boards currently use a parallel port), and we will probably have to redesign some of the layout to handle the UART.
We are in the process of making PCBs for 4x4x4 standalone, 4x4x4 with programmer, and the final 8x8x8 standalone PCB. Before ordering this ($$$) we want to make sure all issues are ironed out.
The LED Cube - End of August 2005
And that is the end of the first month of cube work. Stay tuned for more...
Here are two videos of the resulting cube: Video 1 (15MB) Video 2 (15MB). Note all visualizations are copyright Chris Lomont and Gene Foulk, 2005. Sorry these are a little jerky. Next time I'll use a tripod!