I've tried to design a 4x4x4 LED cube in as simple a way as possible, using as few components as possible. Hopefully this will provide inspiration for others wanting to build their first cube!
At the time of starting this thread, the cube is constructed, but connected on a breadboard. I am working on a stripboard to connect it to permanently.
First of all, here is the schematic:
Obviously, only one layer of 16 LEDS is shown. The other layers share the J1 to J8 connections, but layer 1 uses J9 & J10, layer 2 uses J11 & J12 and so on.
The construction is slightly different to what some would call "standard", in that the cube is constructed in 2 halves, a left half and a right half, each half having 8 LEDS on a layer, by 4 layers high. This layout suits the max7219 driver chip, which was originally designed to drive 8 7-segment displays (8-segment if you include the decimal point). 8 digits x 8 segments = 64 LEDs, but here they form a cube!
And here is the code as it stands, with 3 animated patterns:
I'll add more pictures & videos below.
At the time of starting this thread, the cube is constructed, but connected on a breadboard. I am working on a stripboard to connect it to permanently.
First of all, here is the schematic:
Obviously, only one layer of 16 LEDS is shown. The other layers share the J1 to J8 connections, but layer 1 uses J9 & J10, layer 2 uses J11 & J12 and so on.
The construction is slightly different to what some would call "standard", in that the cube is constructed in 2 halves, a left half and a right half, each half having 8 LEDS on a layer, by 4 layers high. This layout suits the max7219 driver chip, which was originally designed to drive 8 7-segment displays (8-segment if you include the decimal point). 8 digits x 8 segments = 64 LEDs, but here they form a cube!
And here is the code as it stands, with 3 animated patterns:
Code:
'08m2 4x4x4 LED Cube using MAX7219 Driver IC
'P. Beard Aug 2012
#picaxe 08m2
'These variables (w2 to w5) hold the current patterns for each layer in cube.
symbol LAYER1 = w2
symbol LAYER1LEFT = b4
symbol LAYER1RGHT = b5
symbol LAYER2 = w3
symbol LAYER2LEFT = b6
symbol LAYER2RGHT = b7
symbol LAYER3= w4
symbol LAYER3LEFT = b8
symbol LAYER3RGHT = b9
symbol LAYER4= w5
symbol LAYER4LEFT = b10
symbol LAYER4RGHT = b11
symbol RANDSEED = w6
symbol SPEED = w7
symbol ANIM_LOOP = b16
symbol SUB_LOOP = b17
'Pins for serial communications with the MAX7219 IC
symbol M7219DATA = PinC.0
symbol M7219CLK = C.4
symbol M7219LOAD = C.1
symbol LDR = C.2
main:
setfreq m32
w0 = $0C01 : gosub send7219 'Switch on LED Driver
w0 = $0900 : gosub send7219 'Set no decoding on any digits
w0 = $0B07 : gosub send7219 'Scan all 8 digits
w0 = $0F01 : gosub send7219 'Display test mode on
pause 10000
w0 = $0F00 : gosub send7219 'Display test mode off
RANDSEED = 1234
Do
'Rotation
SPEED = 500
gosub randomcolumn : LAYER1 = w1
gosub randomcolumn : LAYER2 = w1
gosub randomcolumn : LAYER3 = w1
gosub randomcolumn : LAYER4 = w1
gosub randomcolumn : LAYER1 = LAYER1 | w1
gosub randomcolumn : LAYER2 = LAYER2 | w1
gosub randomcolumn : LAYER3 = LAYER3 | w1
gosub randomcolumn : LAYER4 = LAYER4 | w1
For ANIM_LOOP = 1 to 200
w0 = LAYER1 : gosub rotateclockwise : LAYER1 = w0
w0 = LAYER2 : gosub rotateclockwise : LAYER2 = w0
w0 = LAYER3 : gosub rotateclockwise : LAYER3 = w0
w0 = LAYER4 : gosub rotateclockwise : LAYER4 = w0
'inc LAYER1
gosub updatecube
Next
'Random rise & fall
random RANDSEED
LAYER1 = RANDSEED 'Start off with all bottom layer lit
LAYER2 = 0
LAYER3 = 0
LAYER4 = LAYER1 ^ $FFFF
SPEED = 500
For ANIM_LOOP = 1 to 33
Do
'Pick an led on the bottom row that is lit
gosub randomcolumn : w0 = LAYER1 & w1
Loop until w0 <> 0
'Move that led up to the top layer
LAYER1 = LAYER1 ^ w1 : LAYER2 = LAYER2 ^ w1 : gosub updatecube
LAYER2 = LAYER2 ^ w1 : LAYER3 = LAYER3 ^ w1 : gosub updatecube
LAYER3 = LAYER3 ^ w1 : LAYER4 = LAYER4 ^ w1 : gosub updatecube
Do
'Pick an led on the top row that is lit
gosub randomcolumn
w0 = LAYER4 & w1
Loop until w0 <> 0
'Move that led down to the bottom layer
LAYER4 = LAYER4 ^ w1 : LAYER3 = LAYER3 ^ w1 : gosub updatecube
LAYER3 = LAYER3 ^ w1 : LAYER2 = LAYER2 ^ w1 : gosub updatecube
LAYER2 = LAYER2 ^ w1 : LAYER1 = LAYER1 ^ w1 : gosub updatecube
Next
'Random Rain
SPEED = 1000
For ANIM_LOOP = 1 to 100
LAYER1 = LAYER2 : LAYER2 = LAYER3 : LAYER3 = LAYER4 : gosub randomcolumn
LAYER4 = w1 : gosub randomcolumn
LAYER4 = LAYER4 | w1 : gosub updatecube
Next
loop
send7219: 'Send contents of w0 to the MAX7219 Driver IC
pulsout M7219CLK, 1 'Bits 15 to 12 are not used
pulsout M7219CLK, 1
pulsout M7219CLK, 1
pulsout M7219CLK, 1
M7219DATA = bit11 : pulsout M7219CLK, 1 'Bits 11 to 8 are the command
M7219DATA = bit10 : pulsout M7219CLK, 1
M7219DATA = bit9 : pulsout M7219CLK, 1
M7219DATA = bit8 : pulsout M7219CLK, 1
M7219DATA = bit7 : pulsout M7219CLK, 1 'Bits 7 to 0 are the data
M7219DATA = bit6 : pulsout M7219CLK, 1
M7219DATA = bit5 : pulsout M7219CLK, 1
M7219DATA = bit4 : pulsout M7219CLK, 1
M7219DATA = bit3 : pulsout M7219CLK, 1
M7219DATA = bit2 : pulsout M7219CLK, 1
M7219DATA = bit1 : pulsout M7219CLK, 1
M7219DATA = bit0 : pulsout M7219CLK, 1
pulsout M7219LOAD, 1
return
updatecube: 'Update the cube LEDs
b0 = LAYER1LEFT : b1 = $01 : gosub send7219
b0 = LAYER1RGHT : b1 = $02 : gosub send7219
b0 = LAYER2LEFT : b1 = $03 : gosub send7219
b0 = LAYER2RGHT : b1 = $04 : gosub send7219
b0 = LAYER3LEFT : b1 = $05 : gosub send7219
b0 = LAYER3RGHT : b1 = $06 : gosub send7219
b0 = LAYER4LEFT : b1 = $07 : gosub send7219
b0 = LAYER4RGHT : b1 = $08 : gosub send7219
readadc LDR, b0
b0 = 255 - b0 / 16
b1 = $0A : gosub send7219 'Set intensity
pause SPEED
return
randomcolumn:
'Pick a column at random and return in w1
random RANDSEED
w0 = RANDSEED & 15
lookup w0, (1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384, 32768), w1
return
rotateclockwise:
'Rotate w0 clockwise
'04 05 06 07
'03 02 01 00
'12 13 14 15
'11 10 09 08
bit16 = bit8
bit8 = bit15
bit15 = bit0
bit0 = bit7
bit7 = bit6
bit6 = bit5
bit5 = bit4
bit4 = bit3
bit3 = bit12
bit12 = bit11
bit11 = bit10
bit10 = bit9
bit9 = bit16
bit16 = bit14
bit14 = bit1
bit1 = bit2
bit2 = bit13
bit13 = bit16
return
end
Last edited: