Cubo de LED com Arduino: como montar um cubo 3x3x3 e 4x4x4 com código
Monte um cubo de LED com Arduino: gabarito de solda, montagem 3x3x3 e 4x4x4, transistores nas camadas, cálculo dos resistores, expansão com 74HC595 e código de animação com arrays.
O cubo de LED é um dos projetos de luz mais chamativos que dá para montar com Arduino: LEDs organizados em uma grade tridimensional acendem camada por camada e desenham planos girando, gotas de chuva caindo e cubos que crescem e encolhem no ar. A melhor forma de começar um cubo de LED com Arduino é nos tamanhos 3x3x3 (27 LEDs) ou 4x4x4 (64 LEDs); nesses tamanhos, os pinos de um Arduino Uno, alguns transistores e um pouco de paciência na solda são tudo o que você precisa. O truque é não dar um pino para cada LED, e sim usar um método chamado multiplexação por camadas e colunas: você controla 27 LEDs com 12 pinos e 64 LEDs com apenas 7 pinos graças a dois chips 74HC595.
Neste guia, você vai aprender como um cubo de LED funciona, como fazer um gabarito de solda, como unir as camadas passo a passo, por que as camadas precisam ser acionadas por transistores e como se calculam os valores dos resistores. Depois, você encontra um código para Arduino que roda animações baseadas em arrays em um cubo 3x3x3, como chegar a um cubo 4x4x4 com o 74HC595, as versões para ESP32 e Raspberry Pi Pico (MicroPython), uma alternativa com WS2812B para um cubo colorido e soluções para os erros de montagem mais comuns, como um LED invertido ou uma solda fria.

O que é um cubo de LED e como ele funciona?
Um cubo de LED é feito empilhando camadas horizontais de LEDs com espaçamento igual. Em cada camada, as pernas de cátodo (−) de todos os LEDs são soldadas juntas, então cada camada tem uma única linha de cátodo comum. As pernas de ânodo (+) dos LEDs que ficam um em cima do outro são soldadas na vertical e formam as colunas. Um cubo 3x3x3 tem 3 camadas e 9 colunas, e um cubo 4x4x4 tem 4 camadas e 16 colunas. Cada LED fica exatamente no cruzamento de uma camada com uma coluna: para acender um LED, você aplica tensão positiva na coluna dele e liga a camada dele ao GND.
Dá para descrever cada LED do cubo com três coordenadas: x (da esquerda para a direita), y (da frente para trás) e z (de baixo para cima). No código deste artigo, o número da coluna é calculado como c = y × 3 + x (c = y × 4 + x no 4x4x4), e z é o número da camada. Assim como um pixel em uma tela, um único ponto de luz do cubo é chamado de voxel (pixel de volume). Fazer uma animação, na verdade, é decidir quais voxels ficam acesos em cada momento.
Como funciona a multiplexação por camadas e colunas?
Se você ligar mais de uma camada ao mesmo tempo, a tensão positiva aplicada em uma coluna acende um LED em cada camada ativa dessa coluna, e não dá para desenhar o padrão desejado. Por isso o cubo é varrido camada por camada: o Arduino primeiro desliga todas as camadas, escreve nos pinos o padrão de colunas da primeira camada, liga só essa camada por alguns milissegundos, depois a desliga e passa para a segunda camada. Quando esse ciclo se repete mais de cem vezes por segundo, o olho retém a luz por um instante (persistência da visão), e você vê todas as camadas acesas ao mesmo tempo.
Calcular a taxa de varredura é fácil: taxa de atualização = 1 / (número de camadas × tempo por camada). Se cada camada de um cubo 3x3x3 ficar ligada por 3 ms, uma passada leva 9 ms e o cubo se atualiza cerca de 110 vezes por segundo. Em um 4x4x4 com 2 ms por camada, a passada leva 8 ms e a taxa é de 125 Hz. Abaixo de 50–60 Hz, o olho percebe a cintilação; acima de 100 Hz, a imagem parece totalmente estável e aparecem menos faixas na câmera do celular. O preço é o brilho: como cada camada fica acesa só 1/3 do tempo (1/4 no 4x4x4), a corrente média de um LED cai para essa fração da corrente instantânea.
| Cubo | LEDs | Colunas + camadas | Pinos, acionamento direto | Pinos com 74HC595 | Pinos sem multiplexação |
|---|---|---|---|---|---|
| 3x3x3 | 27 | 9 + 3 | 12 | 3 + 3 = 6 | 27 |
| 4x4x4 | 64 | 16 + 4 | 20 | 3 + 4 = 7 | 64 |
| 5x5x5 | 125 | 25 + 5 | 30 | 3 + 5 = 8 | 125 |
| 8x8x8 | 512 | 64 + 8 | 72 | 3 + 8 = 11 | 512 |
Lista de peças
| Peça | Cubo 3x3x3 | Cubo 4x4x4 (com 74HC595) |
|---|---|---|
| LED de 5 mm (de uma cor, difuso se possível) | 27 + 3 de reserva | 64 + 6 de reserva |
| Resistor de coluna | 9 × 220 Ω | 16 × 330 Ω (azul, branco) ou 470 Ω (vermelho, amarelo) |
| Transistor NPN (camada) | 3 × 2N2222A ou BC337 | 4 × 2N2222A ou BC337 |
| Resistor de base | 3 × 470 Ω | 4 × 470 Ω |
| Registrador de deslocamento | Não é necessário | 2 × 74HC595 (74HCT595 para ESP32 e Pico) + 100 nF em cada um |
| Placa controladora | Arduino Uno ou Nano | Arduino Uno, Nano, ESP32 ou Pico |
| Montagem | Placa perfurada, fio rígido fino | Placa perfurada, fio de cobre estanhado de 0,5–0,8 mm |
| Ferramentas | Ferro de solda, estanho, alicate de corte, alicate, broca de 5 mm | As mesmas ferramentas + espaçadores de mesma altura |




