Guide · 15 min di lettura

Effetto Supercar con Arduino: LED in sequenza, circuito e codice

Effetto Supercar con Arduino: 8 LED e 220 Ω, codice con array e ciclo for, velocità col potenziometro, millis, 74HC595, WS2812B, ESP32 e Raspberry Pi Pico.

L'effetto Supercar con Arduino è un classico gioco di luci in cui una fila di LED si accende uno dopo l'altro, scorrendo da un'estremità all'altra e tornando indietro, proprio come la luce frontale di KITT, l'auto parlante della famosa serie anni '80 Supercar (Knight Rider in originale). Ti bastano un Arduino Uno, 6 o 8 LED, una resistenza da 220 Ω per ogni LED e qualche cavetto jumper. Se la luce scorre in una sola direzione e poi riparte dall'inizio, si parla di LED in sequenza o luci rincorrenti. Sono due progetti classici che si fanno subito dopo il semaforo, e il modo più divertente per imparare due degli strumenti più importanti della programmazione: gli array e il ciclo for.

In questa guida monterai il circuito e scriverai prima il codice dei LED in sequenza, poi quello dell'effetto Supercar che va avanti e indietro. Poi regolerai la velocità con un potenziometro, aggiungerai un effetto in cui i LED si accumulano a un'estremità e farai girare lo stesso effetto con millis(), senza mai bloccare il codice. Nelle ultime sezioni vedrai come pilotare 8 LED con soli 3 pin usando il chip 74HC595, come realizzare un effetto Supercar con scia da un unico pin con i LED indirizzabili WS2812B, le versioni per ESP32 e Raspberry Pi Pico (MicroPython) e le soluzioni agli errori più comuni.

LED da 5 mm rossi, gialli, blu, verdi e bianchi
Per il classico look Supercar usa 6 o 8 LED da 5 mm dello stesso colore (meglio rossi); la gamba lunga è l'anodo (+), quella corta il catodo (−).

Che cos'è l'effetto Supercar e che differenza c'è con i LED in sequenza?

Nella serie, la luce rossa sul paraurti anteriore di KITT scorre senza sosta da sinistra a destra, come un occhio che scruta. In elettronica questo effetto si chiama anche scanner Larson (Larson scanner), dal nome del produttore della serie, Glen A. Larson; gli occhi dei robot Cylon della sua altra serie, Galactica, funzionano allo stesso modo. Nello scanner vero, dietro il punto acceso si vede una traccia rossa che si spegne lentamente, una scia. In un semplice circuito a LED ogni LED è o tutto acceso o tutto spento; per imitare la scia bisogna abbassare la luminosità dei LED in modo graduale con il PWM. Lo faremo più avanti con i WS2812B e l'ESP32. La tabella riassume gli effetti che programmerai in questo articolo e quanti passi dura un giro con 8 LED.

EffettoCosa faUn giro con 8 LEDIn questo articolo
LED in sequenzaUna sola luce scorre da sinistra a destra e poi riparte8 passiPasso 1
SupercarUna sola luce va avanti e indietro tra le due estremità14 passiPassi 2 e 3
AccumuloOgni luce corre fino all'ultimo posto libero a destra e lì resta36 passiPasso 4
Incontro al centroDue luci arrivano dalle estremità al centro, poi si allontanano8 passiSezione 74HC595
Supercar con sciaIl LED di testa è al massimo, quelli dietro si spengono gradualmente14 passiSezioni WS2812B ed ESP32

Materiali e scelta della resistenza

ComponenteQuantitàNota
Arduino Uno (o Nano)1Va bene anche un ESP32 o un Raspberry Pi Pico
LED da 5 mm6–8Stesso colore e stesso lotto, così la luminosità è uguale
Resistenza da 220 Ω6–8Una per LED; 330 Ω sul Pico
Potenziometro da 10 kΩ (B10K)1Solo per le versioni a velocità regolabile
Breadboard1Basta mezza breadboard (400 fori)
Cavetti jumper12–15Maschio-maschio
74HC595 o stick WS2812B da 8 LED1Facoltativo: per le sezioni sul risparmio di pin e sull'effetto scia

