Guias · 20 min de leitura

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.

LED de 5 mm para cubo de LED
A peça básica do cubo de LED é o LED de 5 mm: a perna longa é o ânodo (+); a perna curta e o lado chanfrado do corpo indicam o cátodo (−).

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.

CuboLEDsColunas + camadasPinos, acionamento diretoPinos com 74HC595Pinos sem multiplexação
3x3x3279 + 3123 + 3 = 627
4x4x46416 + 4203 + 4 = 764
5x5x512525 + 5303 + 5 = 8125
8x8x851264 + 8723 + 8 = 11512

Lista de peças

PeçaCubo 3x3x3Cubo 4x4x4 (com 74HC595)
LED de 5 mm (de uma cor, difuso se possível)27 + 3 de reserva64 + 6 de reserva
Resistor de coluna9 × 220 Ω16 × 330 Ω (azul, branco) ou 470 Ω (vermelho, amarelo)
Transistor NPN (camada)3 × 2N2222A ou BC3374 × 2N2222A ou BC337
Resistor de base3 × 470 Ω4 × 470 Ω
Registrador de deslocamentoNão é necessário2 × 74HC595 (74HCT595 para ESP32 e Pico) + 100 nF em cada um
Placa controladoraArduino Uno ou NanoArduino Uno, Nano, ESP32 ou Pico
MontagemPlaca perfurada, fio rígido finoPlaca perfurada, fio de cobre estanhado de 0,5–0,8 mm
FerramentasFerro de solda, estanho, alicate de corte, alicate, broca de 5 mmAs mesmas ferramentas + espaçadores de mesma altura
Placa Arduino Uno
Placa Arduino Uno
Resistor de 220 Ω
Resistor de 220 Ω
Protoboard
Protoboard
Fio jumper
Fio jumper

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.

  1. 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.
  2. 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.
  3. 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.
  4. 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.
Teste cada LED um por um antes de começar a soldar: basta encostar a perna longa no lado positivo e a perna curta no lado negativo de uma bateria tipo moeda CR2032 de 3 V. O modo de diodo do multímetro também acende um LED fraquinho. Tirar um LED queimado do meio do cubo é muito difícil. Para a aparência, escolha LEDs difusos; LEDs transparentes concentram a luz em uma direção, então o cubo brilha de forma desigual quando visto de lado. Você pode deixar fosca a cúpula de LEDs transparentes com uma lixa fina.

Montagem passo a passo: camadas e colunas

  1. 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é.
  2. 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.
  3. 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.
  4. 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.
  5. 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.
  6. 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.
  7. 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.
  8. 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.
O erro de montagem mais caro é um único LED invertido. Um LED invertido não fica só apagado: quando um pino de coluna está em LOW, ele abre um caminho de corrente reversa da linha da camada para aquela coluna, e LEDs fantasmas podem acender em camadas que deveriam estar apagadas. Toda vez que colocar um LED no gabarito, confira se a perna curta (o lado chanfrado do corpo) aponta para a seta, e sempre teste cada camada antes de uni-la.

Acionando as camadas com transistores

Transistor NPN
A corrente da camada passa por um transistor NPN, não por um pino do Arduino: o 2N2222A (E-B-C) ou o BC337 (C-B-E) são boas escolhas.

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.

TransistorIC contínuaOrdem dos pinos (lado plano para você)Uso no cubo de LED
BC547100 mAC-B-ESó para cubos de baixa corrente; os 115 mA de um 3x3x3 passam do limite dele
2N2222A600 mAE-B-CIdeal para 3x3x3 e 4x4x4
BC337800 mAC-B-EIdeal para 3x3x3 e 4x4x4
IRLZ44N (MOSFET de nível lógico)Dezenas de ampèresG-D-SCubos 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 LEDTensão direta (VF)3x3x3, direto do Arduino (5 V)4x4x4, 74HC595 (5 V)
Vermelho, amarelo1,8–2,2 V220 Ω (≈12–13 mA)470 Ω (≈5–6 mA)
Verde puro, azul2,9–3,3 V180–220 Ω (≈8–9 mA)330 Ω (≈4–5 mA)
Branco2,9–3,4 V180–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çãoArduino Uno / NanoObservação
Colunas 0–8 (ânodos)D2–D10Resistor em série de 220 Ω em cada coluna
Camada de baixo (z = 0)A0Para a base do transistor 1 via 470 Ω
Camada do meio (z = 1)A1Para a base do transistor 2 via 470 Ω
Camada de cima (z = 2)A2Para a base do transistor 3 via 470 Ω
Coletores dos transistores—Cada um no fio de cátodo da sua camada
Emissores dos transistoresGNDOs três em um GND comum
Vista de cimax = 0x = 1x = 2
y = 2 (fundo)Coluna 6 → D8Coluna 7 → D9Coluna 8 → D10
y = 1 (meio)Coluna 3 → D5Coluna 4 → D6Coluna 5 → D7
y = 0 (frente)Coluna 0 → D2Coluna 1 → D3Coluna 2 → D4
Não use D0 e D1 nas colunas: esses pinos são compartilhados com o carregamento pela USB e com o Monitor Serial, e LEDs ligados neles podem atrapalhar o carregamento. Por isso o cubo 3x3x3 usa D2–D10 e A0–A2; os pinos A0–A5 funcionam como saídas digitais comuns com digitalWrite(). A corrente total também fica dentro dos limites: quando as nove colunas puxam 12,7 mA, saem cerca de 115 mA do Arduino, abaixo do limite total de 200 mA do ATmega328P. Você vê onde ficam os pinos na placa com a ferramenta Pinagem.

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.

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}

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çãoArduino UnoESP32Raspberry Pi Pico
DS (14), primeiro chipD11GPIO 23GP19
SH_CP (11), comum aos dois chipsD13GPIO 18GP18
ST_CP (12), comum aos dois chipsD10GPIO 5GP17
OE (13) / MR (10)GND / 5VGND / 5VGND / VBUS
VCC (16) / GND (8)5V / GND5V / GNDVBUS / GND
Q7' (9) → DS (14) do segundo chipCascataCascataCascata
Transistores das camadas 0–3 (via 470 Ω)D2, D3, D4, D5GPIO 25, 26, 27, 32GP10, GP11, GP12, GP13
Tipo de chip74HC59574HCT59574HCT595
Pelo pino VCC ou GND do 74HC595 podem passar no máximo 70 mA no total. Com resistores pequenos, como 220 Ω, uma camada totalmente acesa puxa 80–100 mA por chip; o chip esquenta, a tensão de saída cai e, com o tempo, ele queima. Use os valores de 330–470 Ω da tabela de resistores e coloque um capacitor de 100 nF entre os pinos VCC e GND de cada chip, o mais perto possível dos pinos.
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}

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?.

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)

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