Como fazer um gabarito de solda
O segredo de um cubo caprichado é o gabarito. Se você soldar os LEDs segurando com a mão, o espaçamento varia, as camadas ficam tortas e o cubo parece inclinado. O gabarito é um pedaço de madeira com furos igualmente espaçados, onde os LEDs ficam de cabeça para baixo, com a cúpula virada para baixo. O espaçamento é definido pelo comprimento da perna de cátodo: na maioria dos LEDs de 5 mm, a perna curta tem cerca de 25 mm, mas meça os seus LEDs com uma régua. Quando você dobra a perna a 90° a uns 2–3 mm do corpo, a parte horizontal que sobra deve passar 2–3 mm por cima da perna do LED vizinho; por isso um espaçamento de 20 mm é um bom ponto de partida.
- Desenhe com régua uma grade 3x3 (ou 4x4) em compensado, MDF ou papelão grosso, com 20 mm entre os pontos e pelo menos 2 cm de margem das bordas.
- Marque cada ponto primeiro com um prego e depois fure reto com uma broca de 5 mm. O LED deve ficar firme no furo, mas sair sem força; se estiver apertado demais, alargue um pouco o furo.
- Desenhe uma seta em uma borda do gabarito para indicar o lado do cátodo; a perna curta de todos os LEDs vai apontar para o mesmo lado.
- Prepare quatro espaçadores de mesma altura, adequados ao espaçamento entre camadas, para apoiar a camada de cima enquanto você une as camadas; sobras de sarrafo de madeira ou papelão dobrado resolvem.
Montagem passo a passo: camadas e colunas
- Dobre as pernas: dobre na horizontal, a 90°, a perna curta (cátodo) de cada LED, a 2–3 mm do corpo, na direção da seta do gabarito. A perna longa (ânodo) fica em pé.
- Monte a primeira camada: coloque os LEDs nos furos com a cúpula para baixo. Cada perna de cátodo de uma fileira deve encostar na perna de cátodo do LED seguinte; a perna do último LED da fileira pode ficar solta.
- Solde os cátodos: solde cada ponto de contato em 2–3 segundos, com o ferro a 320–350 °C. Depois, solde um fio reto (uma perna de resistor cortada ou fio de cobre estanhado) atravessando as pontas das fileiras para uni-las. A camada vira ao mesmo tempo uma única linha elétrica e uma estrutura firme; no 4x4x4, colocar um fio nas duas pontas deixa a camada ainda mais resistente.
- Teste a camada: sem tirar a camada do gabarito, ligue a linha de cátodo ao GND e encoste 5 V, através de um resistor de 220 Ω, em cada perna de ânodo. Se algum LED não acender, troque-o agora.
- Faça as outras camadas: repita o processo até ter 3 (ou 4) camadas. Mantenha as pernas de cátodo apontando para o mesmo lado em todas as camadas, para que as colunas fiquem perfeitamente alinhadas.
- Una as camadas: deixe uma camada no gabarito e alinhe a próxima exatamente em cima dela, sobre os espaçadores. Faça uma pequena dobra de 2 mm na ponta de cada perna de ânodo dos LEDs de baixo, que aponta para cima, para que a perna passe ao lado do corpo do LED de cima e encoste na perna de ânodo dele. Solde primeiro os quatro cantos, confira o alinhamento e depois termine as outras colunas.
- Tire os fios das camadas: solde um fio na linha de cátodo de cada camada e desça-o por uma lateral do cubo. Esses fios não podem encostar um no outro nem nas colunas; deixe alguns milímetros entre eles.
- Monte na base: vire o cubo; as pernas de ânodo livres da última camada adicionada agora apontam para baixo, e essa camada passa a ser a mais próxima da base, a camada de baixo (z = 0). Passe as pernas e os fios das camadas por uma placa perfurada, solde-os e coloque os resistores de coluna ao lado de cada coluna.
Acionando as camadas com transistores