Un LED non limita da solo la propria corrente, quindi ogni LED ha una resistenza in serie. Il valore si calcola con la legge di Ohm: R = (tensione di alimentazione − tensione diretta del LED) / corrente. Un LED rosso ha una tensione diretta di circa 2 V, quindi a 5 V con 220 Ω la corrente è (5 − 2) / 220 ≈ 13,6 mA. Il LED si accende bello luminoso e resti sotto i 20 mA consigliati per un pin di Arduino. Nell'effetto ad accumulo, quando tutti e otto i LED sono accesi insieme, la corrente totale è di circa 109 mA, ancora entro il limite di 200 mA che l'Uno accetta sommando tutti i pin. Per riconoscere una resistenza da 220 Ω dalle sue fasce colorate usa lo strumento codice colori delle resistenze; per altri colori e tensioni, il calcolatore di resistenza per LED.

Collegamenti: 8 LED e un potenziometro

La gamba lunga (anodo) di ogni LED va a un pin digitale della scheda attraverso una resistenza, la gamba corta (catodo) va a GND. Sulla breadboard la soluzione più ordinata è collegare il pin GND di Arduino alla linea blu (−) e portare lì le gambe corte di tutti e otto i LED. Disponi i LED a distanza regolare, da sinistra a destra nell'ordine dei pin: così l'ordine dell'array nel codice corrisponde all'ordine reale della luce. Le due gambe esterne del potenziometro vanno a 5V e GND, quella centrale (il cursore) va ad A0. La tabella mostra i pin usati da tutti i codici di questo articolo; se usi 6 LED, salta le ultime due righe dei LED e cancella gli ultimi due pin dall'array nel codice. Puoi vedere la piedinatura della tua scheda con lo strumento Pinout.

FunzioneArduino UnoESP32Raspberry Pi Pico
LED 1 (tutto a sinistra)D2GPIO 18GP8
LED 2D3GPIO 19GP9
LED 3D4GPIO 21GP10
LED 4D5GPIO 22GP11
LED 5D6GPIO 23GP12
LED 6D7GPIO 25GP13
LED 7D8GPIO 26GP14
LED 8 (tutto a destra)D9GPIO 27GP15
Gamba centrale del potenziometroA0GPIO 34GP26 (ADC0)
Gambe esterne del potenziometro5V e GND3V3 e GND3V3(OUT) e AGND
Catodi dei LED (gamba corta)GNDGNDGND
Resistenza in serie220 Ω220 Ω330 Ω
Non collegare LED ai pin D0 e D1: servono per caricare lo sketch via USB e per il Monitor seriale; con i LED collegati il caricamento può fallire e i LED lampeggiano a caso. Per questo l'array parte da D2. Se nessun LED si accende, controlla prima che la linea blu della breadboard sia davvero collegata al pin GND di Arduino.
Arduino Uno
Arduino Uno
Breadboard
Breadboard
R · Ω
R · Ω
Jumper
Jumper

Passo 1: codice dei LED in sequenza con array e ciclo for

Potresti scrivere otto righe pinMode e sedici righe digitalWrite per otto LED, ma il codice si allunga e cambiare il numero di LED diventa scomodo. Invece metti i numeri dei pin in un array e lo percorri in ordine con un ciclo for. Il primo elemento dell'array è LEDS[0], cioè D2; l'ultimo è LEDS[7], cioè D9. Così lo stesso codice funziona senza modifiche con 6, 8 o 12 LED: cambi solo l'array. Trovi le basi di array e cicli spiegate più in dettaglio in Basi di programmazione Arduino.

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}
RigaCosa fa
const int LEDS[] = {2, ..., 9};Array che contiene i pin dei LED in ordine da sinistra a destra; LEDS[0] = 2, LEDS[7] = 9
sizeof(LEDS) / sizeof(LEDS[0])Calcola il numero di elementi: sull'Uno 16 byte / 2 byte = 8; si aggiorna da solo quando aggiungi o togli pin
for (int i = 0; i < LED_SAYISI; i++)Conta la variabile i da 0 a 7; a ogni giro viene gestito un elemento dell'array
pinMode(LEDS[i], OUTPUT)Imposta tutti e otto i pin come uscita con un solo ciclo
digitalWrite, delay(BEKLE), digitalWriteAccende il LED, aspetta BEKLE millisecondi, lo spegne e passa al successivo

