Für unseren LED-Würfel gehen wir nach dem selben Prinzip vor, wie bei der LED Matrix. Wir verwenden 4 Ebenen und 16 Säulen um die 64 LED unseres 4×4 Würfels zu steuern.
Zuerst erstellen wir eine Schablone mit Löchern im Abstand von 3 cm für die LED und testen diese vorher mit einer Knopfzelle.

Dann löten wir alle Anoden an ein Gitter aus Kupferdrähten. Diese haben wir aus alten Kabeln genommen und gerade gezogen. Am besten geht das, indem man den Draht an einem Ende in einen Schraubstock einspannt und das andere mit einem Akkuschrauber hin und her dreht währen man daran zieht.

Die Lötstellen sind nicht sehr schön, aber das spielt keine Rolle. Von diesen Teilen haben wir 4 Stück gemacht. Dann eine kleine Plattform aus Holz zusammengeleimt. Ah ja, der Deckel bekam noch Löcher für die Drähte der Säulen, welche so platziert sind, dass sie mit den Kathoden der LED verbunden werden können.

Dann nach dem Trocknen des Leims haben wir alles schön fein geschliffen, die Kanten abgerundet und alles mit einer Lasur überzogen.

Die Drähte für die Säulen werden mit Heissleim befestigt.

Die 4 Ebenen werden auf die Säulen gesteckt und alle Kathoden an den Säulen verlötet. Abstand der Ebenen ist natürlich wieder 3 cm.

So sieht dann der Würfel aus. Jede Ebene, an dem alle Anoden befestigt sind, wird noch mit einem Draht verbunden der durch den Sockel geht.

Nun die Kabel – an jedem Draht der unten rauskommt muss ein Kabel befestigt werden. Wie vorher erwähnt, sind das 16 Säulen plus 4 Ebenen, also 20 Kabel.

Jetzt die anderen Enden der Kabel mit dem Microcontroller verbinden. Wir verwenden einen Raspberry Pi Pico. Die Anschlüsse GP0 bis GP15 sind für die 16 Säulen. Die 4 Ebenen sind an GP16-19, wobei auch noch ein Widerstand mit 100 Ohm dazwischen liegt. Hier ein Link zu einer praktischen Übersicht der Pinbelegung des Picos: https://picow.pinout.xyz/

Nun kann die Programmierung des Pico beginnen. Dazu verwenden wir Thonny auf einem Rasbperry Pi 5 mit dem RaspiOS als Desktop Oberfläche.
from time import sleep
from machine import Pin
columns = [
Pin(0, Pin.OUT),
Pin(1, Pin.OUT),
Pin(2, Pin.OUT),
Pin(3, Pin.OUT),
Pin(4, Pin.OUT),
Pin(5, Pin.OUT),
Pin(6, Pin.OUT),
Pin(7, Pin.OUT),
Pin(8, Pin.OUT),
Pin(9, Pin.OUT),
Pin(10, Pin.OUT),
Pin(11, Pin.OUT),
Pin(12, Pin.OUT),
Pin(13, Pin.OUT),
Pin(14, Pin.OUT),
Pin(15, Pin.OUT)
]
levels = [
Pin(19, Pin.OUT),
Pin(18, Pin.OUT),
Pin(17, Pin.OUT),
Pin(16, Pin.OUT)
]
snake16 = [0,1,2,3,7,6,5,4,8,9,10,11,15,14,13,12]
snake16rev = snake16.copy()
snake16rev.reverse()
def col(state):
for c in columns:
if state:
c.high()
else:
c.low()
def lev(state):
for l in levels:
if state:
l.high()
else:
l.low()
def allOn():
col(False)
lev(True)
def allOff():
col(True)
lev(False)
def blinkAll(times, speed):
allOff()
for n in range(times):
sleep(speed)
allOn()
sleep(speed)
allOff()
def cycleSingle(speed):
allOff()
for l in levels:
l.high()
if levels.index(l) % 2 == 0:
order = snake16
else:
order = snake16rev
for c in order:
columns[c].low()
sleep(speed)
columns[c].high()
l.low()
allOff()
def colOn(number):
col(True)
lev(True)
columns[number].low()
def cycleCols(speed):
for n in snake16:
colOn(n)
sleep(speed)
allOff()
def rowOn(number):
levels[number//4].high()
for c in [0,4,8,12]:
columns[c+number%4].low()
def cycleRows(speed):
for n in snake16:
rowOn(n)
sleep(speed)
allOff()
def lineOn(number):
allOff()
levels[number//4].high()
for l in range(4):
columns[l+(number%4)*4].low()
def cycleLines(speed):
for n in snake16rev:
lineOn(n)
sleep(speed)
allOff()
def levelOn(level):
lev(False)
col(False)
levels[level].high()
def cycleLevels(speed):
lev(False)
col(False)
for l in [0,1,2,3,2,1,0]:
levels[l].high()
sleep(speed)
levels[l].low()
allOff()
def areaOn(number):
lev(True)
col(True)
for a in range(4):
columns[a+(number%4)*4].low()
def cycleAreas(speed):
for a in [0,1,2,3,2,1,0]:
areaOn(a)
sleep(speed)
allOff()
def sliceOn(number):
lev(True)
col(True)
for c in [0,4,8,12]:
columns[c+number%4].low()
def cycleSlices(speed):
for s in [0,1,2,3,2,1,0]:
sliceOn(s)
sleep(speed)
allOff()
def blockOn(number):
allOff()
for r in [0,1,4,5]:
rowOn(r+number+number//3)
def cycleBlocks(speed):
allOff()
for b in [0,1,2,5,4,3,6,7,8,5,2,1,0,3,6,4]:
blockOn(b)
sleep(speed)
def cubeOn(number):
allOff()
for l in [0,1]:
levels[l+number//9].high()
for c in [0,1,4,5]:
n = number%9
columns[c+n+n//3].low()
def cyclyCube(speed):
for c in [0,1,2,5,4,3,6,7,8,17,16,15,12,13,14,11,10,9,18,19,20,23,22,21,24,25,26,23,14,13]:
cubeOn(c)
sleep(speed)
def explode(times, speed):
for n in range(times):
allOff()
sleep(speed)
cubeOn(13)
sleep(speed)
allOn()
sleep(speed)
def show():
cycleSingle(0.1)
cycleCols(0.2)
cycleRows(0.2)
cycleLines(0.2)
cycleLevels(0.2)
cycleAreas(0.2)
cycleSlices(0.2)
cyclyCube(0.2)
cycleBlocks(0.2)
explode(3, 0.2)
blinkAll(3, 0.5)
show()
Uns so sieht das dann aus:

