Guias · 16 min de leitura

Efeito Super Máquina com Arduino e LED sequencial: circuito, código e controle de velocidade

Monte o efeito Super Máquina (Knight Rider) com Arduino: 8 LEDs com resistores de 220 Ω, código com array e laço for, velocidade no potenciômetro, millis, 74HC595, WS2812B, ESP32 e Pico.

O circuito Super Máquina com Arduino é um efeito de LED clássico em que uma fileira de LEDs acende um após o outro, varrendo de uma ponta à outra e voltando. O nome vem da luz de varredura na frente do KITT, o carro falante da famosa série dos anos 1980 “A Super Máquina” (Knight Rider). Você só precisa de um Arduino Uno, 6 ou 8 LEDs, um resistor de 220 Ω para cada LED e alguns jumpers. Se a luz corre em um só sentido e depois recomeça do início, o efeito se chama LED sequencial ou sequencial de LEDs. Os dois são projetos clássicos que os iniciantes montam logo depois do semáforo, e são o jeito mais divertido de aprender duas das ferramentas mais importantes da programação: os arrays e o laço for.

Neste guia você vai montar o circuito e escrever primeiro o código do LED sequencial e depois o do efeito Super Máquina, que vai e volta. Em seguida, vai ajustar a velocidade com um potenciômetro, acrescentar um efeito em que os LEDs se empilham em uma das pontas e rodar o mesmo efeito com millis(), sem nunca bloquear o código. Nas últimas seções você encontra como controlar 8 LEDs com apenas 3 pinos usando um chip 74HC595, como fazer um efeito Super Máquina com rastro a partir de um único pino usando LEDs endereçáveis WS2812B, as versões para ESP32 e Raspberry Pi Pico (MicroPython) e as soluções para os erros mais comuns.

LEDs de 5 mm vermelhos, amarelos, azuis, verdes e brancos
Para o visual clássico da Super Máquina, use 6 ou 8 LEDs de 5 mm da mesma cor (de preferência vermelhos); a perna longa é o ânodo (+) e a perna curta, o cátodo (−).

O que é o efeito Super Máquina e qual a diferença para o LED sequencial?

Na série, a luz vermelha no para-choque dianteiro do KITT varre para a esquerda e para a direita sem parar, como um olho que vigia tudo. Na eletrônica, esse efeito também é chamado de scanner Larson, em homenagem ao produtor da série, Glen A. Larson; os olhos dos robôs Cylon de outra série dele, Battlestar Galactica, funcionam do mesmo jeito. No scanner de verdade, dá para ver atrás do ponto aceso um brilho vermelho que vai sumindo devagar: o rastro. Em um circuito simples de LEDs, cada LED fica totalmente aceso ou totalmente apagado; para imitar o rastro, é preciso diminuir o brilho dos LEDs aos poucos com PWM. Vamos fazer exatamente isso mais adiante com o WS2812B e o ESP32. A tabela abaixo resume os efeitos que você vai programar neste artigo e quantos passos uma volta leva com 8 LEDs.

EfeitoO que fazUma volta com 8 LEDsNeste artigo
LED sequencialUma única luz corre da esquerda para a direita e depois recomeça8 passosPasso 1
Super MáquinaUma única luz vai e volta entre as duas pontas14 passosPassos 2 e 3
EmpilhamentoCada luz corre até a posição livre mais à direita e fica ali36 passosPasso 4
Encontro no meioDuas luzes vêm das pontas até o meio e depois se afastam8 passosSeção do 74HC595
Super Máquina com rastroO LED da frente fica com brilho total, os de trás vão se apagando14 passosSeções do WS2812B e do ESP32

Lista de materiais e escolha do resistor

ComponenteQtd.Observação
Arduino Uno (ou Nano)1Um ESP32 ou um Raspberry Pi Pico também servem
LED de 5 mm6–8Mesma cor e mesmo lote, para que o brilho pareça igual
Resistor de 220 Ω6–8Um por LED; 330 Ω no Pico
Potenciômetro de 10 kΩ (B10K)1Só para as versões com velocidade ajustável
Protoboard1Meia protoboard (400 furos) é suficiente
Jumpers12–15Macho-macho
74HC595 ou barra WS2812B de 8 LEDs1Opcional: para as seções de economia de pinos e de efeito com rastro

O LED não limita a própria corrente, por isso cada LED recebe um resistor em série. Você encontra o valor com a Lei de Ohm: R = (tensão de alimentação − tensão direta do LED) / corrente. Um LED vermelho tem tensão direta de cerca de 2 V, então, em 5 V com 220 Ω, a corrente é (5 − 2) / 220 ≈ 13,6 mA. Isso acende o LED com um brilho bom e fica abaixo dos 20 mA recomendados para um pino do Arduino. No efeito de empilhamento, quando os oito LEDs estão acesos ao mesmo tempo, a corrente total é de cerca de 109 mA, ainda dentro do limite de 200 mA do Uno para todos os pinos somados. Para reconhecer um resistor de 220 Ω pelas faixas coloridas, use a ferramenta Código de cores; para outras cores e tensões, experimente a calculadora Resistor para LED.

Ligação: 8 LEDs e um potenciômetro