Con BEKLE (il tempo di passo) a 100 ms la luce attraversa gli otto LED in 0,8 secondi e riparte subito. Se lo abbassi a 30 ms lo scorrimento diventa velocissimo; se lo alzi a 300 ms sembra lento, come lampade che si accendono una alla volta. Per caricare lo sketch scegli scheda e porta nel menu Strumenti e premi Carica; se il caricamento non va a buon fine, segui la lista di controllo in Arduino non carica lo sketch.

Passo 2: codice dell'effetto Supercar (avanti e indietro)

Per l'effetto Supercar la luce deve tornare indietro quando arriva all'estremità destra. Lo fai con due cicli: il primo conta da sinistra a destra, il secondo da destra a sinistra. Il punto delicato sono i LED alle estremità. Se entrambi i cicli contano per intero da 0 a 7 e da 7 a 0, il LED di destra si accende una volta alla fine del ciclo di andata e un'altra all'inizio di quello di ritorno; la luce resta il doppio del tempo alle estremità e il movimento sembra scattoso. Per questo il ciclo di andata si ferma a 6 e quello di ritorno a 1. Così ogni giro dura esattamente 14 passi e la luce resta alle estremità quanto al centro. Abbiamo anche spostato le tre righe che accendono e spengono un LED in una piccola funzione chiamata yakSondur() ("accendi e spegni"): il codice diventa più corto e più leggibile.

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}
La velocità più simile a quella della serie è di circa 60–120 ms per passo. Con 8 LED e 80 ms un giro completo di andata e ritorno dura 14 × 80 = 1,12 secondi. Quando scendi verso i 20 ms, l'occhio vede più LED accesi contemporaneamente e la luce diventa una linea sfocata.

Passo 3: regolare la velocità con un potenziometro

Invece di modificare il codice e ricaricarlo ogni volta che vuoi un'altra velocità, puoi usare un potenziometro. Un potenziometro è un partitore di tensione: la tensione sulla gamba centrale varia tra 0 e 5 V a seconda della posizione dell'albero, e analogRead() la trasforma in un numero tra 0 e 1023. map(deger, 0, 1023, 400, 20) converte quel numero in un tempo di passo tra 400 e 20 ms; dato che l'intervallo è scritto al contrario, più alto è il valore letto, più corto è il passo e più veloce va la luce. Il verso in cui girare per accelerare dipende da quale gamba esterna hai collegato a 5V; se ti sembra al contrario, scambia i due fili esterni oppure inverti 400 e 20 in map(). Puoi leggere come funziona un potenziometro all'interno in Che cos'è un potenziometro?.

Potenziometro da 10 kΩ
Potenziometro da 10 kΩ: le gambe esterne vanno a 5V e GND, la gamba centrale del cursore va ad 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}

In questa versione il tempo di passo viene riletto a ogni LED, quindi la velocità cambia non appena giri l'albero. Mentre delay() è in esecuzione, però, Arduino non può fare nient'altro: anche se giri l'albero a metà di un passo lento da 400 ms, la nuova velocità vale solo dal passo successivo. Per un effetto con pochi LED non è un problema, ma quando aggiungi un pulsante per cambiare modalità o letture di sensori devi passare al metodo con millis() del passo 5.

Passo 4: l'effetto ad accumulo

Nell'effetto ad accumulo la prima luce corre fino in fondo a destra e lì resta accesa. Anche la seconda corre, ma questa volta si ferma un posto più a sinistra; a ogni giro la destinazione si sposta di un LED verso sinistra finché tutta la barra è piena. Nel codice lo fai con due cicli annidati: quello esterno conta quanti LED si sono già accumulati (dolu, "pieno"), quello interno quanti passi corre la luce in questo giro. Il LED che raggiunge la sua destinazione (hedef) non viene spento; se ne occupa proprio la riga if (i < hedef). Con otto LED, riempire tutta la barra richiede 8 + 7 + 6 + ... + 1 = 36 passi.

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}

