Guide · 20 min di lettura

Cubo LED Arduino: come costruire un cubo 3x3x3 e 4x4x4 con codice

Cubo LED con Arduino: dima per saldatura, montaggio 3x3x3 e 4x4x4, strati pilotati da transistor, calcolo delle resistenze, 74HC595 e codice delle animazioni.

Un cubo LED è uno dei progetti luminosi più spettacolari che puoi realizzare con Arduino: i LED, disposti in una griglia tridimensionale, si accendono strato dopo strato e disegnano piani che ruotano, gocce di pioggia che cadono e cubi che crescono e si rimpiccioliscono a mezz'aria. Per il tuo primo cubo LED con Arduino conviene partire da un 3x3x3 (27 LED) o da un 4x4x4 (64 LED); a queste dimensioni bastano i pin di un Arduino Uno, qualche transistor e un po' di pazienza con il saldatore. Il trucco è non dare un pin a ogni LED, ma usare il multiplexing a strati e colonne: controlli 27 LED con 12 pin e 64 LED con soli 7 pin grazie a due chip 74HC595.

In questa guida imparerai come funziona un cubo LED, come preparare una dima per saldatura, come unire gli strati passo dopo passo, perché gli strati vanno pilotati con i transistor e come si calcolano le resistenze. Poi troverai il codice Arduino che riproduce animazioni basate su array su un cubo 3x3x3, come passare a un cubo 4x4x4 con il 74HC595, le versioni per ESP32 e Raspberry Pi Pico (MicroPython), l'alternativa WS2812B per un cubo a colori e le soluzioni agli errori di montaggio più comuni, come un LED montato al contrario o una saldatura fredda.

LED da 5 mm per un cubo LED
Il mattone di base di un cubo LED è il LED da 5 mm: il terminale lungo è l'anodo (+), quello corto e il lato piatto del corpo indicano il catodo (−).

Che cos'è un cubo LED e come funziona?

Un cubo LED si ottiene impilando strati orizzontali di LED disposti alla stessa distanza. In ogni strato i terminali di catodo (−) di tutti i LED vengono saldati insieme, così ogni strato ha un'unica linea di catodo comune. I terminali di anodo (+) dei LED posti uno sopra l'altro vengono saldati in verticale e formano le colonne. Un cubo 3x3x3 ha 3 strati e 9 colonne, un cubo 4x4x4 ha 4 strati e 16 colonne. Ogni LED si trova esattamente all'incrocio tra uno strato e una colonna: per accendere un LED dai una tensione positiva alla sua colonna e colleghi il suo strato a GND.

Puoi individuare ogni LED del cubo con tre coordinate: x (da sinistra a destra), y (dal davanti verso il retro) e z (dal basso verso l'alto). Nel codice di questo articolo il numero di colonna si calcola con c = y × 3 + x (nel 4x4x4 c = y × 4 + x), mentre z è il numero dello strato. Come un pixel su uno schermo, un singolo punto luminoso del cubo si chiama voxel (pixel di volume). Creare un'animazione significa in pratica decidere quali voxel si accendono e in quale momento.

Come funziona il multiplexing a strati e colonne?

Se accendi più strati contemporaneamente, la tensione positiva su una colonna accende un LED in ogni strato attivo di quella colonna, quindi non riesci a disegnare la figura che vuoi. Per questo il cubo viene scansionato strato per strato: Arduino spegne prima tutti gli strati, scrive sui pin la configurazione delle colonne del primo strato, accende solo quello strato per qualche millisecondo, poi lo spegne e passa al secondo. Quando questo ciclo si ripete più di cento volte al secondo, l'occhio trattiene la luce per un attimo (persistenza della visione) e vedi tutti gli strati accesi nello stesso momento.

Calcolare la velocità di scansione è semplice: frequenza di aggiornamento = 1 / (numero di strati × tempo per strato). Se in un cubo 3x3x3 tieni acceso ogni strato per 3 ms, un giro dura 9 ms e il cubo si aggiorna circa 110 volte al secondo. In un 4x4x4 con 2 ms per strato, il giro dura 8 ms e la frequenza è di 125 Hz. Sotto i 50–60 Hz l'occhio nota lo sfarfallio; sopra i 100 Hz appare del tutto stabile a occhio nudo e le bande nei video del telefono si riducono. Il prezzo da pagare è la luminosità: dato che ogni strato è acceso solo per 1/3 del tempo (1/4 nel 4x4x4), la corrente media di un LED scende a quella frazione della sua corrente istantanea.

CuboLEDColonne + stratiPin con pilotaggio direttoPin con 74HC595Pin senza multiplexing
3x3x3279 + 3123 + 3 = 627
4x4x46416 + 4203 + 4 = 764
5x5x512525 + 5303 + 5 = 8125
8x8x851264 + 8723 + 8 = 11512

Lista dei materiali

MaterialeCubo 3x3x3Cubo 4x4x4 (con 74HC595)
LED da 5 mm (un solo colore, meglio se diffuso)27 + 3 di scorta64 + 6 di scorta
Resistenza di colonna9 × 220 Ω16 × 330 Ω (blu, bianco) o 470 Ω (rosso, giallo)
Transistor NPN (strato)3 × 2N2222A o BC3374 × 2N2222A o BC337
Resistenza di base3 × 470 Ω4 × 470 Ω
Shift registerNon serve2 × 74HC595 (74HCT595 per ESP32 e Pico) + 100 nF ciascuno
Scheda di controlloArduino Uno o NanoArduino Uno, Nano, ESP32 o Pico
MontaggioBasetta millefori, filo rigido sottileBasetta millefori, filo di rame stagnato da 0,5–0,8 mm
AttrezziSaldatore, stagno, tronchesino, pinze, punta da 5 mmGli stessi attrezzi + distanziali di uguale altezza
Arduino Uno
Arduino Uno
220 Ω
220 Ω
Breadboard
Breadboard
Jumper
Jumper

Preparare la dima per saldatura

Il segreto di un cubo ben fatto è la dima. Se saldi i LED tenendoli in mano, le distanze si spostano, gli strati vengono storti e il cubo sembra deformato. La dima è un pezzo di legno con fori equidistanti in cui i LED si appoggiano capovolti, con la cupola verso il basso. La distanza dipende dalla lunghezza del terminale di catodo: nella maggior parte dei LED da 5 mm il terminale corto misura circa 25 mm, ma misura i tuoi LED con un righello. Quando pieghi il terminale a 90° a 2–3 mm dal corpo, il tratto orizzontale che resta deve sovrapporsi di 2–3 mm al terminale del LED vicino; per questo una distanza di 20 mm è un buon punto di partenza.

  1. Disegna con un righello una griglia 3x3 (o 4x4) su compensato, MDF o cartone spesso, con 20 mm tra i punti e almeno 2 cm di margine dai bordi.
  2. Segna prima ogni punto con un chiodo, poi foralo ben dritto con una punta da 5 mm. Il LED deve restare fermo nel foro ma uscire senza forzare; se è troppo stretto, allarga leggermente il foro.
  3. Disegna su un bordo della dima una freccia che indichi la direzione del catodo; il terminale corto di tutti i LED punterà dalla stessa parte.
  4. Prepara quattro distanziali della stessa altezza, adatti alla distanza tra gli strati, che reggano lo strato superiore mentre unisci gli strati; vanno bene ritagli di listello di legno o cartone piegato.
Prima di saldare, prova i LED uno per uno: basta appoggiare il terminale lungo sul polo positivo e quello corto sul negativo di una batteria a bottone CR2032 da 3 V. Anche la prova diodi del multimetro accende debolmente un LED. Dissaldare un LED guasto dal centro di un cubo è difficilissimo. Per un bell'effetto scegli LED diffusi; i LED trasparenti concentrano la luce in una sola direzione, quindi il cubo, guardato di lato, brilla in modo irregolare. Puoi opacizzare la cupola dei LED trasparenti con una carta abrasiva fine.

Montaggio passo dopo passo: strati e colonne

  1. Piega i terminali: Piega a 90° in orizzontale il terminale corto (catodo) di ogni LED, a 2–3 mm dal corpo, verso la freccia della dima. Il terminale lungo (anodo) resta verticale.
  2. Disponi il primo strato: Inserisci i LED nei fori con la cupola verso il basso. Ogni terminale di catodo di una fila deve toccare quello del LED successivo; il terminale dell'ultimo LED della fila può restare libero.
  3. Salda i catodi: Salda ogni punto di contatto in 2–3 secondi al massimo, con il saldatore a 320–350 °C. Poi salda un filo dritto (un terminale di resistenza tagliato o filo di rame stagnato) di traverso sulle estremità delle file per unirle. Così lo strato diventa sia un'unica linea elettrica sia un telaio robusto; nel 4x4x4, un filo a entrambe le estremità lo rende ancora più solido.
  4. Prova lo strato: Senza togliere lo strato dalla dima, collega la linea di catodo a GND e tocca ogni terminale di anodo con 5 V attraverso una resistenza da 220 Ω. Se un LED non si accende, sostituiscilo adesso.
  5. Prepara gli altri strati: Ripeti il procedimento fino ad avere 3 (o 4) strati. Tieni i terminali di catodo rivolti dalla stessa parte in ogni strato, così le colonne cadranno esattamente una sopra l'altra.
  6. Unisci gli strati: Lascia uno strato nella dima e allinea il successivo proprio sopra, appoggiato sui distanziali. Fai una piccola piega di 2 mm in punta a ogni terminale di anodo rivolto verso l'alto dei LED sottostanti, in modo che passi accanto al corpo del LED superiore e si appoggi al suo terminale di anodo. Salda prima i quattro angoli, controlla l'allineamento e poi completa le altre colonne.
  7. Porta fuori i fili degli strati: Salda un filo alla linea di catodo di ogni strato e fallo scendere lungo un lato del cubo. Questi fili non devono toccarsi tra loro né toccare le colonne; lascia qualche millimetro di spazio.
  8. Monta il cubo sulla base: Capovolgi il cubo; i terminali di anodo liberi dell'ultimo strato aggiunto ora puntano verso il basso, e quello strato diventa il più vicino alla base, cioè lo strato inferiore (z = 0). Infila terminali e fili degli strati in una basetta millefori, saldali e metti le resistenze di colonna accanto a ogni colonna.
L'errore di montaggio più costoso è un solo LED montato al contrario. Non si limita a restare spento: quando un pin di colonna è LOW, apre un percorso di corrente inversa dalla linea dello strato verso quella colonna, e su strati che dovrebbero essere spenti possono accendersi LED fantasma. Ogni volta che metti un LED nella dima controlla che il terminale corto (il lato piatto del corpo) punti verso la freccia, e prova sempre ogni strato prima di unirlo agli altri.

Pilotare gli strati con i transistor

Transistor NPN
La corrente dello strato la porta un transistor NPN, non il pin di Arduino: il 2N2222A (E-B-C) o il BC337 (C-B-E) sono ottime scelte.

Un pin di colonna alimenta un solo LED, ma quando uno strato è acceso la corrente di tutti i suoi LED torna a GND attraverso la stessa linea di catodo. In un cubo 3x3x3 sono 9 LED × 12,7 mA ≈ 115 mA, nel cubo 4x4x4 con 74HC595 16 LED × 5 mA ≈ 80 mA. Il limite consigliato per un pin di Arduino Uno è 20 mA e il massimo assoluto 40 mA, quindi non puoi collegare una linea di strato direttamente a un pin. La soluzione è un transistor NPN sotto ogni strato: il collettore va alla linea dello strato, l'emettitore a GND e la base a un pin di Arduino tramite una resistenza. Quando il pin va HIGH, il transistor va in saturazione e porta lo strato a GND. Per far condurre del tutto il transistor, scegli una corrente di base pari a circa 1/10–1/20 della corrente di collettore: per 115 mA servono 6–12 mA, e (5 V − 0,7 V) / 470 Ω ≈ 9 mA cade proprio in questo intervallo. Trovi i dettagli in Che cos'è un transistor? e le piedinature nello strumento transistor.

TransistorIC continuaOrdine dei piedini (lato scritto davanti)Uso nel cubo LED
BC547100 mAC-B-ESolo per cubi a bassa corrente; i 115 mA di un 3x3x3 superano il suo limite
2N2222A600 mAE-B-CIdeale per 3x3x3 e 4x4x4
BC337800 mAC-B-EIdeale per 3x3x3 e 4x4x4
IRLZ44N (MOSFET logic level)Decine di ampereG-D-SCubi grandi come l'8x8x8; 220 Ω sul gate, 10 kΩ tra gate e GND

Calcolo delle resistenze: di colonna e di base

La resistenza di colonna è l'unico componente che limita la corrente del LED, e ce n'è una per colonna; non serve una resistenza per ogni LED, perché in una colonna si accende un solo LED alla volta. La formula deriva dalla legge di Ohm: R = (Valimentazione − VLED − VCE(sat)) / ILED. Con un'alimentazione di 5 V, un LED rosso con tensione diretta di 2,0 V e un transistor che in saturazione fa cadere circa 0,2 V, puntando a 12 mA ottieni R = (5 − 2,0 − 0,2) / 0,012 ≈ 233 Ω. Il valore standard più vicino, 220 Ω, fa passare circa 12,7 mA nel LED. Con un LED blu da 3,1 V, gli stessi 220 Ω danno circa 7,7 mA, una luminosità ancora ben visibile in multiplexing.

Colore del LEDTensione diretta (VF)3x3x3, diretto da Arduino (5 V)4x4x4, 74HC595 (5 V)
Rosso, giallo1,8–2,2 V220 Ω (≈12–13 mA)470 Ω (≈5–6 mA)
Verde puro, blu2,9–3,3 V180–220 Ω (≈8–9 mA)330 Ω (≈4–5 mA)
Bianco2,9–3,4 V180–220 Ω (≈7–9 mA)330 Ω (≈4–5 mA)

Nel cubo con 74HC595 scegliamo di proposito resistenze più grandi: attraverso il pin VCC o GND di questo chip possono passare al massimo 70 mA in totale, e con uno strato acceso tutte e otto le uscite possono essere accese insieme. 8 × 5,5 mA ≈ 44 mA lasciano un margine sicuro. La corrente media del LED, che determina la luminosità percepita, è la corrente istantanea divisa per il numero di strati: 12,7 / 3 ≈ 4,2 mA nel 3x3x3 e 5,5 / 4 ≈ 1,4 mA nel 4x4x4. I LED efficienti di oggi si vedono bene al chiuso con queste correnti, ma in una stanza molto luminosa un cubo 4x4x4 può sembrare un po' spento. Per calcolare con i valori del tuo LED usa gli strumenti resistenza per LED e tensioni dei LED.

Schema di collegamento del cubo LED 3x3x3

CollegamentoArduino Uno / NanoNota
Colonne 0–8 (anodi)D2–D10Resistenza in serie da 220 Ω su ogni colonna
Strato inferiore (z = 0)A0Alla base del transistor 1 tramite 470 Ω
Strato centrale (z = 1)A1Alla base del transistor 2 tramite 470 Ω
Strato superiore (z = 2)A2Alla base del transistor 3 tramite 470 Ω
Collettori dei transistor—Ciascuno al filo di catodo del proprio strato
Emettitori dei transistorGNDTutti e tre a un GND comune
Vista dall'altox = 0x = 1x = 2
y = 2 (dietro)Colonna 6 → D8Colonna 7 → D9Colonna 8 → D10
y = 1 (centro)Colonna 3 → D5Colonna 4 → D6Colonna 5 → D7
y = 0 (davanti)Colonna 0 → D2Colonna 1 → D3Colonna 2 → D4
Non usare D0 e D1 per le colonne: questi pin sono condivisi con il caricamento via USB e con il Monitor seriale, e i LED collegati possono far fallire il caricamento. Per questo il cubo 3x3x3 usa D2–D10 e A0–A2; i pin A0–A5 funzionano come normali uscite digitali con digitalWrite(). Anche la corrente totale resta nei limiti: quando tutte e nove le colonne assorbono 12,7 mA, da Arduino escono circa 115 mA, sotto il limite totale di 200 mA dell'ATmega328P. Puoi vedere dove si trovano i pin sulla scheda con lo strumento pinout.

Codice Arduino per il cubo LED 3x3x3: animazioni con gli array

Ogni fotogramma dell'animazione è memorizzato come un numero per strato. Uno strato 3x3x3 ha 9 LED, quindi basta un valore a 9 bit; lo memorizziamo in un uint16_t e il bit c rappresenta la colonna c. I fotogrammi finiscono nella memoria flash con PROGMEM, così anche animazioni con centinaia di fotogrammi non riempiono i 2 KB di RAM dell'Uno. Il codice qui sotto non richiede librerie aggiuntive.

C++ (Arduino IDE)
1// 3x3x3 LED küp: katman çoklama ve dizilerle animasyon / 3x3x3 LED cube: layer multiplexing and array animations
2const byte colPins[9]   = {2, 3, 4, 5, 6, 7, 8, 9, 10};   // sütun anotları, 220 ohm ile / column anodes via 220 ohm
3const byte layerPins[3] = {A0, A1, A2};                     // alt, orta, üst katman transistörü / bottom, middle, top layer transistor
4
5// Her kare 3 katman, her katman 9 bit: bit c = sütun c (c = y*3 + x)
6// Each frame has 3 layers of 9 bits: bit c = column c (c = y*3 + x)
7const uint16_t frames[][3] PROGMEM = {
8  {0b111111111, 0b000000000, 0b000000000},  // 0: alt katman / bottom layer
9  {0b000000000, 0b111111111, 0b000000000},  // 1: orta katman / middle layer
10  {0b000000000, 0b000000000, 0b111111111},  // 2: üst katman / top layer
11  {0b000000000, 0b000010000, 0b000000000},  // 3: yalnız merkez / centre only
12  {0b111101111, 0b101000101, 0b111101111},  // 4: tel kafes, 12 kenar / wireframe, 12 edges
13  {0b010010010, 0b010010010, 0b010010010},  // 5: dönen düzlem, 1. konum / rotating plane, step 1
14  {0b100010001, 0b100010001, 0b100010001},  // 6: dönen düzlem, 2. konum / rotating plane, step 2
15  {0b000111000, 0b000111000, 0b000111000},  // 7: dönen düzlem, 3. konum / rotating plane, step 3
16  {0b001010100, 0b001010100, 0b001010100},  // 8: dönen düzlem, 4. konum / rotating plane, step 4
17  {0b111111111, 0b111111111, 0b111111111}   // 9: hepsi açık / all on
18};
19
20void setup() {
21  for (byte c = 0; c < 9; c++) pinMode(colPins[c], OUTPUT);
22  for (byte z = 0; z < 3; z++) pinMode(layerPins[z], OUTPUT);  // LOW: katmanlar kapalı / LOW: layers off
23}
24
25// Bir kareyi verilen süre boyunca katman katman tarar / scans one frame layer by layer for the given time
26void showFrame(byte f, unsigned int ms) {
27  unsigned long start = millis();
28  while (millis() - start < ms) {
29    for (byte z = 0; z < 3; z++) {
30      uint16_t bits = pgm_read_word(&frames[f][z]);         // katman verisini oku / read the layer data
31      for (byte c = 0; c < 9; c++) digitalWrite(colPins[c], bitRead(bits, c));
32      digitalWrite(layerPins[z], HIGH);                      // katmanı aç / layer on
33      delay(3);                                              // 3 ms göster / show for 3 ms
34      digitalWrite(layerPins[z], LOW);                       // sütunlar değişmeden önce kapat / off before the columns change
35    }
36  }
37}
38
39void loop() {
40  for (byte f = 0; f <= 4; f++) showFrame(f, 500);           // katmanlar, merkez, kafes / layers, centre, wireframe
41  for (byte turn = 0; turn < 4; turn++)                      // düzlemi 4 tur döndür / spin the plane 4 times
42    for (byte f = 5; f <= 8; f++) showFrame(f, 120);
43  showFrame(9, 800);                                         // hepsi açık / all on
44}

Il cuore del codice è la funzione showFrame(). Per ogni strato scrive prima la configurazione delle colonne sui pin, poi accende solo il transistor di quello strato per 3 ms e spegne lo strato prima che le colonne cambino. Quest'ordine è importante: se cambi le colonne mentre uno strato è acceso, la figura dello strato precedente compare per un attimo sul nuovo strato e si crea l'effetto fantasma (ghosting). bitRead(bits, c) restituisce il bit c del numero come 0 o 1, mentre pgm_read_word() legge il valore a 16 bit dalla flash. loop() mostra prima gli strati uno alla volta, poi il centro e i 12 spigoli del cubo, quindi fa ruotare un piano verticale su quattro posizioni creando un effetto girandola.

Progettare le tue animazioni

Per disegnare un nuovo fotogramma, guarda il cubo dall'alto e immagina ogni strato come un foglio a quadretti 3x3. Segna le colonne da accendere e scrivi il numero binario dopo 0b da sinistra a destra, dal bit 8 al bit 0. Per esempio, i quattro angoli sono le colonne 0, 2, 6 e 8, cioè 0b101000101. Se scrivi lo stesso valore in tutti e tre gli strati ottieni barre verticali ai quattro angoli; se lo scrivi solo nello strato centrale, quattro punti sospesi a mezz'aria. Se i numeri binari ti sono nuovi, l'articolo Sistemi di numerazione e operazioni sui bit spiega il concetto nel dettaglio. Alcune tecniche utili quando scrivi il codice:

  • Scorrimento dei bit: Se sposti a sinistra il valore di uno strato di 3 bit nel 3x3x3 o di 4 bit nel 4x4x4, la figura arretra di una fila; eliminando con & i bit che escono ottieni onde e scritte scorrevoli.
  • Copia degli strati: Copiare l'array degli strati di un passo verso il basso o verso l'alto crea effetti di pioggia, bolle che salgono e ascensore.
  • Casualità: Voxel scelti con random() che lampeggiano per un istante creano un cielo stellato o un effetto scintilla.
  • Inversione: Con l'operatore ~ trasformi un fotogramma nel suo negativo, e alternando velocemente i due ottieni un lampeggio d'effetto.

Cubo LED 4x4x4: ingrandire con il 74HC595

Un cubo 4x4x4 ha 16 colonne e 4 strati; pilotarlo direttamente richiede 20 pin, cioè tutti i pin dell'Uno, compresi D0 e D1. Se invece piloti le colonne con due shift register 74HC595 in cascata, le 16 colonne costano solo 3 pin (dati, clock e latch); aggiungendo 4 pin per gli strati arrivi a 7 pin in tutto. L'uscita Q7' (pin 9) del primo chip va all'ingresso DS del secondo, mentre le linee di clock e di latch sono in comune tra i due chip. Le colonne 0–7 (le due file anteriori) si collegano alle uscite Q0–Q7 del primo chip, le colonne 8–15 (le due file posteriori) al secondo. Lo stesso metodo cresce fino a 4 chip per un cubo 5x5x5 e a 8 chip per un 8x8x8.

CollegamentoArduino UnoESP32Raspberry Pi Pico
DS (14), primo chipD11GPIO 23GP19
SH_CP (11), in comune ai due chipD13GPIO 18GP18
ST_CP (12), in comune ai due chipD10GPIO 5GP17
OE (13) / MR (10)GND / 5VGND / 5VGND / VBUS
VCC (16) / GND (8)5V / GND5V / GNDVBUS / GND
Q7' (9) → DS (14) del secondo chipCascataCascataCascata
Transistor degli strati 0–3 (tramite 470 Ω)D2, D3, D4, D5GPIO 25, 26, 27, 32GP10, GP11, GP12, GP13
Tipo di chip74HC59574HCT59574HCT595
Attraverso il pin VCC o GND del 74HC595 possono passare al massimo 70 mA in totale. Con resistenze piccole come 220 Ω, uno strato completamente acceso assorbe 80–100 mA per chip; il chip si scalda, la sua tensione d'uscita cala e alla lunga si guasta. Usa i valori da 330–470 Ω della tabella delle resistenze e metti un condensatore da 100 nF tra i pin VCC e GND di ogni chip, il più vicino possibile ai piedini.
C++ (Arduino IDE)
1// 4x4x4 LED küp: 2 adet 74HC595 (16 sütun) + 4 transistörlü katman / 4x4x4 LED cube: two 74HC595s (16 columns) + 4 transistor layers
2const byte DATA_PIN  = 11;                 // 74HC595 DS (14)
3const byte CLOCK_PIN = 13;                 // 74HC595 SH_CP (11)
4const byte LATCH_PIN = 10;                 // 74HC595 ST_CP (12)
5const byte layerPins[4] = {2, 3, 4, 5};    // alttan üste katman transistörleri, 470 ohm ile / layer transistors bottom to top, via 470 ohm
6
7uint16_t cube[4];                          // ekrandaki görüntü: katman başına 16 bit / current image: 16 bits per layer
8
9// Hazır kareler: bit c = sütun c (c = y*4 + x) / ready-made frames: bit c = column c (c = y*4 + x)
10const uint16_t frames[][4] PROGMEM = {
11  {0xFFFF, 0x0000, 0x0000, 0x0000},        // alt katman / bottom layer
12  {0x0000, 0xFFFF, 0x0000, 0x0000},
13  {0x0000, 0x0000, 0xFFFF, 0x0000},
14  {0x0000, 0x0000, 0x0000, 0xFFFF},        // üst katman / top layer
15  {0x9009, 0x0000, 0x0000, 0x9009},        // 8 köşe / 8 corners
16  {0xF99F, 0x9009, 0x9009, 0xF99F},        // tel kafes / wireframe
17  {0x0000, 0x0660, 0x0660, 0x0000}         // içteki 2x2x2 küp / inner 2x2x2 cube
18};
19const byte FRAME_COUNT = sizeof(frames) / sizeof(frames[0]);
20
21void write16(uint16_t v) {                 // 16 biti iki entegreye gönder / send 16 bits to both chips
22  digitalWrite(LATCH_PIN, LOW);
23  shiftOut(DATA_PIN, CLOCK_PIN, MSBFIRST, highByte(v));  // önce uzaktaki entegre / far chip first
24  shiftOut(DATA_PIN, CLOCK_PIN, MSBFIRST, lowByte(v));
25  digitalWrite(LATCH_PIN, HIGH);           // çıkışlara aktar / copy to the outputs
26}
27
28void refresh() {                           // her 2 ms'de sıradaki katmana geç / move to the next layer every 2 ms
29  static byte z = 0;
30  static unsigned long last = 0;
31  if (micros() - last < 2000) return;
32  last = micros();
33  digitalWrite(layerPins[z], LOW);         // eski katmanı kapat / old layer off
34  z = (z + 1) % 4;
35  write16(cube[z]);                        // yeni katmanın sütunları / columns of the new layer
36  digitalWrite(layerPins[z], HIGH);        // yeni katmanı aç / new layer on
37}
38
39void holdFor(unsigned int ms) {            // beklerken küpü yenilemeye devam et / keep refreshing while waiting
40  unsigned long start = millis();
41  while (millis() - start < ms) refresh();
42}
43
44void clearCube() {
45  for (byte z = 0; z < 4; z++) cube[z] = 0;
46}
47
48void setVoxel(byte x, byte y, byte z) {    // tek LED yak, x/y/z = 0..3 / light one LED, x/y/z = 0..3
49  bitSet(cube[z], y * 4 + x);
50}
51
52void loadFrame(byte f) {                   // PROGMEM'deki kareyi yükle / load a frame from PROGMEM
53  for (byte z = 0; z < 4; z++) cube[z] = pgm_read_word(&frames[f][z]);
54}
55
56void sweep() {                             // dikey düzlemi x ekseninde kaydır / sweep a vertical plane along x
57  for (byte x = 0; x < 4; x++) {
58    clearCube();
59    for (byte y = 0; y < 4; y++)
60      for (byte z = 0; z < 4; z++) setVoxel(x, y, z);
61    holdFor(150);
62  }
63}
64
65void rain(byte steps) {                    // yağmur: damlalar yukarıdan düşer / rain: drops fall from the top
66  clearCube();
67  for (byte s = 0; s < steps; s++) {
68    for (byte z = 0; z < 3; z++) cube[z] = cube[z + 1];   // her şeyi bir kat indir / move everything down a layer
69    cube[3] = bit(random(16)) | bit(random(16));         // üstte 1-2 yeni damla / 1-2 new drops on top
70    holdFor(120);
71  }
72}
73
74void setup() {
75  pinMode(DATA_PIN, OUTPUT);
76  pinMode(CLOCK_PIN, OUTPUT);
77  pinMode(LATCH_PIN, OUTPUT);
78  for (byte z = 0; z < 4; z++) pinMode(layerPins[z], OUTPUT);
79  randomSeed(analogRead(A0));              // boştaki A0'dan rastgele tohum / random seed from the unconnected A0
80}
81
82void loop() {
83  for (byte f = 0; f < FRAME_COUNT; f++) {
84    loadFrame(f);
85    holdFor(500);
86  }
87  for (byte i = 0; i < 3; i++) sweep();
88  rain(80);
89}

In questa versione la scansione avviene nella funzione refresh() in modo non bloccante: a ogni chiamata controlla con micros() se sono passati 2 ms; in caso affermativo spegne lo strato precedente, invia i 16 bit del nuovo strato ai due chip e accende il nuovo strato. In questo modo il codice delle animazioni modifica solo l'array cube[] e non deve occuparsi dell'aggiornamento. holdFor() continua a chiamare refresh() mentre aspetta, quindi non dovresti usare un delay() lungo in nessun punto del programma. setVoxel(x, y, z) ti permette di accendere un singolo LED tramite le coordinate; sweep() lo usa per far scorrere un piano verticale attraverso il cubo, mentre rain() copia gli strati di un passo verso il basso e aggiunge gocce casuali in cima. La differenza tra delay() e millis() la trovi in millis() e delay(), mentre come spostare la scansione in un interrupt del timer lo trovi in Gli interrupt di Arduino.

Cubo LED con ESP32

I pin dell'ESP32 forniscono 3,3 V. Non bastano per pilotare direttamente i LED blu e bianchi, la cui tensione diretta è di circa 3 V; dopo la caduta sulla resistenza e sul transistor non resta quasi nulla. Per questo con l'ESP32 la soluzione più pulita è pilotare le colonne tramite un 74HCT595 alimentato a 5 V: la famiglia HCT considera HIGH anche 2 V, quindi legge senza problemi i segnali a 3,3 V, mentre i LED sono alimentati a 5 V. Sulla base dei transistor di strato tieni sempre 470 Ω; (3,3 − 0,7) / 470 ≈ 5,5 mA bastano per una corrente di strato di 80 mA. Il codice 4x4x4 qui sopra si compila così com'è sull'ESP32; devi solo sostituire le costanti dei pin con i valori della tabella (23, 18, 5 e 25, 26, 27, 32). Se vuoi, puoi anche usare il Wi-Fi dell'ESP32 per scegliere le animazioni da una pagina web sul telefono; per iniziare, leggi Che cos'è l'ESP32?.

Cubo LED con Raspberry Pi Pico e MicroPython

Anche il Pico è una scheda a 3,3 V e, con l'impostazione predefinita, i suoi pin erogano solo pochi milliampere, quindi usi lo stesso circuito con il 74HCT595. Alimenta chip e LED da VBUS (pin 40), che porta i 5 V della USB. In MicroPython i 16 bit vengono inviati tramite SPI hardware: i pin GP18 (SCK) e GP19 (MOSI) di SPI0 pilotano clock e dati, mentre GP17 pilota il latch. Il codice segue la stessa logica: show() scansiona un fotogramma strato per strato per il tempo indicato, e nell'effetto pioggia lo slicing della lista (cube[1:]) fa scendere ogni strato di un passo. Per l'installazione e i primi passi, leggi Che cos'è il Raspberry Pi Pico?.

MicroPython
1# Pico + 2 adet 74HCT595 ile 4x4x4 LED küp / 4x4x4 LED cube with a Pico + two 74HCT595s
2from machine import Pin, SPI
3import time
4import random
5
6# GP18 = SCK -> SH_CP, GP19 = MOSI -> DS; GP16 (MISO) boş kalır / GP16 (MISO) stays unconnected
7spi = SPI(0, baudrate=1000000, polarity=0, phase=0, sck=Pin(18), mosi=Pin(19))
8latch = Pin(17, Pin.OUT, value=0)                                # ST_CP
9layers = [Pin(n, Pin.OUT, value=0) for n in (10, 11, 12, 13)]    # alttan üste, 470 ohm ile / bottom to top, via 470 ohm
10
11def write16(v):
12    latch.value(0)
13    spi.write(bytes((v >> 8, v & 0xFF)))    # önce uzaktaki entegre / far chip first
14    latch.value(1)                          # çıkışlara aktar / copy to the outputs
15
16def show(frame, ms):
17    # kareyi ms boyunca katman katman tara / scan the frame layer by layer for ms
18    end = time.ticks_add(time.ticks_ms(), ms)
19    while time.ticks_diff(end, time.ticks_ms()) > 0:
20        for z in range(4):
21            write16(frame[z])
22            layers[z].value(1)              # katmanı aç / layer on
23            time.sleep_us(2000)
24            layers[z].value(0)              # sütunlar değişmeden kapat / off before the columns change
25
26FRAMES = [
27    [0x9009, 0x0000, 0x0000, 0x9009],       # 8 köşe / 8 corners
28    [0xF99F, 0x9009, 0x9009, 0xF99F],       # tel kafes / wireframe
29    [0x0000, 0x0660, 0x0660, 0x0000],       # içteki küp / inner cube
30]
31
32while True:
33    for f in FRAMES:
34        show(f, 600)
35    cube = [0, 0, 0, 0]
36    for _ in range(60):                     # yağmur: her şey bir kat iner / rain: everything drops a layer
37        drop = (1 << random.getrandbits(4)) | (1 << random.getrandbits(4))
38        cube = cube[1:] + [drop]
39        show(cube, 120)

Cubi più grandi: 5x5x5 e 8x8x8

Man mano che il cubo cresce, crescono anche due problemi. Il primo è la corrente: un cubo 8x8x8 ha 64 LED per strato e, con 10 mA per LED, la corrente di strato arriva a 640 mA; non è più un lavoro per un piccolo transistor TO-92, ma per un MOSFET logic level. Il secondo è il tempo di scansione: per mantenere 100 Hz con 8 strati restano 1,25 ms per strato e per ognuno vanno inviati 64 bit (8 byte); shiftOut() è troppo lento e l'SPI hardware diventa indispensabile. Inoltre ogni LED è acceso solo per 1/8 del tempo, quindi la luminosità cala; i cubi grandi richiedono driver di colonna più potenti e un alimentatore esterno da 5 V al posto della USB (vedi Come alimentare Arduino). Per questo il tuo primo cubo dovrebbe essere un 3x3x3 o un 4x4x4: padroneggerai la tecnica prima di saldare 512 LED.

Alternativa: cubo LED a colori con WS2812B

LED RGB indirizzabile WS2812B
Ogni LED WS2812B ha il proprio chip di controllo; un cubo da 64 LED si comanda da un unico pin dati.

Se invece di un cubo monocolore preferisci scegliere il colore di ogni LED singolarmente, puoi usare LED indirizzabili come il WS2812B. Ognuno di questi LED ha il proprio chip di controllo, quindi non servono multiplexing, transistor né resistenze di colonna: i 64 LED si collegano in catena con 5 V, GND e una linea dati e si pilotano da un unico pin. Per un cubo si usano LED indirizzabili da 5 mm a 4 piedini (come PL9823 o APA106) oppure pezzi tagliati da una striscia WS2812B. Il prezzo da pagare è la corrente: circa 60 mA per LED a bianco pieno, cioè 3,8 A per 64 LED. Usa quindi un alimentatore da 5 V e 4 A, aggiungi un condensatore da 1000 µF sull'alimentazione e una resistenza da 330 Ω sulla linea dati, e limita la luminosità via software. Il codice usa la libreria Adafruit NeoPixel.

C++ (Arduino IDE)
1// WS2812B ile 4x4x4 RGB LED küp / 4x4x4 RGB LED cube with WS2812B
2#include <Adafruit_NeoPixel.h>
3
4const byte DATA_PIN = 6;                   // 330 ohm ile ilk LED'in DIN ucuna / to the first LED's DIN via 330 ohm
5const byte N = 4;
6Adafruit_NeoPixel cube(N * N * N, DATA_PIN, NEO_GRB + NEO_KHZ800);
7
8uint16_t idx(byte x, byte y, byte z) {     // koordinattan zincirdeki sıraya / coordinate to position in the chain
9  return z * 16 + y * 4 + x;               // düz (zikzaksız) kablolama varsayılır / assumes straight, non-zigzag wiring
10}
11
12void setup() {
13  cube.begin();
14  cube.setBrightness(40);                  // parlaklığı ve akımı sınırla (0-255) / limit brightness and current (0-255)
15}
16
17void loop() {
18  static uint16_t hue = 0;
19  for (byte z = 0; z < N; z++)
20    for (byte y = 0; y < N; y++)
21      for (byte x = 0; x < N; x++)         // her katman farklı tonda / each layer gets a different hue
22        cube.setPixelColor(idx(x, y, z), cube.gamma32(cube.ColorHSV(hue + z * 8192U)));
23  cube.show();
24  hue += 256;                              // gökkuşağını kaydır / shift the rainbow
25  delay(20);
26}

La funzione idx() del codice converte una coordinata x, y, z nella posizione all'interno della catena e presuppone che tu abbia cablato ogni fila nello stesso verso. Se hai fatto il cablaggio a zigzag, nelle file dispari devi usare 3 − x al posto di x. Alcuni LED indirizzabili da 5 mm si aspettano i colori in ordine RGB; se vedi verde invece di rosso, cambia NEO_GRB in NEO_RGB. setBrightness(40) riduce la luminosità a circa il 16 %, così anche nel caso peggiore la corrente resta intorno a 0,6 A.

CaratteristicaCubo LED monocoloreCubo LED WS2812B
ColoreUno solo (quello del LED)16 milioni di colori, LED per LED
Pin usati (4x4x4)7 (con 74HC595)1
Componenti aggiuntiviTransistor, resistenze, 74HC595Condensatore, resistenza sulla linea dati, alimentatore potente
Lavoro di saldatura2 piedini per LED4 piedini per LED, più fili
Controllo della luminositàAcceso/spento (PWM per singolo LED difficile)256 livelli per ogni LED
Corrente (4x4x4)Circa 100 mA, basta la USBFino a ≈3,8 A, alimentazione esterna obbligatoria
Cosa insegnaMultiplexing, transistor, operazioni sui bitIndirizzamento, tonalità, gestione dell'energia

Idee di progetti con il cubo LED

  • Cubo che balla con la musica: Aumenta il numero di strati accesi in base al livello sonoro misurato con un sensore di suono per creare un equalizzatore tridimensionale.
  • Snake in 3D: Guida il serpente lungo i tre assi di un cubo 4x4x4 con un joystick e un pulsante; per altre idee di giochi, leggi Progetti di giochi con Arduino.
  • Cubo dado: Premendo un pulsante, i voxel si mescolano velocemente e il cubo mostra un numero da 1 a 6 con uno schema di punti.
  • Progetto per la fiera della scienza: Spiega la persistenza della visione allungando il tempo per strato con un potenziometro e mostrando il momento in cui inizia lo sfarfallio; per altre idee, leggi Idee per progetti scientifici.
  • Scegliere l'animazione dal telefono: Ogni lettera inviata con un modulo Bluetooth HC-05 avvia un'animazione diversa.
  • Luce notturna colorata: Imposta lente sfumature di colore su un cubo WS2812B; se usi un ESP32, controlla gli effetti dal telefono con WLED.

Errori comuni e soluzioni

SintomoCausa probabileSoluzione
Un singolo LED non si accende maiLED al contrario o guasto, oppure saldatura di un terminale rottaControlla il verso del catodo, prova il LED con una batteria a bottone e sostituiscilo se serve
LED che dovrebbero essere spenti brillano debolmente (fantasma)Le colonne cambiano mentre uno strato è acceso, oppure nel cubo c'è un LED al contrarioSpegni prima lo strato, poi scrivi le colonne; se il codice è corretto, cerca il LED al contrario
I LED sfarfallano o si spengono quando tocchi il cuboSaldatura fredda: un giunto opaco, granuloso, a forma di pallinaRiscalda il giunto con la punta del saldatore pulita e aggiungi un po' di stagno nuovo
Un intero strato resta spentoPiedini del transistor invertiti (E-B-C confuso con C-B-E) o resistenza di base scollegataVerifica l'ordine dei piedini nel datasheet e misura il collegamento della base
Un'intera colonna resta spentaLa colonna non è saldata alla base, oppure la resistenza o il pin sono sbagliatiMisura la colonna da un capo all'altro con il multimetro e controlla l'array dei pin nel codice
Il cubo sfarfallaTempo per strato troppo lungo, oppure Serial.print() o delay() nel ciclo di scansioneImposta il tempo per strato a 2–3 ms ed elimina il codice che blocca la scansione
Il cubo è molto fiocoResistenze troppo grandi, LED blu pilotati a 3,3 V o troppi stratiRicalcola la resistenza; sulle schede a 3,3 V alimenta il 74HCT595 a 5 V
Lo sketch non si caricaUn LED è collegato a D0 o D1Fai partire le colonne da D2 oppure scollega quei fili durante il caricamento
Il modo migliore per cercare i guasti è scansionare il cubo con uno sketch di prova: scrivi un piccolo ciclo che accende ogni LED a turno per 200 ms. Un LED che resta spento o si accende nel punto sbagliato rivela subito un giunto rotto o una colonna scambiata. Una saldatura fredda appare opaca e granulosa invece che lucida; una buona saldatura sembra un cono lucido e leggermente concavo che avvolge il terminale. Per ripassare la tecnica, dai un'occhiata a Come saldare.

Il cubo LED è uno dei pochi progetti che insegnano insieme saldatura, transistor, calcolo delle resistenze, multiplexing e operazioni sui bit. Inizia con un 3x3x3 e, quando codice e logica delle animazioni ti saranno chiari, passa a un 4x4x4 con il 74HC595, oppure ai WS2812B se vuoi il colore. Se prima preferisci provare l'idea di accendere i LED in sequenza su una semplice fila, effetto Supercar e LED in sequenza con Arduino è un ottimo riscaldamento. Nell'app BlueGrays trovi progetti di LED in sequenza, effetto Supercar, animazioni WS2812B e matrici LED con schemi di collegamento e codice passo dopo passo.

Domande frequenti

Quanti LED e quanti pin servono per un cubo LED?

Un cubo 3x3x3 richiede 27 LED e un cubo 4x4x4 ne richiede 64; conviene comprarne qualcuno di scorta. Con il multiplexing a strati e colonne, al 3x3x3 bastano 9 colonne e 3 strati, cioè 12 pin. Un 4x4x4 richiede 20 pin con il pilotaggio diretto, ma se piloti le colonne con due 74HC595 il totale scende a 7 pin.

Quale resistenza usare in un cubo LED?

Si mette una resistenza per colonna; in un cubo 3x3x3 pilotato direttamente da Arduino a 5 V, 220 Ω è un valore comune e sicuro. Nel cubo con 74HC595 usa 330 Ω per i LED blu e bianchi e 470 Ω per quelli rossi e gialli, così non superi il limite totale di 70 mA del chip. Per il tuo valore applica R = (Valimentazione − VLED − 0,2 V) / ILED.

Perché gli strati di un cubo LED si pilotano con i transistor?

Quando uno strato è acceso, la corrente di tutti i suoi LED torna a GND attraverso un'unica linea; in un cubo 3x3x3 supera i 100 mA. Dato che il limite consigliato di un pin di Arduino è 20 mA, la linea dello strato viene portata a GND da un transistor NPN come il 2N2222A o il BC337. Basta una resistenza di base da 470 Ω.

Perché il mio cubo LED sfarfalla?

Lo sfarfallio compare quando la velocità di scansione è troppo bassa. La frequenza di aggiornamento è 1 / (numero di strati × tempo per strato) e deve superare i 100 Hz, quindi tieni il tempo per strato a 2–3 ms e non mettere delay() lunghi o Serial.print() nel ciclo di scansione. Se il cubo sfarfalla solo quando lo tocchi, il problema è molto probabilmente una saldatura fredda.

Perché si accendono LED che dovrebbero essere spenti?

Si chiama effetto fantasma (ghosting) e ha due cause principali. Cambiare i valori delle colonne con uno strato acceso porta per un attimo la figura precedente sul nuovo strato; spegni prima lo strato e poi scrivi le colonne. Se il codice è corretto, un LED montato al contrario nel cubo potrebbe aprire un percorso di corrente verso altri strati.

Si può fare un cubo LED 8x8x8 con Arduino Uno?

Sì, ma i pin da soli non bastano: servono una catena di 74HC595 o driver simili per le 64 colonne, MOSFET logic level per gli 8 strati e SPI hardware per una scansione veloce. Saldare 512 LED richiede anche diversi giorni. La cosa migliore è padroneggiare prima la tecnica con un cubo 3x3x3 o 4x4x4.

Vedi tutti i progetti
LED in sequenza
#5Intermedio

LED in sequenza

Luci che si accendono una dopo l'altra, come se corressero. L'Arduino accende sei LED uno alla volta; ognuno brilla per un istante e si spegne, così la luce percorre la fila dall'inizio alla fine e po

4.6(85)
207
Effetto Supercar con LED
#6Intermedio

Effetto Supercar con LED

La classica luce che va e viene: un punto luminoso scorre da un capo all'altro di sei LED e poi torna indietro. L'Arduino accende ogni LED per un decimo di secondo prima di passare al successivo, inve

4.8(106)
202
Effetto Supercar a velocità regolabile
#8Intermedio

Effetto Supercar a velocità regolabile

Una luce corre su sei LED da un'estremità all'altra, torna indietro e riparte. Girando la manopola del potenziometro cambi subito la velocità della corsa: con la manopola da un lato la luce quasi vola

4.5(60)
120
Utilizzo della striscia LED WS2812B
#69Intermedio
Premium

Utilizzo della striscia LED WS2812B

Conosci una striscia LED intelligente in cui puoi colorare ogni singola luce per conto suo. L'Arduino accende prima i primi cinque LED di rosso, un secondo dopo gli altri cinque di blu, poi li spegne

4.8(54)
70
WS2812B Animazione 1
#75Intermedio
Premium

WS2812B Animazione 1

Su una striscia di 56 LED tutti i colori dell'arcobaleno si mettono in fila uno accanto all'altro e scorrono senza fermarsi mai, come se un fiume di luce scivolasse lungo la striscia. Ogni LED brilla

4.9(69)
89
WS2812B Animazione 2
#76Intermedio
Premium

WS2812B Animazione 2

Allestisci nella tua stanza uno spettacolo di luci che cambia colore da solo. L'Arduino fa scorrere i colori senza sosta su una striscia da 30 LED e ogni pochi secondi passa a una nuova serie: arcobal

4.8(65)
84
Serpente di pixel Matrice 8x8
#88Avanzato
Premium

Serpente di pixel Matrice 8x8

Costruisci con le tue mani il classico gioco del serpente e giocaci. Su una matrice di luci colorate 8x8 guidi un serpente verde con un joystick e mangi mele rosse; a ogni mela il serpente si allunga,

4.7(39)
57
Matrice LED 4x 32x8 - Pacchetto di 6 animazioni
#91Intermedio
Premium

Matrice LED 4x 32x8 - Pacchetto di 6 animazioni

Quattro pannelli LED 32x8 messi uno sopra l'altro formano uno schermo quadrato su cui si alternano sei animazioni: pioggia digitale che cade, una spirale che cresce, cellule che nascono e muoiono da s

4.5(35)
48