A perna longa (ânodo) de cada LED vai, através de um resistor, a um pino digital da placa, e a perna curta (cátodo) vai ao GND. Na protoboard, o jeito mais organizado é ligar o pino GND do Arduino ao barramento azul (−) da protoboard e levar as pernas curtas dos oito LEDs até esse barramento. Coloque os LEDs com espaçamento igual, da esquerda para a direita, na ordem dos pinos; assim a ordem do array no código corresponde à ordem física da luz. As duas pernas externas do potenciômetro vão ao 5V e ao GND, e a perna do meio (o cursor) vai ao A0. A tabela abaixo mostra os pinos usados por todos os sketches deste artigo; se você usar 6 LEDs, pule as duas últimas linhas de LED e apague os dois últimos pinos do array no código. Você pode ver a disposição dos pinos da sua placa na ferramenta Pinagem.

FunçãoArduino UnoESP32Raspberry Pi Pico
LED 1 (extrema esquerda)D2GPIO 18GP8
LED 2D3GPIO 19GP9
LED 3D4GPIO 21GP10
LED 4D5GPIO 22GP11
LED 5D6GPIO 23GP12
LED 6D7GPIO 25GP13
LED 7D8GPIO 26GP14
LED 8 (extrema direita)D9GPIO 27GP15
Perna do meio do potenciômetroA0GPIO 34GP26 (ADC0)
Pernas externas do potenciômetro5V e GND3V3 e GND3V3(OUT) e AGND
Cátodos dos LEDs (perna curta)GNDGNDGND
Resistor em série220 Ω220 Ω330 Ω
Não ligue LEDs aos pinos D0 e D1: esses pinos são usados para carregar o código pelo USB e pelo Monitor Serial; com LEDs ligados, o carregamento pode falhar e os LEDs piscam de forma aleatória. É por isso que o array começa no D2. Se nenhum LED acender, verifique primeiro se o barramento azul da protoboard está mesmo ligado ao pino GND do Arduino.
Arduino Uno
Arduino Uno
Protoboard
Protoboard
R · Ω
R · Ω
Jumper
Jumper

Passo 1: código do LED sequencial com array e laço for

Você poderia escrever oito linhas separadas de pinMode e dezesseis linhas separadas de digitalWrite para oito LEDs, mas o código fica longo e mudar a quantidade de LEDs vira um trabalhão. Em vez disso, você coloca os números dos pinos em um array (vetor) e o percorre com um laço for. O primeiro elemento do array é LEDS[0], que é o D2; o último é LEDS[7], que é o D9. Assim o mesmo código funciona sem mudanças com 6, 8 ou 12 LEDs; você só edita o array. Os fundamentos de arrays e laços estão explicados com mais detalhes em Programação Arduino do zero.

C++ (Arduino IDE)
1// Yürüyen LED: 8 LED sırayla yanar / Running light: 8 LEDs light up one after another
2const int LEDS[] = {2, 3, 4, 5, 6, 7, 8, 9};             // LED pinleri / LED pins
3const int LED_SAYISI = sizeof(LEDS) / sizeof(LEDS[0]);  // dizideki LED sayısı (8) / number of LEDs (8)
4const int BEKLE = 100;                                  // adım süresi (ms) / step time (ms)
5
6void setup() {
7  for (int i = 0; i < LED_SAYISI; i++) {
8    pinMode(LEDS[i], OUTPUT);                           // tüm LED pinleri çıkış / all LED pins as outputs
9  }
10}
11
12void loop() {
13  for (int i = 0; i < LED_SAYISI; i++) {
14    digitalWrite(LEDS[i], HIGH);                        // sıradaki LED'i yak / light the next LED
15    delay(BEKLE);
16    digitalWrite(LEDS[i], LOW);                         // söndür ve devam et / turn it off and move on
17  }
18}
LinhaO que faz
const int LEDS[] = {2, ..., 9};Array que guarda os pinos dos LEDs em ordem, da esquerda para a direita; LEDS[0] = 2, LEDS[7] = 9
sizeof(LEDS) / sizeof(LEDS[0])Calcula a quantidade de elementos: no Uno, 16 bytes / 2 bytes = 8; o valor se atualiza sozinho quando você adiciona ou remove pinos
for (int i = 0; i < LED_SAYISI; i++)Conta a variável i de 0 a 7; a cada volta, um elemento do array é processado
pinMode(LEDS[i], OUTPUT)Transforma os oito pinos em saídas com um único laço
digitalWrite, delay(BEKLE), digitalWriteAcende o LED, espera BEKLE milissegundos, apaga e passa para o próximo

Com BEKLE (o tempo de cada passo) em 100 ms, a luz percorre os oito LEDs em 0,8 segundo e recomeça na hora. Baixe para 30 ms e o fluxo fica muito rápido; suba para 300 ms e ele parece lento, como lâmpadas acendendo uma a uma. Para carregar o código, selecione a placa e a porta no menu Ferramentas e clique em Carregar; se o carregamento falhar, siga a lista de verificação em Erro ao carregar código no Arduino.

Passo 2: código do efeito Super Máquina (vai e volta)

No efeito Super Máquina, a luz precisa dar meia-volta ao chegar à ponta direita. Você faz isso com dois laços: o primeiro conta da esquerda para a direita e o segundo, da direita para a esquerda. O ponto delicado aqui são os LEDs das pontas. Se os dois laços contarem completos, de 0 a 7 e de 7 a 0, o LED mais à direita acende uma vez no fim do laço de ida e outra vez no começo do laço de volta; a luz fica o dobro do tempo nas pontas e o movimento parece engasgar. Por isso o laço de ida para no 6 e o de volta, no 1. Com isso, cada volta leva exatamente 14 passos e a luz fica nas pontas o mesmo tempo que no meio. Também passamos as três linhas que acendem e apagam um LED para uma pequena função chamada yakSondur() (“acender e apagar”, em turco); o código fica mais curto e mais fácil de ler.

C++ (Arduino IDE)
1// Karaşimşek (Knight Rider): ışık iki uç arasında gidip gelir / light bounces between the two ends
2const int LEDS[] = {2, 3, 4, 5, 6, 7, 8, 9};
3const int LED_SAYISI = sizeof(LEDS) / sizeof(LEDS[0]);
4const int BEKLE = 80;                                   // adım süresi (ms) / step time (ms)
5
6void yakSondur(int i) {
7  digitalWrite(LEDS[i], HIGH);
8  delay(BEKLE);
9  digitalWrite(LEDS[i], LOW);
10}
11
12void setup() {
13  for (int i = 0; i < LED_SAYISI; i++) pinMode(LEDS[i], OUTPUT);
14}
15
16void loop() {
17  for (int i = 0; i < LED_SAYISI - 1; i++) {           // soldan sağa: 0..6 / left to right: 0..6
18    yakSondur(i);
19  }
20  for (int i = LED_SAYISI - 1; i > 0; i--) {           // sağdan sola: 7..1 / right to left: 7..1
21    yakSondur(i);
22  }
23}
A velocidade mais parecida com a da série é de cerca de 60–120 ms por passo. Com 8 LEDs e 80 ms, uma volta completa de ida e volta leva 14 × 80 = 1,12 segundo. Quando você desce para algo em torno de 20 ms, o olho enxerga vários LEDs acesos ao mesmo tempo e a luz vira uma linha borrada.

Passo 3: controle de velocidade com potenciômetro

Em vez de mudar o código e carregá-lo de novo toda vez que quiser outra velocidade, você pode usar um potenciômetro. Um potenciômetro é um divisor de tensão: a tensão na perna do meio varia entre 0 e 5 V conforme a posição do eixo, e o analogRead() transforma isso em um número entre 0 e 1023. map(deger, 0, 1023, 400, 20) converte esse número em um tempo de passo entre 400 e 20 ms; como a faixa está escrita ao contrário, quanto maior a leitura, menor o passo e mais rápida a luz. Para que lado você precisa girar o eixo para acelerar depende de qual perna externa você ligou ao 5V; se parecer invertido, troque os dois fios externos de lugar ou inverta o 400 e o 20 no map(). Você pode ler como um potenciômetro funciona por dentro em O que é um potenciômetro?.

Potenciômetro de 10 kΩ
Potenciômetro de 10 kΩ: as pernas externas vão ao 5V e ao GND, e a perna do meio (cursor) vai ao A0.
C++ (Arduino IDE)
1// Hız ayarlı karaşimşek: potansiyometre adım süresini belirler / Speed-adjustable Knight Rider: the pot sets the step time
2const int LEDS[] = {2, 3, 4, 5, 6, 7, 8, 9};
3const int LED_SAYISI = sizeof(LEDS) / sizeof(LEDS[0]);
4const int POT = A0;                                     // potansiyometrenin orta bacağı / pot wiper
5
6int adimSuresi() {
7  int deger = analogRead(POT);                          // 0–1023
8  return map(deger, 0, 1023, 400, 20);                  // değer büyüdükçe hızlanır / faster as the value rises
9}
10
11void yakSondur(int i) {
12  digitalWrite(LEDS[i], HIGH);
13  delay(adimSuresi());                                  // her adımda yeniden okunur / read again on every step
14  digitalWrite(LEDS[i], LOW);
15}
16
17void setup() {
18  for (int i = 0; i < LED_SAYISI; i++) pinMode(LEDS[i], OUTPUT);
19}
20
21void loop() {
22  for (int i = 0; i < LED_SAYISI - 1; i++) yakSondur(i);   // sağa / to the right
23  for (int i = LED_SAYISI - 1; i > 0; i--) yakSondur(i);   // sola / to the left
24}

Nesta versão, o tempo do passo é lido de novo a cada LED, então a velocidade muda no instante em que você gira o eixo. Porém, enquanto o delay() está rodando, o Arduino não consegue fazer mais nada: mesmo que você gire o eixo no meio de um passo lento de 400 ms, a nova velocidade só vale a partir do passo seguinte. Para um efeito com poucos LEDs isso não é problema, mas, quando você acrescentar um botão de modo ou leituras de sensores, vai precisar passar para o método com millis() do passo 5.

Passo 4: o efeito de empilhamento

No efeito de empilhamento, a primeira luz corre até o fim e fica acesa na extremidade direita. A segunda luz também corre, mas desta vez para uma posição antes, mais à esquerda; a cada volta o alvo se desloca um LED para a esquerda, até a barra inteira ficar cheia. No código, você faz isso com dois laços aninhados: o laço externo conta quantos LEDs já se empilharam (dolu, “cheio” em turco), e o laço interno conta quantos passos a luz corre nesta volta. O LED que chega ao seu alvo (hedef) não é apagado; a linha if (i < hedef) cuida exatamente disso. Com oito LEDs, encher a barra inteira leva 8 + 7 + 6 + ... + 1 = 36 passos.

C++ (Arduino IDE)
1// Birikerek dolan efekt: her ışık en boş uca kadar gider ve orada kalır / Stacking effect: each light runs to the last free spot and stays
2const int LEDS[] = {2, 3, 4, 5, 6, 7, 8, 9};
3const int LED_SAYISI = sizeof(LEDS) / sizeof(LEDS[0]);
4const int BEKLE = 60;
5
6void setup() {
7  for (int i = 0; i < LED_SAYISI; i++) pinMode(LEDS[i], OUTPUT);
8}
9
10void loop() {
11  for (int dolu = 0; dolu < LED_SAYISI; dolu++) {       // dolu: sağda birikmiş LED sayısı / LEDs already stacked on the right
12    int hedef = LED_SAYISI - 1 - dolu;                  // bu turda ışığın duracağı yer / where the light stops this round
13    for (int i = 0; i <= hedef; i++) {
14      digitalWrite(LEDS[i], HIGH);
15      delay(BEKLE);
16      if (i < hedef) digitalWrite(LEDS[i], LOW);        // hedefte yanık kalır / stays lit at the target
17    }
18  }
19  delay(600);                                           // dolu çubuğu göster / show the full bar
20  for (int i = LED_SAYISI - 1; i >= 0; i--) {           // sağdan sola boşalt / empty from right to left
21    digitalWrite(LEDS[i], LOW);
22    delay(BEKLE);
23  }
24  delay(300);
25}

No fim do sketch, a barra cheia aparece por 0,6 segundo; depois os LEDs se apagam um a um, da direita para a esquerda, e o efeito recomeça. Se você quiser uma barra que enche mais simples, basta tirar o laço interno e acender os LEDs em ordem sem nunca apagá-los; esse visual é ideal para um indicador de carga ou uma barra de nível de som. Lembre-se de que neste efeito os oito LEDs ficam acesos ao mesmo tempo: desde que cada LED tenha o próprio resistor, o brilho não cai.

Passo 5: efeito Super Máquina sem bloqueio com millis()

Em um código que usa delay(), o Arduino congela pelo tempo indicado a cada passo; mesmo que alguém aperte um botão nesse meio-tempo, ele não percebe. Já o millis() retorna o tempo em milissegundos desde que a placa foi ligada. A lógica é a seguinte: o loop() roda o tempo todo, verifica a cada ciclo se já passou tempo suficiente desde o último passo, dá apenas um passo se tiver passado e sai de novo imediatamente. No código abaixo, o efeito Super Máquina e o LED da placa rodam ao mesmo tempo como duas tarefas independentes: enquanto o scanner varre na velocidade definida pelo potenciômetro, o LED no D13 pisca uma vez por segundo, no seu próprio ritmo. Para saber mais sobre o assunto, veja millis() em vez de delay() no Arduino.

C++ (Arduino IDE)
1// millis() ile bekletmesiz karaşimşek + potansiyometre / Non-blocking Knight Rider with millis() + pot
2const int LEDS[] = {2, 3, 4, 5, 6, 7, 8, 9};
3const int LED_SAYISI = sizeof(LEDS) / sizeof(LEDS[0]);
4const int POT = A0;
5
6int konum = 0;                     // şu an yanan LED / the LED that is lit now
7int yon = 1;                       // +1 sağa, -1 sola / +1 right, -1 left
8unsigned long sonAdim = 0;         // son adımın zamanı / time of the last step
9unsigned long sonBlink = 0;        // dahili LED için / for the onboard LED
10
11void setup() {
12  for (int i = 0; i < LED_SAYISI; i++) pinMode(LEDS[i], OUTPUT);
13  pinMode(LED_BUILTIN, OUTPUT);    // Uno'da D13 / D13 on the Uno
14  digitalWrite(LEDS[konum], HIGH);
15}
16
17void loop() {
18  unsigned long simdi = millis();
19  unsigned long aralik = map(analogRead(POT), 0, 1023, 400, 20);   // adım süresi (ms) / step time (ms)
20
21  // Görev 1: karaşimşek / Task 1: Knight Rider
22  if (simdi - sonAdim >= aralik) {          // taşmaya karşı güvenli / overflow-safe
23    sonAdim = simdi;
24    digitalWrite(LEDS[konum], LOW);
25    konum += yon;
26    if (konum == LED_SAYISI - 1 || konum == 0) yon = -yon;   // uçta yön değiştir / reverse at the ends
27    digitalWrite(LEDS[konum], HIGH);
28  }
29
30  // Görev 2: dahili LED kendi temposunda yanıp söner / Task 2: the onboard LED blinks at its own pace
31  if (simdi - sonBlink >= 500) {
32    sonBlink = simdi;
33    digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN));
34  }
35  // Buraya buton, sensör ya da seri port kodu eklenebilir / button, sensor or serial code can go here
36}

Dois detalhes importam aqui. Primeiro, as variáveis de tempo precisam ser unsigned long; se você usar int, o valor estoura no Uno depois de cerca de 32,7 segundos e a temporização quebra: o efeito para ou acelera sem controle. Segundo, a comparação é feita com uma subtração na forma simdi - sonAdim >= aralik (agora menos o último passo, comparado com o intervalo); esse método continua funcionando corretamente mesmo quando o millis() volta a zero, o que acontece aproximadamente a cada 49,7 dias. Como guardamos a posição e o sentido da luz em duas variáveis (konum e yon), não há mais laços: a cada passo a posição sobe ou desce uma unidade e, nas pontas, o sentido troca de sinal.