Alla fine dello sketch la barra piena resta visibile per 0,6 secondi, poi i LED si spengono uno alla volta da destra a sinistra e l'effetto ricomincia. Se vuoi una barra che si riempie più semplice, basta togliere il ciclo interno e accendere i LED in ordine senza mai spegnerli; questo aspetto è perfetto per un indicatore di carica o una barra del livello sonoro. Ricorda che in questo effetto tutti e otto i LED sono accesi insieme: finché ogni LED ha la sua resistenza, la luminosità non cala.

Passo 5: effetto Supercar non bloccante con millis()

Nel codice che usa delay(), Arduino si blocca per il tempo indicato a ogni passo; se nel frattempo qualcuno preme un pulsante, non se ne accorge. millis(), invece, restituisce i millisecondi trascorsi dall'accensione della scheda. La logica è questa: il loop gira di continuo, a ogni giro controlla se dall'ultimo passo è passato abbastanza tempo e, se sì, fa un solo passo ed esce subito. Nel codice qui sotto l'effetto Supercar e il LED integrato funzionano insieme come due compiti indipendenti: mentre la luce scorre alla velocità impostata dal potenziometro, il LED su D13 lampeggia una volta al secondo con il suo ritmo. Per approfondire, leggi Arduino millis() e delay().

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}

Qui contano due dettagli. Primo, le variabili di tempo devono essere unsigned long; se usi int, sull'Uno il valore va in overflow dopo circa 32,7 secondi e la temporizzazione si guasta: l'effetto si ferma oppure accelera senza controllo. Secondo, il confronto si fa con una sottrazione nella forma simdi - sonAdim >= aralik (adesso meno l'ultimo passo, confrontato con l'intervallo); questo metodo continua a funzionare correttamente anche quando millis() torna a zero, all'incirca ogni 49,7 giorni. Dato che teniamo posizione e direzione della luce in due variabili (konum e yon), non ci sono più cicli: a ogni passo la posizione sale o scende di uno e, alle estremità, la direzione cambia segno.

8 LED con 3 pin usando il 74HC595

Otto LED occupano otto pin dell'Uno; quando vuoi aggiungere al progetto un display LCD, sensori e pulsanti, i pin cominciano a mancare. Il registro a scorrimento 74HC595 pilota le sue otto uscite con soli tre pin di Arduino (dati, clock e latch). Lo stato di ogni LED è un bit di un byte: l'espressione 1 << i mette a 1 solo il bit i, cioè accende un solo LED. Con le operazioni sui bit è facile anche creare motivi: (1 << i) | (0x80 >> i) produce due luci che arrivano contemporaneamente dalle due estremità verso il centro. Collegando in cascata due chip puoi fare persino un effetto Supercar da 16 LED con gli stessi tre pin; il collegamento in cascata, il pilotaggio veloce via SPI e l'uso con i display a 7 segmenti sono spiegati passo per passo nell'articolo Registro a scorrimento 74HC595.

Pin del 74HC595Collegamento (Arduino Uno)
DS (14)D11
SH_CP (11)D13
ST_CP (12)D10
OE (13)GND (uscite sempre attive)
MR (10)5V (reset disattivato)
VCC (16) / GND (8)5V / GND, con un condensatore da 100 nF accanto
Q0 (15), Q1–Q7 (1–7)Ciascuna all'anodo di un LED tramite 470 Ω
Gamba centrale del potenziometroA0
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}

Sulle uscite del 74HC595 si consiglia 470 Ω invece di 220 Ω: la corrente totale che passa dai pin VCC e GND del chip non dovrebbe superare 70 mA. Con 470 Ω scorrono circa 6,4 mA per LED e, anche con tutti e otto i LED accesi, il totale resta a 51 mA. Nell'effetto Supercar comunque sono accesi solo uno o due LED alla volta, quindi i LED si vedono bene lo stesso.

Effetto Supercar con scia da un solo pin con i WS2812B

La versione che somiglia di più al vero scanner di KITT si realizza con i LED indirizzabili WS2812B. Ogni WS2812B ha il suo driver integrato; per quanto lunga sia la striscia, imposti colore e luminosità di ogni LED separatamente con un unico filo dati. Per la scia teniamo un array: a ogni passo la luminosità di tutti i LED viene divisa per tre e il LED di testa viene portato a 255. Così i LED dietro si spengono rapidamente passando per 255, 85, 28 e 9, e dietro la luce si forma una scia naturale. Se dividi per 2 invece che per 3 la scia si allunga, con 5 si accorcia. Per passare da 8 a 60 LED con lo stesso metodo basta cambiare il valore di NUM_LEDS.