Um pino de coluna fornece corrente para um único LED, mas, quando uma camada é ligada, a corrente de todos os LEDs dessa camada volta para o GND pela mesma linha de cátodo. Em um cubo 3x3x3, isso dá 9 LEDs × 12,7 mA ≈ 115 mA, e em um cubo 4x4x4 com 74HC595, 16 LEDs × 5 mA ≈ 80 mA. O limite recomendado para um pino do Arduino Uno é de 20 mA, e o máximo absoluto, de 40 mA, então não dá para ligar uma linha de camada direto em um pino. A solução é um transistor NPN em cada camada: o coletor vai na linha da camada, o emissor no GND e a base em um pino do Arduino através de um resistor. Quando o pino vai para HIGH, o transistor satura e puxa a camada para o GND. Para ligar o transistor por completo, escolha uma corrente de base de cerca de 1/10 a 1/20 da corrente de coletor: 115 mA pedem 6–12 mA, e (5 V − 0,7 V) / 470 Ω ≈ 9 mA cai bem nessa faixa. Para os detalhes, veja O que é transistor? e, para as pinagens, a ferramenta Transistores.
| Transistor | IC contínua | Ordem dos pinos (lado plano para você) | Uso no cubo de LED |
|---|---|---|---|
| BC547 | 100 mA | C-B-E | Só para cubos de baixa corrente; os 115 mA de um 3x3x3 passam do limite dele |
| 2N2222A | 600 mA | E-B-C | Ideal para 3x3x3 e 4x4x4 |
| BC337 | 800 mA | C-B-E | Ideal para 3x3x3 e 4x4x4 |
| IRLZ44N (MOSFET de nível lógico) | Dezenas de ampères | G-D-S | Cubos grandes, como 8x8x8; 220 Ω no gate, 10 kΩ do gate ao GND |
Cálculo dos resistores: resistores de coluna e de base
O resistor de coluna é a única peça que limita a corrente do LED, e há um em cada coluna; não é preciso um resistor por LED, porque só um LED de cada coluna fica aceso em cada instante. A fórmula vem da lei de Ohm: R = (Valim − VLED − VCE(sat)) / ILED. Com alimentação de 5 V, um LED vermelho com tensão direta de 2,0 V e um transistor que derruba cerca de 0,2 V quando saturado, mirando 12 mA, temos R = (5 − 2,0 − 0,2) / 0,012 ≈ 233 Ω. O valor padrão mais próximo, 220 Ω, deixa passar cerca de 12,7 mA pelo LED. Com um LED azul de 3,1 V, os mesmos 220 Ω dão cerca de 7,7 mA, o que ainda fica bem visível com multiplexação.
| Cor do LED | Tensão direta (VF) | 3x3x3, direto do Arduino (5 V) | 4x4x4, 74HC595 (5 V) |
|---|---|---|---|
| Vermelho, amarelo | 1,8–2,2 V | 220 Ω (≈12–13 mA) | 470 Ω (≈5–6 mA) |
| Verde puro, azul | 2,9–3,3 V | 180–220 Ω (≈8–9 mA) | 330 Ω (≈4–5 mA) |
| Branco | 2,9–3,4 V | 180–220 Ω (≈7–9 mA) | 330 Ω (≈4–5 mA) |
No cubo com 74HC595, escolhemos resistores maiores de propósito: pelo pino VCC ou GND desse chip podem passar no máximo 70 mA no total, e, com uma camada ligada, as oito saídas podem estar acesas ao mesmo tempo. 8 × 5,5 mA ≈ 44 mA deixa uma margem segura. A corrente média do LED, que define o brilho percebido, é a corrente instantânea dividida pelo número de camadas: 12,7 / 3 ≈ 4,2 mA em um 3x3x3 e 5,5 / 4 ≈ 1,4 mA em um 4x4x4. Os LEDs eficientes de hoje ficam bem visíveis em ambientes internos com essas correntes, mas em uma sala muito clara um cubo 4x4x4 pode parecer um pouco fraco. Para calcular com os valores do seu LED, use as ferramentas Resistor para LED e Tensões dos LEDs.
Ligação do cubo de LED 3x3x3
| Ligação | Arduino Uno / Nano | Observação |
|---|---|---|
| Colunas 0–8 (ânodos) | D2–D10 | Resistor em série de 220 Ω em cada coluna |
| Camada de baixo (z = 0) | A0 | Para a base do transistor 1 via 470 Ω |
| Camada do meio (z = 1) | A1 | Para a base do transistor 2 via 470 Ω |
| Camada de cima (z = 2) | A2 | Para a base do transistor 3 via 470 Ω |
| Coletores dos transistores | — | Cada um no fio de cátodo da sua camada |
| Emissores dos transistores | GND | Os três em um GND comum |
| Vista de cima | x = 0 | x = 1 | x = 2 |
|---|---|---|---|
| y = 2 (fundo) | Coluna 6 → D8 | Coluna 7 → D9 | Coluna 8 → D10 |
| y = 1 (meio) | Coluna 3 → D5 | Coluna 4 → D6 | Coluna 5 → D7 |
| y = 0 (frente) | Coluna 0 → D2 | Coluna 1 → D3 | Coluna 2 → D4 |
Código Arduino para o cubo de LED 3x3x3: animações com arrays
Cada quadro da animação é guardado como um número por camada. Uma camada do 3x3x3 tem 9 LEDs, então um valor de 9 bits basta; guardamos como uint16_t, e o bit c representa a coluna c. Os quadros vão para a memória flash com PROGMEM, então nem animações com centenas de quadros enchem os 2 KB de RAM do Uno. O código abaixo não precisa de biblioteca extra.
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}O coração do código é a função showFrame(). Para cada camada, ela primeiro escreve o padrão de colunas nos pinos, depois liga só o transistor dessa camada por 3 ms e desliga a camada antes que as colunas mudem. Essa ordem importa: se você mudar as colunas com uma camada ligada, o padrão da camada anterior aparece por um instante na nova camada e causa ghosting (efeito fantasma). bitRead(bits, c) devolve o bit c do número como 0 ou 1, e pgm_read_word() lê o valor de 16 bits da flash. O loop() primeiro mostra as camadas uma a uma, depois o centro e as 12 arestas do cubo e, em seguida, gira um plano vertical por quatro posições, criando um efeito de cata-vento.
Como criar as suas próprias animações
Para desenhar um quadro novo, olhe o cubo de cima e imagine cada camada como uma folha quadriculada de 3x3. Marque as colunas que você quer acesas e escreva o número binário depois de 0b, da esquerda para a direita, do bit 8 até o bit 0. Os quatro cantos, por exemplo, são as colunas 0, 2, 6 e 8, o que dá 0b101000101. Escreva o mesmo valor nas três camadas e você tem barras verticais nos quatro cantos; escreva só na camada do meio e você tem quatro pontos flutuando no ar. Se números binários são novidade para você, Sistemas numéricos e operações bit a bit explica a ideia em detalhe. Algumas técnicas que ajudam na hora de escrever o código:
- Deslocamento de bits: desloque o valor de uma camada 3 bits para a esquerda no 3x3x3, ou 4 bits no 4x4x4, e o padrão anda uma fileira para trás; elimine os bits que transbordam com uma máscara &, e você tem efeitos de onda e de texto rolante.
- Cópia de camadas: copiar o array de camadas um passo para baixo ou para cima dá efeitos de chuva, bolhas subindo e elevador.
- Aleatoriedade: voxels escolhidos com random() que piscam rapidamente criam um efeito de campo de estrelas ou de faíscas.
- Inversão: o operador ~ transforma um quadro no seu negativo, e alternar rapidamente entre os dois cria um destaque piscante.
Cubo de LED 4x4x4: ampliando com o 74HC595
Um cubo 4x4x4 tem 16 colunas e 4 camadas; acioná-lo diretamente exige 20 pinos, ou seja, todos os pinos do Uno, inclusive D0 e D1. Se, em vez disso, você acionar as colunas com dois registradores de deslocamento 74HC595 ligados em cascata, as 16 colunas custam só 3 pinos (dados, clock e latch); somando 4 pinos para as camadas, o total fica em 7 pinos. A saída Q7' (pino 9) do primeiro chip vai para a entrada DS do segundo chip, enquanto as linhas de clock e latch são compartilhadas pelos dois. As colunas 0–7 (as duas fileiras da frente) ligam nas saídas Q0–Q7 do primeiro chip, e as colunas 8–15 (as duas fileiras de trás), no segundo chip. O mesmo método chega a 4 chips em um cubo 5x5x5 e a 8 chips em um cubo 8x8x8.
| Ligação | Arduino Uno | ESP32 | Raspberry Pi Pico |
|---|---|---|---|
| DS (14), primeiro chip | D11 | GPIO 23 | GP19 |
| SH_CP (11), comum aos dois chips | D13 | GPIO 18 | GP18 |
| ST_CP (12), comum aos dois chips | D10 | GPIO 5 | GP17 |
| OE (13) / MR (10) | GND / 5V | GND / 5V | GND / VBUS |
| VCC (16) / GND (8) | 5V / GND | 5V / GND | VBUS / GND |
| Q7' (9) → DS (14) do segundo chip | Cascata | Cascata | Cascata |
| Transistores das camadas 0–3 (via 470 Ω) | D2, D3, D4, D5 | GPIO 25, 26, 27, 32 | GP10, GP11, GP12, GP13 |
| Tipo de chip | 74HC595 | 74HCT595 | 74HCT595 |
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}Nesta versão, a varredura acontece na função refresh(), com um projeto sem bloqueio: a cada chamada, ela usa micros() para verificar se 2 ms já passaram; se sim, desliga a camada antiga, envia os 16 bits da nova camada para os dois chips e liga a nova camada. Assim, o código da animação só altera o array cube[] e nunca precisa cuidar da atualização da imagem. holdFor() continua chamando refresh() enquanto espera, por isso você não deve usar um delay() longo em nenhum lugar do programa. setVoxel(x, y, z) permite acender um único LED pelas coordenadas; sweep() o usa para mover um plano vertical pelo cubo, e rain() copia as camadas um passo para baixo e adiciona gotas aleatórias no topo. Você encontra a diferença entre delay() e millis() em millis() ou delay() e como passar a varredura para uma interrupção de timer em Interrupções no Arduino.
Cubo de LED com o ESP32
Os pinos do ESP32 têm saída de 3,3 V. Isso não basta para acionar diretamente LEDs azuis e brancos, cuja tensão direta fica por volta de 3 V; depois da queda no resistor e no transistor, quase nada sobra. Por isso, a solução mais limpa no ESP32 é acionar as colunas por um 74HCT595 alimentado com 5 V: a família HCT considera até 2 V como HIGH, então lê sinais de 3,3 V sem problemas, enquanto os LEDs são alimentados com 5 V. Mantenha 470 Ω nas bases dos transistores das camadas; (3,3 − 0,7) / 470 ≈ 5,5 mA bastam para uma corrente de camada de 80 mA. O código do 4x4x4 acima compila no ESP32 do jeito que está; você só precisa trocar as constantes de pinos pelos valores da tabela (23, 18, 5 e 25, 26, 27, 32). Se quiser, também pode usar o Wi-Fi do ESP32 para escolher animações em uma página web no celular; para começar, veja O que é o ESP32?.
Cubo de LED com o Raspberry Pi Pico e MicroPython
O Pico também é uma placa de 3,3 V e, na configuração padrão, os pinos fornecem só alguns miliampères, então se usa o mesmo circuito com 74HCT595. Alimente os chips e os LEDs pelo VBUS (pino 40), que traz os 5 V da USB. No MicroPython, os 16 bits são enviados por SPI de hardware: os pinos GP18 (SCK) e GP19 (MOSI) do SPI0 acionam as linhas de clock e de dados, e o GP17 aciona o latch. O código segue a mesma lógica: show() varre um quadro camada por camada pelo tempo indicado e, no efeito de chuva, o fatiamento de lista (cube[1:]) move cada camada um passo para baixo. Para a instalação e os primeiros passos, veja O que é o Raspberry Pi Pico?.
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)Cubos maiores: 5x5x5 e 8x8x8
Quando o cubo cresce, dois problemas crescem junto. O primeiro é a corrente: um cubo 8x8x8 tem 64 LEDs por camada e, a 10 mA por LED, a corrente da camada chega a 640 mA; isso já não é trabalho para um pequeno transistor TO-92, e sim para um MOSFET de nível lógico. O segundo é o tempo de varredura: para manter 100 Hz com 8 camadas, cada camada recebe 1,25 ms e é preciso enviar 64 bits (8 bytes) por camada; o shiftOut() é lento demais para isso, então o SPI de hardware é obrigatório. Além disso, cada LED fica aceso só 1/8 do tempo, e o brilho cai; cubos grandes precisam de drivers de coluna mais fortes e de uma fonte externa de 5 V em vez da USB (veja Como alimentar o Arduino). Por isso, o seu primeiro cubo deve ser um 3x3x3 ou 4x4x4; você domina a técnica antes de soldar 512 LEDs.
Alternativa: cubo de LED colorido com WS2812B

