The software is derived from my earlier LED cube, the charlieplexed version. Of course the "hardware layer" had to be changed, because physical control of the LEDs is different. But the rest is very similar.
To add a bit more structure, I partitioned it into several files. There is the main routine (in LEDCube444.c), the file HWControl.c for low level hardware support and a collection of software routines to generate procedural patterns called PatternTools.c.
The patterns or rather pattern sequences are in individual files. This has the advantage that they can be included optionally or rearranged. You can also add your own creations.
If you are not interested in modifying anything, just skip the details. But if you are, here it goes.
It contains the main routine.First it invokes the initialisation routine, then it displays the HW check pattern sequence once and finally it starts an endless loop displaying all the patterns. The patterns are #include'd so it is very easy to manage them.
This file contains two important sub-routines. First, there is the "ioinit" routine. It initialises the IO ports of the controller and sets the timer for the multiplexing interrupt. Finally, it enables interrupts.
Second, there is the interrupt service routine (ISR). It switches through the LED groups (i.e. the half-levels) and sets the appropriate anode values. It gets these values from a pre-calculated array, so there is little processing in the ISR. As a small addition I added a dimming function. The global variable "dimmer" can be set to values between 0 and 32 to set the cube's brightness.
A secondary task in this routine is the implementation of an egg timer. It can be set to a certain value and then will count down in the ISR. This is a simple way to create delays. Quite often in sequences, the waiting time is always the same, so there is a global variable "current_delay". If set, all you have to do is invoke the "standard_delay" routine in order to get a fixed delay.
There are a few other routines in this module. They are secondary display functions. Most important is the calculate_IO routine. It translates the cube array values to port values for use in the ISR.
The cube array ("LED_Cube") contains the LEDs to be set. Each LED corresponds to one array element. The top, right, front LED is LED0. The one behind is LED1, after that follow LED2 and three. LED4 is the top, front, second from right LED. This continues in a regular sequence until LED63, which is bottom, back, left.
To help writing compact code, there is a "display" routine. It invokes the calculate_IO and then the standard_delay routine. And then there is the "do_plus" routine. It is the same as the "display" routine but also clears the cube after the delay. It is then ready for the next LED setting to be generated.
My pattern sequences are more or less generated by algorithms rather than just read back from memory somehow. To that end I created a set of tools to create certain elements.
The most obvious is a "set_LED" routine. It is almost trivial. The LED number is the argument and it is used the set the corresponding cube array element.
Far more interesting and powerful is the "set_pattern" routine. During my first attempts to generate patterns, I found that a lot of elements like a fully set plane or column are actually regular patterns in the cube array. As an example, setting the top plane means just to set the first 16 LEDs. To set the second plane you have to set 16 LEDs again, but this time with an offset of 16.
In order to set a vertical plane, you have to set 4 LEDs in sequence, then skip the next 12 LEDs. Then you have to repeat this 4 time.
The "set_pattern" routine has therefore 4 parameters: The offset ("start"), the no. of LEDS to be switched on ("LED_on"), the number of LEDs to be off ("LED_off") and a "repeat" value.
Based on this algorithm, there are many other pattern generating routines, like setting columns in various directions.
Finally, there is a support routine to generate "pseudo_random" numbers, via a LFSR.
These are located in a sub-directory "patterns". Take a look if you want to write your own sequences. If you are not that firm, you can start by modifying the existing patterns. The loop variables i ,j and k are available for the pattern generating algorithms.
Programming the Controller
The software was written and compiled under Atmel AVR-Studio. The download package contains a hex-file in case you want to quickly get the cube working, without compiling the firmware first.
There is only the flash ROM to write. EEPROM is not used.
The fuse setting is default, but the internal RC clock oscillator is set to 4 MHz. In AVR-Studio the fuse setting is reported as:
HIGH: 0xD9 LOW: 0xE3
The patterns shown in the youtube video take less than 50% of the flash memory of the ATMega8 controller. So first of all it would be possible to add more pattern sequences. Then, there are still a few pins available. So, you could add some buttons and create some kind of interactive display.
Since the serial RX/TX pins are left over deliberately, it would be possible to use some kind of remote control scheme to control the cube.
Lots of possibilities to experiment!
That is it. If you build this cube, I would appreciate it if you could let me know. I am always interested to learn if this post inspired anyone. And if you have proposals to improve it, do let me know.
In case you have questions, either leave a comment or get in touch via email (see my profile). But please give some kind of name or alias. Otherwise it can get confusing...
Oh and the software, as with all my projects is available through the download page.