LED RGB indirizzabile WS2812B
WS2812B: ogni LED ha il suo driver interno; si collega con DIN, 5V e GND, e DOUT va al LED successivo.
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}
Quando colleghi i WS2812B, metti una resistenza da 330 Ω in serie sulla linea dati e un condensatore da 1000 µF tra 5V e GND; se usi un alimentatore esterno, collega il suo GND a quello di Arduino. Ogni LED può assorbire circa 60 mA sul bianco pieno; uno stick da 8 LED funziona con l'USB, ma da 30 LED in su serve un alimentatore da 5 V separato. Per l'installazione della libreria, l'ordine dei colori e il calcolo dei consumi, leggi l'articolo LED WS2812B NeoPixel.

Effetto Supercar con ESP32: scia in PWM su ogni pin

Sull'Uno un effetto Supercar con scia è difficile da fare con LED normali, perché il PWM c'è solo sui pin 3, 5, 6, 9, 10 e 11, e nel nostro array D2–D9 ce ne sono solo quattro. Sull'ESP32, grazie all'hardware LEDC, quasi ogni pin di uscita può generare PWM, e l'ESP32 classico ha 16 canali PWM. Dato che analogWrite() funziona direttamente nel core Arduino attuale per ESP32, puoi applicare la logica della scia dei WS2812B a LED normali. I pin della tabella sono GPIO sicuri che non influiscono sull'avvio; il potenziometro va al GPIO 34 sul canale ADC1, che legge bene anche con il Wi-Fi attivo, e poiché l'ADC dell'ESP32 è a 12 bit il valore va da 0 a 4095. I pin dell'ESP32 forniscono 3,3 V, quindi con 220 Ω in un LED rosso scorrono circa 6 mA; i LED appaiono un po' meno luminosi che sull'Uno. Per preparare la scheda, leggi Che cos'è l'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}

Effetto Supercar con Raspberry Pi Pico e MicroPython

Sul Raspberry Pi Pico scrivi lo stesso effetto in poche righe di MicroPython. Tenere gli oggetti Pin in una lista svolge lo stesso compito dell'array su Arduino. time.ticks_ms() e time.ticks_diff() sono gli equivalenti in MicroPython di millis() e della sottrazione sicura contro l'overflow. Il potenziometro va a GP26 (ADC0); read_u16() restituisce un valore da 0 a 65535 e il codice lo converte in 400–20 ms. Si consiglia che la corrente totale prelevata da tutti i GPIO del Pico resti sotto i 50 mA; per questo in tabella abbiamo scelto 330 Ω: scorrono circa 4 mA per LED e, anche con tutti e otto accesi, il totale si aggira sui 32 mA. Il progetto Supercar per Pico di BlueGrays usa 6 LED sui pin GP9–GP14; se hai montato quel circuito, ti basta cambiare la lista PINLER in [9, 10, 11, 12, 13, 14]. Per l'installazione e il caricamento con Thonny, leggi Che cos'è il 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()

Anche ogni GPIO del Pico può generare PWM; con machine.PWM e un valore duty_u16() per ogni LED puoi portare l'effetto scia dell'ESP32 sul Pico. Se vuoi usare i WS2812B, il modulo neopixel integrato in MicroPython pilota una striscia da un solo GPIO; però un WS2812B alimentato a 5 V non sempre legge in modo affidabile il segnale dati a 3,3 V del Pico, quindi se i colori impazziscono aggiungi un traslatore di livello in mezzo.