8 LEDs com 3 pinos usando um 74HC595

Oito LEDs ocupam oito pinos do Uno; quando você quiser acrescentar um LCD, sensores e botões ao projeto, os pinos começam a faltar. O registrador de deslocamento 74HC595 controla suas oito saídas com apenas três pinos do Arduino (dados, clock e latch). O estado de cada LED é um bit de um byte: a expressão 1 << i coloca só o bit i em 1, o que acende um único LED. Montar padrões com operações de bits também é fácil: (1 << i) | (0x80 >> i) produz duas luzes que vêm das duas pontas em direção ao meio ao mesmo tempo. Ligando dois chips em cascata, você também consegue montar um efeito Super Máquina de 16 LEDs com os mesmos três pinos; a ligação em cascata, o controle rápido por SPI e o uso de displays de 7 segmentos são explicados passo a passo no artigo 74HC595: registrador de deslocamento.

Pino do 74HC595Ligação (Arduino Uno)
DS (14)D11
SH_CP (11)D13
ST_CP (12)D10
OE (13)GND (saídas sempre ativadas)
MR (10)5V (reset desativado)
VCC (16) / GND (8)5V / GND, com um capacitor de 100 nF ao lado
Q0 (15), Q1–Q7 (1–7)Cada uma através de 470 Ω até o ânodo de um LED
Perna do meio do potenciômetroA0
C++ (Arduino IDE)
1// 74HC595 ile 3 pinden 8 LED: karaşimşek ve ortada buluşma / 8 LEDs from 3 pins with a 74HC595: Knight Rider and meet-in-the-middle
2const int DATA_PIN = 11;    // DS (14)
3const int CLOCK_PIN = 13;   // SH_CP (11)
4const int LATCH_PIN = 10;   // ST_CP (12)
5const int POT = A0;
6
7void yaz595(byte desen) {
8  digitalWrite(LATCH_PIN, LOW);
9  shiftOut(DATA_PIN, CLOCK_PIN, MSBFIRST, desen);   // 8 biti gönder / send the 8 bits
10  digitalWrite(LATCH_PIN, HIGH);                    // çıkışlara aktar / copy to the outputs
11}
12
13void setup() {
14  pinMode(DATA_PIN, OUTPUT);
15  pinMode(CLOCK_PIN, OUTPUT);
16  pinMode(LATCH_PIN, OUTPUT);
17  yaz595(0);                                        // açılışta hepsi sönük / all off at startup
18}
19
20void loop() {
21  int bekle = map(analogRead(POT), 0, 1023, 400, 20);
22
23  for (int i = 0; i < 7; i++) { yaz595(1 << i); delay(bekle); }   // Q0 -> Q7
24  for (int i = 7; i > 0; i--) { yaz595(1 << i); delay(bekle); }   // Q7 -> Q0
25
26  for (int i = 0; i < 4; i++) {                     // uçlardan ortaya / from the ends to the middle
27    yaz595((1 << i) | (0x80 >> i));
28    delay(bekle);
29  }
30  for (int i = 3; i >= 0; i--) {                    // ortadan uçlara / from the middle to the ends
31    yaz595((1 << i) | (0x80 >> i));
32    delay(bekle);
33  }
34}

Nas saídas do 74HC595 recomenda-se 470 Ω em vez de 220 Ω: a corrente total pelos pinos VCC e GND do chip não deve passar de 70 mA. Com 470 Ω passam cerca de 6,4 mA por LED e, mesmo com os oito LEDs acesos, o total fica em 51 mA. No efeito Super Máquina só um ou dois LEDs ficam acesos por vez, então os LEDs continuam bem visíveis.

Super Máquina com rastro a partir de um único pino com WS2812B

A versão mais parecida com o scanner real do KITT é feita com LEDs endereçáveis WS2812B. Cada WS2812B tem o próprio driver embutido; não importa o comprimento da fita, você define a cor e o brilho de cada LED individualmente por um único fio de dados. Para o rastro, mantemos um array: a cada passo, o brilho de todos os LEDs é dividido por três e o LED da frente recebe 255. Assim, os LEDs de trás se apagam rapidamente passando por 255, 85, 28, 9, o que deixa um rastro natural atrás da luz. Use 2 em vez de 3 como divisor e o rastro fica mais longo; use 5 e ele fica mais curto. Para passar de 8 para 60 LEDs com o mesmo método, basta mudar NUM_LEDS.

LED RGB endereçável WS2812B
WS2812B: cada LED tem o próprio driver interno; ele é ligado por DIN, 5V e GND, e o DOUT segue para o próximo LED.
C++ (Arduino IDE)
1// WS2812B ile kuyruklu karaşimşek (tek veri pini) / Knight Rider with a fading tail on WS2812B (one data pin)
2#include <Adafruit_NeoPixel.h>
3
4const int DATA_PIN = 6;      // DIN, 330 Ω üzerinden / DIN through 330 Ω
5const int NUM_LEDS = 8;      // şerit ya da çubuktaki LED sayısı / LEDs on the strip or stick
6const int POT = A0;
7
8Adafruit_NeoPixel strip(NUM_LEDS, DATA_PIN, NEO_GRB + NEO_KHZ800);
9
10uint8_t seviye[NUM_LEDS];    // her LED'in kırmızı parlaklığı / red brightness of each LED
11int konum = 0;
12int yon = 1;
13
14void setup() {
15  strip.begin();
16  strip.setBrightness(80);   // 0–255; USB için düşük tut / keep it low on USB power
17  strip.show();              // hepsini söndür / all off
18}
19
20void loop() {
21  for (int i = 0; i < NUM_LEDS; i++) seviye[i] = seviye[i] / 3;   // kuyruk söner / the tail fades
22  seviye[konum] = 255;                                            // baştaki LED tam parlak / the head is full brightness
23
24  for (int i = 0; i < NUM_LEDS; i++) {
25    strip.setPixelColor(i, strip.Color(seviye[i], 0, 0));         // yalnız kırmızı / red only
26  }
27  strip.show();
28
29  konum += yon;
30  if (konum == NUM_LEDS - 1 || konum == 0) yon = -yon;            // uçta yön değiştir / reverse at the ends
31  delay(map(analogRead(POT), 0, 1023, 150, 20));
32}
Ao ligar um WS2812B, coloque um resistor de 330 Ω em série com a linha de dados e um capacitor de 1000 µF entre 5V e GND e, se usar uma fonte de alimentação externa, ligue o GND dela ao GND do Arduino. Cada LED pode consumir cerca de 60 mA em branco total; uma barra de 8 LEDs funciona pelo USB, mas 30 LEDs ou mais precisam de uma fonte separada de 5 V. Para instalação da biblioteca, ordem das cores e cálculo da alimentação, veja o artigo Fita de LED WS2812B (NeoPixel).

Super Máquina no ESP32: rastro com PWM em todos os pinos

No Uno, é difícil fazer um efeito Super Máquina com rastro usando LEDs comuns, porque o PWM só existe nos pinos 3, 5, 6, 9, 10 e 11, e o nosso array D2–D9 contém apenas quatro deles. No ESP32, graças ao hardware LEDC, quase todo pino de saída consegue gerar PWM, e o ESP32 clássico tem 16 canais de PWM. Como o analogWrite() funciona diretamente no core atual do ESP32 para Arduino, você pode aplicar a lógica de rastro do WS2812B a LEDs comuns. Os pinos da tabela são GPIOs seguros, que não afetam a inicialização; o potenciômetro vai ao GPIO 34, no canal ADC1, que lê de forma confiável mesmo com o Wi-Fi ligado, e, como o ADC do ESP32 é de 12 bits, o valor vai de 0 a 4095. Os pinos do ESP32 fornecem 3,3 V, então passam cerca de 6 mA por um LED vermelho com 220 Ω; os LEDs ficam um pouco mais fracos do que no Uno. Para configurar a placa, veja O que é o ESP32?.

C++ (Arduino IDE)
1// ESP32: her pinde PWM ile kuyruklu karaşimşek / ESP32: Knight Rider with a PWM tail on every pin
2const int LEDS[] = {18, 19, 21, 22, 23, 25, 26, 27};
3const int LED_SAYISI = sizeof(LEDS) / sizeof(LEDS[0]);
4const int POT = 34;                        // ADC1, yalnızca giriş / ADC1, input only
5
6int parlaklik[LED_SAYISI];                 // 0–255
7int konum = 0;
8int yon = 1;
9unsigned long sonAdim = 0;
10
11void setup() {
12  // analogWrite() pini PWM için kendisi hazırlar / analogWrite() sets the pin up for PWM itself
13}
14
15void loop() {
16  unsigned long aralik = map(analogRead(POT), 0, 4095, 400, 20);   // ESP32 ADC 12 bit: 0–4095
17  if (millis() - sonAdim >= aralik) {
18    sonAdim = millis();
19    for (int i = 0; i < LED_SAYISI; i++) parlaklik[i] /= 3;        // kuyruk söner / the tail fades
20    parlaklik[konum] = 255;
21    for (int i = 0; i < LED_SAYISI; i++) analogWrite(LEDS[i], parlaklik[i]);
22    konum += yon;
23    if (konum == LED_SAYISI - 1 || konum == 0) yon = -yon;
24  }
25}

Super Máquina no Raspberry Pi Pico com MicroPython

No Raspberry Pi Pico, você escreve o mesmo efeito em poucas linhas de MicroPython. Guardar os objetos Pin em uma lista faz o mesmo papel do array no Arduino. time.ticks_ms() e time.ticks_diff() são os equivalentes em MicroPython do millis() e da subtração segura contra estouro. O potenciômetro vai ao GP26 (ADC0); read_u16() retorna um valor de 0 a 65535, e o código o converte para 400–20 ms. Recomenda-se que a corrente total puxada de todos os GPIOs do Pico fique abaixo de 50 mA; por isso escolhemos 330 Ω na tabela: passam cerca de 4 mA por LED e, mesmo com os oito LEDs acesos, o total fica em torno de 32 mA. O projeto Super Máquina para Pico do app BlueGrays usa 6 LEDs nos pinos GP9–GP14; se você montou esse circuito, basta mudar a lista PINLER para [9, 10, 11, 12, 13, 14]. Para a instalação e o carregamento de código com o Thonny, veja O que é o Raspberry Pi Pico?.

MicroPython
1# Raspberry Pi Pico: potansiyometreyle hız ayarlı karaşimşek / Pico: Knight Rider with pot speed control
2from machine import Pin, ADC
3import time
4
5PINLER = [8, 9, 10, 11, 12, 13, 14, 15]        # GP8–GP15
6leds = [Pin(p, Pin.OUT) for p in PINLER]
7pot = ADC(26)                                   # GP26 = ADC0
8
9def adim_suresi():
10    # read_u16: 0–65535 -> 400–20 ms
11    return 400 - pot.read_u16() * 380 // 65535
12
13konum, yon = 0, 1
14leds[konum].on()
15son = time.ticks_ms()
16
17while True:
18    if time.ticks_diff(time.ticks_ms(), son) >= adim_suresi():   # millis() benzeri / like millis()
19        son = time.ticks_ms()
20        leds[konum].off()
21        konum += yon
22        if konum == len(leds) - 1 or konum == 0:
23            yon = -yon                          # uçta yön değiştir / reverse at the ends
24        leds[konum].on()

Todo GPIO do Pico também gera PWM; com machine.PWM e um valor de duty_u16() para cada LED, você pode levar o efeito com rastro do ESP32 para o Pico. Se quiser usar LEDs WS2812B, o módulo neopixel embutido no MicroPython controla uma fita a partir de um único GPIO; porém, um WS2812B alimentado com 5 V nem sempre lê com confiabilidade o sinal de dados de 3,3 V do Pico, então, se as cores falharem, coloque um conversor de nível lógico no meio.

Ideias de projetos com o efeito Super Máquina

  • Medidor de nível de som (VU meter): use a intensidade sonora medida com um sensor de som KY-038 para decidir quantos LEDs da barra que enche vão acender.
  • Barra de LEDs de sensor de estacionamento: acenda mais LEDs à medida que a distância medida com um HC-SR04 diminui e faça todos piscarem quando chegar muito perto.
  • Jogo de pegar a luz: enquanto o scanner varre rapidamente, tente apertar um botão exatamente quando o LED do meio estiver aceso; diminua o tempo do passo a cada acerto.
  • Decoração noturna automática: faça o efeito começar sozinho quando um LDR detectar que está escurecendo.
  • Lanterna traseira para carrinho de modelismo ou bicicleta: faça um efeito Super Máquina vermelho com rastro em uma barra WS2812B e acenda todos os LEDs com brilho total quando o botão de freio for apertado.
  • Indicador de nível: mostre a posição de um potenciômetro ou a tensão de uma bateria como uma barra que enche.
  • Displays maiores: leve a mesma lógica para uma matriz de LED MAX7219 ou um cubo de LED.

Erros comuns e como corrigir

SintomaCausaSolução
Os LEDs acendem muito fracosFalta o pinMode(OUTPUT); o digitalWrite só liga o resistor de pull-up internoDefina todos os pinos como OUTPUT com um laço no setup()
Um LED nunca acendeO LED está invertido, ou um resistor ou fio está deslocado uma fileiraPerna longa no resistor e no pino, perna curta no GND; teste o LED sozinho com 5V e um resistor
Os LEDs das pontas ficam acesos o dobro do tempoOs dois laços incluem os LEDs das pontasUse i < LED_SAYISI − 1 no laço de ida e i > 0 no laço de volta
Um pino aleatório pisca ou o programa se comporta de forma estranhaLeitura além do fim do array: i <= LED_SAYISIMude a condição para i < LED_SAYISI; não existe o elemento LEDS[8]
O código não carrega ou os LEDs piscam durante o carregamentoHá LEDs ligados ao D0 e ao D1Comece o array no D2
O potenciômetro não muda a velocidadeUma perna externa está ligada ao A0 em vez da perna do meio, ou o valor é lido só uma vez, fora do laçoLigue a perna do meio ao A0; chame analogRead a cada passo
O efeito dá problema depois de uns 32 segundosO valor de millis() é guardado em uma variável intDeclare as variáveis de tempo como unsigned long
Os WS2812B não acendem ou mostram cores aleatóriasFalta GND comum, falta o resistor de dados ou a fita foi ligada pela ponta errada (DOUT)Una os GNDs, acrescente 330 Ω e ligue pela ponta DIN, de onde as setas partem
Antes de montar o circuito, você pode testar o código no Tinkercad com 8 LEDs e um potenciômetro. Se algo der errado no circuito real, carregue um sketch curto que deixa todos os pinos em HIGH por alguns segundos para testar os LEDs um a um; você vai ver na hora qual LED não acende.

O efeito Super Máquina parece simples, mas reúne as ideias básicas que você vai usar depois em todo projeto: arrays, laços, leituras analógicas, map(), temporização sem bloqueio, operações de bits e LEDs endereçáveis. Como próximo passo, dê uma olhada no projeto Semáforo com Arduino ou na lista de ideias de projetos com Arduino. No app BlueGrays você encontra o LED sequencial, o Super Máquina e as versões com velocidade ajustável, os efeitos de empilhamento e Super Máquina com WS2812B e os projetos de LED sequencial com ESP32 e Super Máquina com Pico, cada um com esquema do circuito passo a passo e código pronto para testar na sua própria placa.