Se você prefere escolher a cor de cada LED individualmente em vez de montar um cubo de uma cor só, pode usar LEDs endereçáveis como o WS2812B. Cada um desses LEDs tem o próprio chip driver, então não é preciso multiplexação, transistores nem resistores de coluna: os 64 LEDs são ligados em cascata com 5 V, GND e uma linha de dados e acionados por um único pino. Para um cubo, usam-se LEDs endereçáveis de 5 mm com 4 pernas (como o PL9823 ou o APA106) ou pedaços cortados de uma fita WS2812B. O preço é a corrente: cerca de 60 mA por LED no branco máximo, o que dá 3,8 A para 64 LEDs. Então use uma fonte de 5 V e 4 A, adicione um capacitor de 1000 µF na alimentação e um resistor de 330 Ω na linha de dados, e limite o brilho no software. O código usa a biblioteca Adafruit NeoPixel.
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}A função idx() do código converte uma coordenada x, y, z na posição dentro da cadeia e pressupõe que você ligou todas as fileiras no mesmo sentido. Se você fez a fiação em zigue-zague, vai precisar usar 3 − x em vez de x nas fileiras ímpares. Alguns LEDs endereçáveis de 5 mm esperam as cores na ordem RGB; se aparecer verde no lugar de vermelho, troque NEO_GRB por NEO_RGB. setBrightness(40) reduz o brilho para cerca de 16%, então, mesmo no pior caso, a corrente fica em torno de 0,6 A.
| Característica | Cubo de LED de uma cor | Cubo de LED WS2812B |
|---|---|---|
| Cor | Uma cor (a do próprio LED) | 16 milhões de cores, definidas por LED |
| Pinos usados (4x4x4) | 7 (com 74HC595) | 1 |
| Peças extras | Transistores, resistores, 74HC595 | Capacitor, resistor de dados, fonte potente |
| Trabalho de solda | 2 pernas por LED | 4 pernas por LED, mais fios |
| Controle de brilho | Liga/desliga (PWM por LED é difícil) | 256 níveis para cada LED |
| Corrente (4x4x4) | Cerca de 100 mA, a USB basta | Até ≈3,8 A, fonte externa obrigatória |
| O que ensina | Multiplexação, transistores, operações com bits | Endereçamento, matiz, gestão de energia |
Ideias de projetos com cubo de LED
- Cubo que reage à música: aumente o número de camadas acesas conforme o nível de som medido com um sensor de som e faça um equalizador tridimensional.
- Jogo da cobrinha em 3D: conduza a cobrinha pelos três eixos em um cubo 4x4x4 com um joystick e um botão; para mais ideias de jogos, veja projetos de jogos com Arduino.
- Cubo dado: quando você aperta um botão, os voxels se embaralham rapidamente e o cubo mostra um número de 1 a 6 como um padrão de pontos.
- Projeto para feira de ciências: explique a persistência da visão aumentando o tempo por camada com um potenciômetro e mostrando o momento em que a cintilação começa; para mais ideias, veja ideias de projetos para feira de ciências.
- Escolha de animações pelo celular: faça cada letra enviada por um módulo Bluetooth HC-05 iniciar uma animação diferente.
- Luz noturna colorida: crie transições lentas de cor em um cubo WS2812B; se estiver usando um ESP32, controle os efeitos pelo celular com o WLED.
Erros comuns e como corrigi-los
| Sintoma | Causa provável | Solução |
|---|---|---|
| Um único LED nunca acende | O LED está invertido ou queimado, ou uma solda de perna quebrou | Confira o lado do cátodo, teste o LED com uma bateria tipo moeda e troque se necessário |
| LEDs que deveriam estar apagados brilham fraco (ghosting) | As colunas mudam com uma camada ligada, ou há um LED invertido no cubo | Desligue primeiro a camada e depois escreva as colunas; se o código estiver certo, encontre o LED invertido |
| Os LEDs piscam ou apagam quando você toca no cubo | Solda fria: uma solda fosca, granulada, em forma de bolinha | Reaqueça a solda com a ponta do ferro limpa e adicione um pouco de estanho novo |
| Uma camada inteira fica apagada | As pernas do transistor estão invertidas (E-B-C confundido com C-B-E) ou o resistor de base está solto | Confira a ordem dos pinos no datasheet e meça a ligação da base |
| Uma coluna inteira fica apagada | A coluna não está soldada na base, ou o resistor ou o pino está errado | Meça a coluna de ponta a ponta com um multímetro e confira o array de pinos no código |
| O cubo cintila | O tempo por camada é longo demais, ou há um Serial.print() ou delay() no laço de varredura | Ajuste o tempo por camada para 2–3 ms e remova o código que bloqueia a varredura |
| O cubo está muito fraco | Os resistores são grandes demais, há LEDs azuis acionados com 3,3 V ou camadas demais | Recalcule o resistor; em placas de 3,3 V, alimente um 74HCT595 com 5 V |
| O sketch não carrega | Há um LED ligado no D0 ou no D1 | Comece as colunas no D2 ou desconecte esses fios durante o carregamento |
O cubo de LED é um dos raros projetos que ensinam ao mesmo tempo solda, transistores, cálculo de resistores, multiplexação e operações com bits. Comece com um 3x3x3 e, quando o código e a lógica das animações fizerem sentido, passe para um 4x4x4 com o 74HC595, ou para o WS2812B se quiser cor. Se quiser testar primeiro a ideia de acender LEDs em sequência em uma fileira reta, efeito Super Máquina e sequencial de LEDs com Arduino é um bom aquecimento. No app BlueGrays, você encontra projetos de sequencial de LEDs, efeito Knight Rider, animações com WS2812B e matriz de LEDs, com esquema do circuito passo a passo e código.
Perguntas frequentes
Quantos LEDs e pinos um cubo de LED precisa?
Um cubo 3x3x3 precisa de 27 LEDs e um cubo 4x4x4, de 64; vale a pena comprar alguns de reserva. Com multiplexação por camadas e colunas, um cubo 3x3x3 precisa de 9 colunas mais 3 camadas, ou seja, 12 pinos. Um cubo 4x4x4 usa 20 pinos com acionamento direto, mas, se você acionar as colunas com dois 74HC595, o total cai para 7 pinos.
Qual resistor devo usar em um cubo de LED?
Há um resistor por coluna; para um cubo 3x3x3 acionado diretamente por um Arduino a 5 V, 220 Ω é um valor comum e seguro. Em um cubo com 74HC595, use 330 Ω para LEDs azuis e brancos e 470 Ω para LEDs vermelhos e amarelos, para ficar abaixo do limite total de 70 mA do chip. Para calcular o seu valor, aplique R = (Valim − VLED − 0,2 V) / ILED.
Por que as camadas de um cubo de LED são acionadas por transistores?
Quando uma camada é ligada, a corrente de todos os LEDs dessa camada volta para o GND por uma única linha; em um cubo 3x3x3, isso passa de 100 mA. Como o limite recomendado de um pino do Arduino é de 20 mA, a linha da camada é puxada para o GND por um transistor NPN, como o 2N2222A ou o BC337. Um resistor de base de 470 Ω é suficiente.
Por que o meu cubo de LED está cintilando?
A cintilação aparece quando a taxa de varredura é baixa demais. A taxa de atualização é 1 / (número de camadas × tempo por camada) e deve ficar acima de 100 Hz, então mantenha o tempo por camada em 2–3 ms e não coloque um delay() longo nem Serial.print() no laço de varredura. Se o cubo só cintila quando você toca nele, o problema provavelmente é uma solda fria.
Por que acendem LEDs que deveriam estar apagados?
Isso se chama ghosting (efeito fantasma) e tem duas causas principais. Mudar os valores das colunas com uma camada ligada leva o padrão anterior para a nova camada por um instante; desligue primeiro a camada e depois escreva as colunas. Se o código estiver certo, um LED invertido no cubo pode estar abrindo um caminho de corrente para outras camadas.
Dá para montar um cubo de LED 8x8x8 com um Arduino Uno?
Sim, mas os pinos sozinhos não bastam: você precisa de uma cadeia de 74HC595 ou drivers parecidos para as 64 colunas, MOSFETs de nível lógico para as 8 camadas e SPI de hardware para uma varredura rápida. Soldar 512 LEDs também leva dias. Dominar a técnica primeiro em um cubo 3x3x3 ou 4x4x4 é o melhor caminho.
Projetos para montar depois desta leitura
Ver todos os projetos
Sequencial de LEDs
Luzes que acendem uma após a outra, como se estivessem correndo. O Arduino acende seis LEDs, um de cada vez; cada um brilha por um instante e apaga, fazendo a luz percorrer a sequência do início ao fi