Idee di progetti con l'effetto Supercar

  • Vu meter (indicatore di livello sonoro): decidi quanti LED della barra si accendono in base al volume misurato con il sensore di suono KY-038.
  • Barra LED per sensore di parcheggio: accendi più LED man mano che la distanza misurata con l'HC-SR04 diminuisce, e falli lampeggiare tutti quando sei vicinissimo.
  • Gioco "acchiappa la luce": mentre la luce va avanti e indietro veloce, prova a premere un pulsante proprio quando si accende il LED centrale; a ogni centro accorcia il tempo di passo.
  • Decorazione notturna automatica: fai partire l'effetto da solo quando una fotoresistenza (LDR) rileva che fa buio.
  • Luce posteriore per modellino o bicicletta: crea un effetto Supercar rosso con scia su uno stick WS2812B e accendi tutti i LED al massimo quando premi il pulsante del freno.
  • Indicatore di livello: mostra la posizione di un potenziometro o la tensione di una batteria come una barra che si riempie.
  • Display più grandi: porta la stessa logica su una matrice LED MAX7219 o su un cubo di LED.

Errori comuni e come risolverli

SintomoCausaSoluzione
I LED si accendono debolissimiManca pinMode(OUTPUT); digitalWrite attiva solo la resistenza di pull-up internaImposta tutti i pin come OUTPUT con un ciclo in setup()
Un LED non si accende maiIl LED è al contrario, oppure una resistenza o un cavo sono spostati di una filaGamba lunga verso resistenza e pin, gamba corta a GND; prova il LED da solo con 5V e una resistenza
I LED alle estremità restano accesi il doppioEntrambi i cicli includono i LED alle estremitàUsa i < LED_SAYISI − 1 nel ciclo di andata e i > 0 in quello di ritorno
Un pin a caso sfarfalla o il programma fa cose straneSi esce dall'array: i <= LED_SAYISICambia la condizione in i < LED_SAYISI; l'elemento LEDS[8] non esiste
Lo sketch non si carica o i LED lampeggiano durante il caricamentoCi sono LED collegati a D0 e D1Fai partire l'array da D2
Il potenziometro non cambia la velocitàAd A0 arriva una gamba esterna invece di quella centrale, oppure il valore viene letto una sola volta fuori dal cicloCollega la gamba centrale ad A0; chiama analogRead a ogni passo
Dopo circa 32 secondi l'effetto impazzisceIl valore di millis() è salvato in una variabile intDichiara le variabili di tempo come unsigned long
I WS2812B non si accendono o mostrano colori casualiManca il GND comune, manca la resistenza sui dati o la striscia è collegata dal lato sbagliato (DOUT)Unisci i GND, aggiungi 330 Ω, collegati al lato DIN, dove partono le frecce
Prima di montare il circuito puoi provare il codice su Tinkercad con 8 LED e un potenziometro. Se qualcosa non va nel circuito reale, carica un breve sketch che porta tutti i pin a HIGH per qualche secondo e controlla i LED uno per uno; vedrai subito quale non si accende.

L'effetto Supercar sembra semplice, ma contiene idee di base che userai poi in ogni progetto: array, cicli, letture analogiche, map(), temporizzazione non bloccante, operazioni sui bit e LED indirizzabili. Come passo successivo dai un'occhiata al progetto semaforo con Arduino o all'elenco di idee per progetti Arduino. Nell'app BlueGrays trovi i LED in sequenza, l'effetto Supercar e le loro versioni a velocità regolabile, gli effetti ad accumulo e Supercar con WS2812B e i progetti LED in sequenza con ESP32 e Supercar con Pico, ognuno con schema passo passo e codice pronto da provare sulla tua scheda.

Domande frequenti

Quanti LED si possono controllare con Arduino Uno?

L'Uno ha 20 pin utilizzabili come uscite digitali, D0–D13 e A0–A5; se lasci liberi D0 e D1 per la comunicazione seriale, puoi pilotare direttamente 18 LED. Dai a ogni LED la sua resistenza e tieni la corrente totale sotto i 200 mA; se tutti e 18 devono essere accesi insieme, scegli 330 Ω o più. Per più LED si usa un registro a scorrimento 74HC595 o una striscia WS2812B, che pilota centinaia di LED con un solo pin.

Che resistenza serve per i LED in sequenza?

Su un Arduino Uno a 5 V, 220 Ω va bene per i LED rossi e dà circa 13,6 mA per LED; anche 330 Ω funziona, ma i LED sono un po' meno luminosi. Sull'ESP32 a 3,3 V si consigliano 220 Ω, sul Pico 330 Ω. Negli effetti in cui è acceso un solo LED funziona anche un'unica resistenza in comune, ma la luminosità cala quando se ne accendono diversi, quindi la scelta giusta è una resistenza per LED.