Perguntas frequentes

Quantos LEDs um Arduino Uno consegue controlar?

O Uno tem 20 pinos que podem ser usados como saídas digitais, D0–D13 e A0–A5; se você deixar D0 e D1 livres para a comunicação serial, consegue controlar 18 LEDs diretamente. Dê a cada LED o próprio resistor e mantenha a corrente total abaixo de 200 mA; se os 18 forem ficar acesos ao mesmo tempo, escolha 330 Ω ou mais. Para mais LEDs, use um registrador de deslocamento 74HC595 ou uma fita WS2812B, que controla centenas de LEDs a partir de um único pino.

Que resistor usar em um sequencial de LEDs?

Em um Arduino Uno de 5 V, 220 Ω serve para LEDs vermelhos e dá cerca de 13,6 mA por LED; 330 Ω também funciona, mas os LEDs ficam um pouco mais fracos. No ESP32 de 3,3 V recomenda-se 220 Ω e, no Pico, 330 Ω. Em efeitos em que só um LED fica aceso, um único resistor compartilhado também funciona, mas o brilho cai quando vários LEDs acendem; por isso, um resistor por LED é a escolha certa.

Dá para montar o circuito Super Máquina sem Arduino?

Sim, o jeito clássico é com um CI 555 timer e um chip contador CD4017. O 555 gera os pulsos de clock e o 4017 coloca suas 10 saídas em HIGH uma após a outra, o que por si só já dá um LED sequencial. Para o movimento de vai e volta, as saídas são combinadas com diodos: as 10 saídas são ligadas a 6 LEDs na ordem 1-2-3-4-5-6-5-4-3-2, e a velocidade é ajustada com um potenciômetro no 555.

Qual a diferença entre LED sequencial e efeito Super Máquina?

No LED sequencial, a luz corre em um só sentido e recomeça depois do último LED; com 8 LEDs, uma volta tem 8 passos. No efeito Super Máquina, a luz dá meia-volta na ponta e vai e volta entre as duas extremidades; com 8 LEDs, uma volta tem 14 passos. A diferença no código também é pequena: para o Super Máquina você acrescenta um segundo laço, que conta de trás para frente.

Por que usar millis() em vez de delay() em um sequencial de LEDs?

Enquanto o delay() está rodando, o Arduino não consegue fazer mais nada; ele perde toques em botões e não lê sensores. Com millis(), cada passagem pelo loop() só dá um passo quando o tempo se esgota, e as outras tarefas rodam no tempo restante. Assim, enquanto o scanner varre, botões, potenciômetros ou comandos pela serial respondem na hora.

Como adicionar um rastro ao efeito Super Máquina?

Para o rastro, você precisa diminuir aos poucos o brilho dos LEDs que vêm atrás do LED da frente, o que exige PWM. No Uno, o PWM só existe nos pinos 3, 5, 6, 9, 10 e 11, então dá para montar um efeito Super Máquina com rastro de 6 LEDs nesses pinos. O caminho mais fácil é uma fita WS2812B, em que você ajusta cada LED individualmente, ou um ESP32 ou Pico, que têm PWM em todos os pinos.

Ver todos os projetos
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
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 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
Sequencial de LEDs com velocidade ajustável
#7Intermediário

Sequencial de LEDs com velocidade ajustável

Seis LEDs acendem um após o outro, fazendo a luz parecer correr de uma ponta à outra. Ao girar o botão do potenciômetro, a velocidade muda na hora: para um lado, a luz corre rapidamente; para o outro,

4.6(72)
146
Efeito Super Máquina com WS2812B
#73Intermediário
Premium

Efeito Super Máquina com WS2812B

Um ponto de luz vermelho desliza de uma ponta à outra de uma fita LED inteligente e volta, indo e vindo sem parar. A cada passo, o Arduino acende apenas um LED, espera um décimo de segundo e passa ao

4.9(73)
94
LED sequencial com WS2812B (efeito de preenchimento)
#72Intermediário
Premium

LED sequencial com WS2812B (efeito de preenchimento)

Uma fita de luz que enche e esvazia como um copo de água. O Arduino acende dez LEDs coloridos em laranja, um por vez, e os mantém acesos; quando a fita está cheia, apaga um por vez na mesma ordem, e o

4.7(50)
65
LEDs sequenciais com ESP32
#108Iniciante

LEDs sequenciais com ESP32

6 LEDs se acendem em sequência da esquerda para a direita e da direita para a esquerda, no estilo Knight Rider. Um exemplo básico de uso de laços for e arrays. Ensina a lógica de mudança de direção.

4.5(19)
32
Raspberry Pi Pico: efeito Knight Rider com LEDs (6 LEDs em vaivém)
#154Iniciante

Raspberry Pi Pico: efeito Knight Rider com LEDs (6 LEDs em vaivém)

Efeito clássico de LEDs do "Knight Rider" com o Pico! 6 LEDs acendem da esquerda para a direita e depois no sentido contrário, sem parar. Como a grade dianteira do carro KITT da famosa série dos anos 80. Este projeto é uma evolução do projeto LEDs em sequência: o mesmo circuito com 6 LEDs (GP9-GP14), com outro padrão de código. Aprenda a inverter listas com reversed(), usar dois laços for separados para o vaivém e criar várias animações no mesmo circuito.

0.0(0)
13