Efeito Knight Rider com LEDs
O clássico efeito Knight Rider: um ponto de luz percorre seis LEDs de uma ponta à outra e depois volta. O Arduino acende cada LED por um décimo de segundo antes de passar para o próximo, muda de direç

Efeito Knight Rider com LEDs e velocidade ajustável
Uma luz percorre seis LEDs de uma ponta à outra, muda de direção e volta. Ao girar o botão do potenciômetro, você ajusta a velocidade na hora: em uma extremidade, a luz quase voa; na outra, avança dev

Uso da fita LED WS2812B
Conheça uma fita LED inteligente em que você pode definir a cor de cada luz individualmente. O Arduino primeiro acende os cinco primeiros LEDs em vermelho, um segundo depois acende os outros cinco em

Animação 1 com WS2812B
Em uma fita de 56 LEDs, todas as cores do arco-íris ficam lado a lado e fluem sem parar, como se um rio de luz deslizasse pela fita. Cada LED brilha em uma cor um pouco diferente da do anterior, e o m

Animação 2 com WS2812B
Monte no seu quarto um espetáculo de luzes que muda de cor sozinho. O Arduino mantém as cores em movimento em uma fita de 30 LEDs e troca o conjunto de cores a cada poucos segundos: arco-íris, faixas

Cobrinha em pixels: matriz 8x8
Monte o clássico jogo da cobrinha com as próprias mãos e jogue. Em uma matriz de luzes coloridas 8x8, você guia uma cobra verde com um joystick e come maçãs vermelhas; a cada maçã, a cobra cresce, ace

4x matriz de LED 32x8 - Pacote de 6 animações
Quatro painéis de LED 32x8 empilhados formam um display quadrado que exibe seis animações em sequência: chuva digital, uma espiral que cresce, células que nascem e morrem sozinhas, ondas circulares na
Mais artigos
App BlueGrays
Monte este circuito passo a passo pelo celular
Esquema do circuito, código e lista de componentes em uma só tela. Mais de 200 projetos com Arduino, ESP32 e Pico prontos para montar.
Escaneie com seu celular
Aponte a câmera para o código para abrir a loja de aplicativos do seu celular.
ou abrir a loja