Si può fare l'effetto Supercar senza Arduino?

Sì, il metodo classico usa un timer NE555 e un contatore CD4017. Il 555 genera gli impulsi di clock e il 4017 porta a HIGH le sue 10 uscite una dopo l'altra, il che da solo dà dei LED in sequenza. Per l'andata e ritorno le uscite si combinano con dei diodi: le 10 uscite vengono collegate a 6 LED nell'ordine 1-2-3-4-5-6-5-4-3-2, e la velocità si regola con un potenziometro sul 555.

Che differenza c'è tra LED in sequenza ed effetto Supercar?

Nei LED in sequenza la luce scorre in una sola direzione e dopo l'ultimo LED riparte dall'inizio; con 8 LED un giro è di 8 passi. Nell'effetto Supercar la luce torna indietro all'estremità e va avanti e indietro tra i due lati; con 8 LED un giro è di 14 passi. Anche nel codice la differenza è piccola: per l'effetto Supercar aggiungi un secondo ciclo che conta all'indietro.

Perché usare millis() invece di delay() per i LED in sequenza?

Mentre delay() è in esecuzione Arduino non può fare nient'altro: perde le pressioni dei pulsanti e non legge i sensori. Con millis(), a ogni giro del loop si fa un passo solo quando il tempo è scaduto, e nel resto del tempo girano altri compiti. Così, mentre la luce scorre, pulsanti, potenziometro o comandi seriali rispondono all'istante.

Come si aggiunge la scia all'effetto Supercar?

Per la scia bisogna abbassare gradualmente la luminosità dei LED che seguono la testa, e per questo serve il PWM. Sull'Uno il PWM c'è solo sui pin 3, 5, 6, 9, 10 e 11, quindi con quei pin puoi fare un effetto Supercar con scia a 6 LED. La strada più semplice è una striscia WS2812B, in cui regoli ogni LED separatamente, oppure un ESP32 o un Pico, che hanno il PWM su tutti i pin.

Vedi tutti i progetti
Effetto Supercar con LED
#6Intermedio

Effetto Supercar con LED

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

4.8(106)
202
LED in sequenza
#5Intermedio

LED in sequenza

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

4.6(85)
207
Effetto Supercar a velocità regolabile
#8Intermedio

Effetto Supercar a velocità regolabile

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

4.5(60)
120
LED in sequenza a velocità regolabile
#7Intermedio

LED in sequenza a velocità regolabile

Sei LED si accendono uno dopo l'altro e la luce sembra correre da un'estremità all'altra. Girando la manopola del potenziometro la velocità di questa corsa cambia all'istante: da un lato la luce vola,

4.6(72)
146
Effetto Supercar con WS2812B
#73Intermedio
Premium

Effetto Supercar con WS2812B

Un punto di luce rossa scorre da un capo all'altro di una striscia LED intelligente e poi torna indietro, in un avanti e indietro che non si ferma mai. A ogni passo l'Arduino accende un solo LED, aspe

4.9(73)
94
LED in sequenza con WS2812B (riempimento)
#72Intermedio
Premium

LED in sequenza con WS2812B (riempimento)

Una striscia di luce che si riempie e si svuota come un bicchiere d'acqua. L'Arduino accende uno alla volta dieci LED colorati in arancione e li lascia accesi; quando la striscia è piena, li spegne un

4.7(50)
65
LED Sequenziale ESP32 (Knight Rider)
#108Principiante

LED Sequenziale ESP32 (Knight Rider)

6 LED che si muovono sequenzialmente da sinistra a destra e da destra a sinistra (stile Knight Rider). Esempio di base di utilizzo del ciclo for e degli array. Insegna la logica del cambio di direzione.

4.5(19)
32
Raspberry Pi Pico Knight Rider LED Scanner (6 LED Avanti-Indietro)
#154Principiante

Raspberry Pi Pico Knight Rider LED Scanner (6 LED Avanti-Indietro)

Effetto scanner LED "Knight Rider" classico con Pico! 6 LED vanno da sinistra a destra, poi da destra a sinistra, all'infinito. Impara reversed() e due cicli for separati per pattern avanti-indietro.

0.0(0)
13