LED RGB endereçável WS2812B
Cada LED WS2812B tem o próprio chip driver; um cubo de 64 LEDs é controlado por um único pino de dados.

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.

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}

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ísticaCubo de LED de uma corCubo de LED WS2812B
CorUma cor (a do próprio LED)16 milhões de cores, definidas por LED
Pinos usados (4x4x4)7 (com 74HC595)1
Peças extrasTransistores, resistores, 74HC595Capacitor, resistor de dados, fonte potente
Trabalho de solda2 pernas por LED4 pernas por LED, mais fios
Controle de brilhoLiga/desliga (PWM por LED é difícil)256 níveis para cada LED
Corrente (4x4x4)Cerca de 100 mA, a USB bastaAté ≈3,8 A, fonte externa obrigatória
O que ensinaMultiplexação, transistores, operações com bitsEndereç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

SintomaCausa provávelSolução
Um único LED nunca acendeO LED está invertido ou queimado, ou uma solda de perna quebrouConfira 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 cuboDesligue 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 cuboSolda fria: uma solda fosca, granulada, em forma de bolinhaReaqueça a solda com a ponta do ferro limpa e adicione um pouco de estanho novo
Uma camada inteira fica apagadaAs pernas do transistor estão invertidas (E-B-C confundido com C-B-E) ou o resistor de base está soltoConfira a ordem dos pinos no datasheet e meça a ligação da base
Uma coluna inteira fica apagadaA coluna não está soldada na base, ou o resistor ou o pino está erradoMeça a coluna de ponta a ponta com um multímetro e confira o array de pinos no código
O cubo cintilaO tempo por camada é longo demais, ou há um Serial.print() ou delay() no laço de varreduraAjuste o tempo por camada para 2–3 ms e remova o código que bloqueia a varredura
O cubo está muito fracoOs resistores são grandes demais, há LEDs azuis acionados com 3,3 V ou camadas demaisRecalcule o resistor; em placas de 3,3 V, alimente um 74HCT595 com 5 V
O sketch não carregaHá um LED ligado no D0 ou no D1Comece as colunas no D2 ou desconecte esses fios durante o carregamento
A melhor forma de encontrar defeitos é varrer o cubo com um sketch de teste: escreva um pequeno laço que acenda cada LED por vez durante 200 ms. Um LED que fica apagado ou acende no lugar errado aponta na hora para uma solda quebrada ou uma coluna trocada. Uma solda fria parece fosca e granulada, não brilhante; uma boa solda parece um cone brilhante, levemente côncavo, abraçando a perna. Para aprimorar a sua técnica, dê uma olhada em Como soldar.

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.

Ver todos os projetos
Sequencial de LEDs
#5Intermediário

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

4.6(85)
207
Efeito Knight Rider com LEDs
#6Intermediário

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ç

4.8(106)
202
Efeito Knight Rider com LEDs e velocidade ajustável
#8Intermediário

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

4.5(60)
120
Uso da fita LED WS2812B
#69Intermediário
Premium

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

4.8(54)
70
Animação 1 com WS2812B
#75Intermediário
Premium

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

4.9(69)
89
Animação 2 com WS2812B
#76Intermediário
Premium

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

4.8(65)
84
Cobrinha em pixels: matriz 8x8
#88Avançado
Premium

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

4.7(39)
57
4x matriz de LED 32x8 - Pacote de 6 animações
#91Intermediário
Premium

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

4.5(35)
48