Ratgeber · 14 Min. Lesezeit

Arduino Lauflicht (Knight Rider): Schaltung, Code und Effekte

Arduino Lauflicht im Knight-Rider-Stil: 8 LEDs mit 220 Ω, Code mit Array und for-Schleife, Tempo per Poti, millis, 74HC595, WS2812B, ESP32 und Pico.

Ein Arduino Lauflicht im Knight-Rider-Stil ist ein klassischer LED-Effekt, bei dem eine Reihe von LEDs nacheinander aufleuchtet, von einem Ende zum anderen wandert und wieder zurückkommt. Seinen Namen hat er vom Lauflicht an der Front von KITT, dem sprechenden Auto aus der berühmten Achtzigerjahre-Serie Knight Rider. Du brauchst dafür nur einen Arduino Uno, 6 oder 8 LEDs, für jede LED einen 220-Ω-Widerstand und ein paar Jumperkabel. Läuft das Licht nur in eine Richtung und beginnt dann wieder von vorn, spricht man von einem einfachen Lauflicht. Beides sind Klassiker, die Einsteiger direkt nach der Ampel bauen, und die unterhaltsamste Art, zwei der wichtigsten Werkzeuge des Programmierens zu lernen: Arrays und die for-Schleife.

In dieser Anleitung baust du die Schaltung auf und schreibst zuerst den Code für das einfache Lauflicht, danach für das hin- und herlaufende Knight-Rider-Licht. Anschließend stellst du das Tempo mit einem Potentiometer ein, ergänzt einen Effekt, bei dem sich die LEDs an einem Ende stapeln, und lässt denselben Effekt mit millis() laufen, ohne den Code jemals zu blockieren. In den letzten Abschnitten erfährst du, wie du mit dem 74HC595 acht LEDs über nur 3 Pins ansteuerst, wie du mit adressierbaren WS2812B-LEDs ein Knight-Rider-Licht mit Schweif an einem einzigen Pin baust, wie die Versionen für ESP32 und Raspberry Pi Pico (MicroPython) aussehen und wie du die häufigsten Fehler behebst.

Rote, gelbe, blaue, grüne und weiße 5-mm-LEDs
Für den klassischen Knight-Rider-Look nimmst du 6 oder 8 gleichfarbige (am besten rote) 5-mm-LEDs; das lange Bein ist die Anode (+), das kurze die Kathode (−).

Was ist der Knight-Rider-Effekt, und was unterscheidet ihn vom Lauflicht?

In der Serie wandert das rote Licht an KITTs Frontstoßstange ununterbrochen nach links und rechts, wie ein suchendes Auge. In der Elektronik heißt dieser Effekt nach dem Produzenten der Serie, Glen A. Larson, auch Larson-Scanner; die Augen der Zylonen-Roboter aus seiner anderen Serie Kampfstern Galactica funktionieren nach demselben Prinzip. Beim echten Scanner sieht man hinter dem leuchtenden Punkt eine langsam verglimmende rote Spur, einen Schweif. In einer einfachen LED-Schaltung ist jede LED entweder ganz an oder ganz aus; um den Schweif nachzuahmen, musst du die LEDs per PWM stufenweise dimmen. Genau das machen wir später mit dem WS2812B und dem ESP32. Die Tabelle fasst die Effekte zusammen, die du in diesem Artikel programmierst, und zeigt, wie viele Schritte ein Durchlauf mit 8 LEDs dauert.

EffektWas passiert?Ein Durchlauf mit 8 LEDsIn diesem Artikel
Einfaches LauflichtEin einzelnes Licht läuft von links nach rechts und beginnt dann von vorn8 SchritteSchritt 1
Knight RiderEin einzelnes Licht pendelt zwischen den beiden Enden14 SchritteSchritt 2 und 3
StapeleffektJedes Licht läuft bis zum rechtesten freien Platz und bleibt dort36 SchritteSchritt 4
Treffen in der MitteZwei Lichter kommen von außen zur Mitte und laufen wieder auseinander8 SchritteAbschnitt 74HC595
Knight Rider mit SchweifDie vorderste LED leuchtet voll, die dahinter verglimmen14 SchritteAbschnitte WS2812B und ESP32

Bauteile und die Wahl des Vorwiderstands

BauteilAnzahlHinweis
Arduino Uno (oder Nano)1Ein ESP32 oder Raspberry Pi Pico geht auch
5-mm-LED6–8Gleiche Farbe und gleiche Charge, dann leuchten alle gleich hell
220-Ω-Widerstand6–8Einer pro LED; am Pico 330 Ω
10-kΩ-Potentiometer (B10K)1Nur für die Versionen mit Tempoeinstellung
Steckbrett (Breadboard)1Halbe Größe (400 Löcher) reicht
Jumperkabel12–15Stecker auf Stecker
74HC595 oder WS2812B-Stick mit 8 LEDs1Optional: für die Abschnitte zum Pinsparen und zum Schweif-Effekt

Eine LED begrenzt ihren Strom nicht selbst, deshalb bekommt jede LED einen Vorwiderstand in Reihe. Den Wert findest du mit dem ohmschen Gesetz: R = (Versorgungsspannung − LED-Durchlassspannung) / Strom. Eine rote LED hat etwa 2 V Durchlassspannung, also fließen bei 5 V und 220 Ω (5 − 2) / 220 ≈ 13,6 mA. Damit leuchtet die LED schön hell, und du bleibst unter den für einen Arduino-Pin empfohlenen 20 mA. Beim Stapeleffekt, wenn alle acht LEDs gleichzeitig leuchten, beträgt der Gesamtstrom etwa 109 mA; das liegt noch innerhalb der 200 mA, die der Uno insgesamt über alle Pins liefern darf. Um einen 220-Ω-Widerstand an seinen Farbringen zu erkennen, nutze das Werkzeug Widerstand-Farbcode; für andere Farben und Spannungen hilft der LED-Vorwiderstandsrechner.

Schaltung: 8 LEDs und ein Potentiometer

Das lange Bein (Anode) jeder LED geht über einen Widerstand an einen Digitalpin des Boards, das kurze Bein (Kathode) an GND. Am saubersten ist es auf dem Steckbrett, den GND-Pin des Arduino mit der blauen (−) Schiene zu verbinden und die kurzen Beine aller acht LEDs auf diese Schiene zu führen. Setze die LEDs in gleichmäßigem Abstand von links nach rechts in Pin-Reihenfolge; so entspricht die Reihenfolge im Array der tatsächlichen Reihenfolge des Lichts. Die beiden äußeren Beine des Potentiometers kommen an 5V und GND, das mittlere Bein (der Schleifer) an A0. Die Tabelle zeigt die Pins, die alle Sketche in diesem Artikel verwenden; mit 6 LEDs lässt du die letzten beiden LED-Zeilen weg und löschst die letzten beiden Pins aus dem Array im Code. Die Pinbelegung deines Boards siehst du im Werkzeug Pinout.

FunktionArduino UnoESP32Raspberry Pi Pico
LED 1 (ganz links)D2GPIO 18GP8
LED 2D3GPIO 19GP9
LED 3D4GPIO 21GP10
LED 4D5GPIO 22GP11
LED 5D6GPIO 23GP12
LED 6D7GPIO 25GP13
LED 7D8GPIO 26GP14
LED 8 (ganz rechts)D9GPIO 27GP15
Potentiometer, mittleres BeinA0GPIO 34GP26 (ADC0)
Potentiometer, äußere Beine5V und GND3V3 und GND3V3(OUT) und AGND
LED-Kathoden (kurzes Bein)GNDGNDGND
Vorwiderstand220 Ω220 Ω330 Ω
Schließ keine LEDs an die Pins D0 und D1 an: Diese Pins werden zum Hochladen über USB und für den seriellen Monitor gebraucht; mit angeschlossenen LEDs kann der Upload fehlschlagen und die LEDs flackern zufällig. Deshalb beginnt das Array bei D2. Leuchtet gar keine LED, prüfe zuerst, ob die blaue Schiene des Steckbretts wirklich mit dem GND-Pin des Arduino verbunden ist.
Arduino Uno
Arduino Uno
Breadboard
Breadboard
R · Ω
R · Ω
Jumper
Jumper

Schritt 1: Lauflicht-Code mit Array und for-Schleife

Du könntest für acht LEDs acht einzelne pinMode-Zeilen und sechzehn einzelne digitalWrite-Zeilen schreiben, aber der Code wird lang, und die Zahl der LEDs zu ändern wird mühsam. Stattdessen legst du die Pinnummern in ein Array und gehst es mit einer for-Schleife der Reihe nach durch. Das erste Element des Arrays ist LEDS[0], also D2; das letzte ist LEDS[7], also D9. So läuft derselbe Code unverändert mit 6, 8 oder 12 LEDs, du passt nur das Array an. Die Grundlagen zu Arrays und Schleifen findest du ausführlicher im Artikel Arduino-Programmierung: Grundlagen.

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}
ZeileWas sie tut
const int LEDS[] = {2, ..., 9};Array, das die LED-Pins von links nach rechts der Reihe nach enthält; LEDS[0] = 2, LEDS[7] = 9
sizeof(LEDS) / sizeof(LEDS[0])Berechnet die Anzahl der Elemente: am Uno 16 Byte / 2 Byte = 8; passt sich automatisch an, wenn du Pins hinzufügst oder entfernst
for (int i = 0; i < LED_SAYISI; i++)Zählt die Variable i von 0 bis 7; in jedem Durchgang wird ein Element des Arrays bearbeitet
pinMode(LEDS[i], OUTPUT)Schaltet alle acht Pins mit einer einzigen Schleife auf Ausgang
digitalWrite, delay(BEKLE), digitalWriteSchaltet die LED ein, wartet BEKLE Millisekunden, schaltet sie aus und geht zur nächsten

Mit BEKLE (der Schrittzeit) bei 100 ms läuft das Licht in 0,8 Sekunden über alle acht LEDs und beginnt sofort von vorn. Setzt du den Wert auf 30 ms, wird der Lauf sehr schnell; bei 300 ms wirkt er gemächlich, wie Lampen, die einzeln angehen. Zum Hochladen wählst du im Menü Werkzeuge Board und Port und klickst auf Hochladen; schlägt der Upload fehl, geh die Checkliste im Artikel Arduino Sketch lässt sich nicht hochladen durch.

Schritt 2: Code für das Knight-Rider-Lauflicht (hin und her)

Für den Knight-Rider-Effekt muss das Licht am rechten Ende umkehren. Dafür nimmst du zwei Schleifen: Die erste zählt von links nach rechts, die zweite von rechts nach links. Der Knackpunkt sind die End-LEDs. Zählen beide Schleifen vollständig von 0 bis 7 und von 7 bis 0, leuchtet die rechte LED einmal am Ende der Vorwärtsschleife und noch einmal am Anfang der Rückwärtsschleife; an den Enden bleibt das Licht doppelt so lange stehen, und die Bewegung wirkt ruckelig. Deshalb stoppt die Vorwärtsschleife bei 6 und die Rückwärtsschleife bei 1. So dauert jeder Durchlauf genau 14 Schritte, und das Licht verweilt an den Enden genauso lange wie in der Mitte. Die drei Zeilen, die eine LED ein- und ausschalten, haben wir außerdem in eine kleine Funktion namens yakSondur() ("ein- und ausschalten") ausgelagert; der Code wird kürzer und besser lesbar.

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}
Am nächsten am Look aus der Serie ist ein Tempo von etwa 60–120 ms pro Schritt. Mit 8 LEDs und 80 ms dauert ein Hin-und-her-Durchlauf 14 × 80 = 1,12 Sekunden. Gehst du auf etwa 20 ms herunter, nimmt dein Auge mehrere LEDs als gleichzeitig leuchtend wahr, und das Licht verschwimmt zu einer Linie.

Schritt 3: Tempo per Potentiometer einstellen

Statt für jedes andere Tempo den Code zu ändern und neu hochzuladen, kannst du ein Potentiometer verwenden. Ein Potentiometer ist ein Spannungsteiler: Die Spannung am mittleren Bein ändert sich je nach Stellung der Achse zwischen 0 und 5 V, und analogRead() macht daraus eine Zahl zwischen 0 und 1023. map(deger, 0, 1023, 400, 20) rechnet diese Zahl in eine Schrittzeit zwischen 400 und 20 ms um; weil der Bereich umgekehrt angegeben ist, wird die Schrittzeit kürzer und das Licht schneller, je größer der gemessene Wert ist. In welche Richtung du drehen musst, damit es schneller wird, hängt davon ab, welches äußere Bein an 5V hängt; fühlt es sich falsch herum an, tausch die beiden äußeren Kabel oder die Werte 400 und 20 in map(). Wie ein Potentiometer innen aufgebaut ist, liest du im Artikel Was ist ein Potentiometer?.

10-kΩ-Potentiometer
10-kΩ-Potentiometer: Die äußeren Beine kommen an 5V und GND, das mittlere Schleiferbein an 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 dieser Version wird die Schrittzeit bei jeder LED neu gelesen, das Tempo ändert sich also, sobald du am Poti drehst. Während delay() läuft, kann der Arduino aber nichts anderes tun: Selbst wenn du mitten in einem langsamen 400-ms-Schritt drehst, gilt das neue Tempo erst ab dem nächsten Schritt. Für einen Effekt mit ein paar LEDs ist das kein Problem, doch sobald du eine Modustaste oder Sensorwerte ergänzt, solltest du auf die millis()-Methode aus Schritt 5 umsteigen.

Schritt 4: der Stapeleffekt

Beim Stapeleffekt läuft das erste Licht ganz nach rechts und bleibt dort leuchten. Das zweite Licht läuft ebenfalls los, stoppt aber einen Platz weiter links; mit jedem Durchgang rückt das Ziel eine LED nach links, bis die ganze Leiste voll ist. Im Code löst du das mit zwei verschachtelten Schleifen: Die äußere zählt, wie viele LEDs sich schon gestapelt haben (dolu, "voll"), die innere, wie viele Schritte das Licht in dieser Runde läuft. Die LED, die ihr Ziel (hedef) erreicht, wird nicht ausgeschaltet; genau dafür sorgt die Zeile if (i < hedef). Bei acht LEDs dauert es 8 + 7 + 6 + ... + 1 = 36 Schritte, bis die Leiste voll ist.

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}

Am Ende des Sketches wird die volle Leiste 0,6 Sekunden lang gezeigt, dann gehen die LEDs von rechts nach links einzeln aus, und der Effekt beginnt von vorn. Willst du eine einfachere Balkenanzeige, die sich füllt, entfernst du die innere Schleife und schaltest die LEDs nacheinander ein, ohne sie wieder auszuschalten; dieser Look eignet sich ideal als Ladeanzeige oder Pegelbalken. Denk daran, dass bei diesem Effekt alle acht LEDs gleichzeitig leuchten: Solange jede LED ihren eigenen Widerstand hat, sinkt die Helligkeit nicht.

Schritt 5: nicht blockierendes Knight-Rider-Lauflicht mit millis()

In Code mit delay() friert der Arduino bei jedem Schritt für die angegebene Zeit ein; drückt in dieser Zeit jemand eine Taste, bekommt er es nicht mit. millis() liefert dagegen die Zeit in Millisekunden seit dem Einschalten des Boards. Die Logik: Die Schleife läuft ständig, prüft bei jedem Durchgang, ob seit dem letzten Schritt genug Zeit vergangen ist, macht in diesem Fall genau einen Schritt und ist sofort wieder fertig. Im folgenden Code laufen das Knight-Rider-Licht und die Onboard-LED als zwei unabhängige Aufgaben gleichzeitig: Während das Lauflicht im Tempo des Potentiometers wandert, blinkt die LED an D13 in ihrem eigenen Takt einmal pro Sekunde. Mehr dazu findest du im Artikel Arduino millis() statt 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}

Zwei Details sind hier wichtig. Erstens müssen die Zeitvariablen vom Typ unsigned long sein; mit int läuft der Wert am Uno nach etwa 32,7 Sekunden über, und das Timing gerät durcheinander: Der Effekt bleibt stehen oder wird unkontrolliert schnell. Zweitens wird mit einer Subtraktion in der Form simdi - sonAdim >= aralik verglichen (jetzt minus letzter Schritt, verglichen mit dem Intervall); diese Methode funktioniert auch dann korrekt, wenn millis() etwa alle 49,7 Tage wieder bei null beginnt. Da wir Position und Richtung des Lichts in zwei Variablen (konum und yon) speichern, gibt es keine Schleifen mehr: Bei jedem Schritt steigt oder fällt die Position um eins, und an den Enden wechselt die Richtung ihr Vorzeichen.

8 LEDs an 3 Pins mit dem 74HC595

Acht LEDs belegen acht Pins des Uno; sobald du ein LCD, Sensoren und Taster ergänzen willst, werden die Pins knapp. Das Schieberegister 74HC595 steuert seine acht Ausgänge über nur drei Arduino-Pins (Daten, Takt und Latch). Der Zustand jeder LED ist ein Bit in einem Byte: Der Ausdruck 1 << i setzt nur Bit i auf 1 und schaltet damit eine einzelne LED ein. Auch Muster lassen sich mit Bitoperationen leicht bauen: (1 << i) | (0x80 >> i) erzeugt zwei Lichter, die gleichzeitig von beiden Enden zur Mitte laufen. Mit zwei verketteten Chips baust du mit denselben drei Pins sogar ein Knight-Rider-Lauflicht mit 16 LEDs; Verkettung, schnelle Ansteuerung per SPI und 7-Segment-Anzeigen erklärt der Artikel 74HC595 Schieberegister Schritt für Schritt.

74HC595-PinAnschluss (Arduino Uno)
DS (14)D11
SH_CP (11)D13
ST_CP (12)D10
OE (13)GND (Ausgänge immer aktiv)
MR (10)5V (Reset deaktiviert)
VCC (16) / GND (8)5V / GND, mit 100-nF-Kondensator direkt daneben
Q0 (15), Q1–Q7 (1–7)Jeweils über 470 Ω an die Anode einer LED
Potentiometer, mittleres BeinA0
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}

An den Ausgängen des 74HC595 empfiehlt sich 470 Ω statt 220 Ω: Der Gesamtstrom über die VCC- und GND-Pins des Chips sollte 70 mA nicht überschreiten. Mit 470 Ω fließen etwa 6,4 mA pro LED, und selbst wenn alle acht leuchten, bleibt der Gesamtstrom bei 51 mA. Beim Knight-Rider-Effekt leuchten ohnehin nur eine oder zwei LEDs gleichzeitig, deshalb sind die LEDs trotzdem gut zu sehen.

Knight-Rider-Lauflicht mit Schweif an einem Pin mit WS2812B

Am ähnlichsten zum echten KITT-Scanner wird die Version mit adressierbaren WS2812B-LEDs. Jede WS2812B hat ihren eigenen Treiber eingebaut; egal wie lang der Streifen ist, du stellst Farbe und Helligkeit jeder LED einzeln über eine einzige Datenleitung ein. Für den Schweif speichern wir ein Array: Bei jedem Schritt wird die Helligkeit aller LEDs durch drei geteilt, und die vorderste LED wird auf 255 gesetzt. Die LEDs dahinter verglimmen so schnell über 255, 85, 28 und 9, und hinter dem Licht entsteht eine natürliche Spur. Teilst du durch 2 statt durch 3, wird der Schweif länger, bei 5 kürzer. Um mit derselben Methode von 8 auf 60 LEDs zu gehen, änderst du nur den Wert NUM_LEDS.

Adressierbare RGB-LED WS2812B
WS2812B: Jede LED hat ihren eigenen Treiber eingebaut; angeschlossen wird sie über DIN, 5V und GND, DOUT geht zur nächsten 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}
Beim Anschließen des WS2812B setzt du einen 330-Ω-Widerstand in die Datenleitung und einen 1000-µF-Kondensator zwischen 5V und GND; mit externem Netzteil muss dessen GND mit dem GND des Arduino verbunden sein. Jede LED kann bei vollem Weiß etwa 60 mA ziehen; ein Stick mit 8 LEDs läuft über USB, ab etwa 30 LEDs brauchst du ein eigenes 5-V-Netzteil. Bibliotheksinstallation, Farbreihenfolge und Leistungsberechnung findest du im Artikel WS2812B NeoPixel LED.

Knight-Rider-Lauflicht am ESP32: PWM-Schweif an jedem Pin

Am Uno ist ein Knight-Rider-Licht mit Schweif aus normalen LEDs schwierig, denn PWM gibt es nur an den Pins 3, 5, 6, 9, 10 und 11, und in unserem Array D2–D9 sind davon nur vier enthalten. Am ESP32 kann dank der LEDC-Hardware fast jeder Ausgangspin PWM erzeugen, und der klassische ESP32 hat 16 PWM-Kanäle. Da analogWrite() im aktuellen ESP32-Arduino-Core direkt funktioniert, kannst du die Schweif-Logik des WS2812B auf ganz normale LEDs übertragen. Die Pins in der Tabelle sind sichere GPIOs, die den Bootvorgang nicht beeinflussen; das Potentiometer hängt an GPIO 34 auf dem ADC1-Kanal, der auch bei eingeschaltetem WLAN zuverlässig misst, und weil der ADC des ESP32 12 Bit hat, reicht der Wert von 0 bis 4095. Die Pins des ESP32 liefern 3,3 V, deshalb fließen mit 220 Ω durch eine rote LED etwa 6 mA; die LEDs wirken etwas dunkler als am Uno. Zur Einrichtung des Boards lies den Artikel Was ist der 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}

Knight-Rider-Lauflicht am Raspberry Pi Pico mit MicroPython

Auf dem Raspberry Pi Pico schreibst du denselben Effekt in wenigen Zeilen MicroPython. Die Pin-Objekte in einer Liste zu halten, erfüllt dieselbe Aufgabe wie das Array beim Arduino. time.ticks_ms() und time.ticks_diff() sind die MicroPython-Gegenstücke zu millis() und zur überlaufsicheren Subtraktion. Das Potentiometer hängt an GP26 (ADC0); read_u16() liefert einen Wert von 0 bis 65535, und der Code rechnet ihn in 400–20 ms um. Empfohlen wird, dass der Gesamtstrom aller GPIOs des Pico unter 50 mA bleibt; deshalb haben wir in der Tabelle 330 Ω gewählt: Pro LED fließen etwa 4 mA, und selbst wenn alle acht leuchten, bleibt der Gesamtstrom bei rund 32 mA. Das Pico-Knight-Rider-Projekt in BlueGrays nutzt 6 LEDs an den Pins GP9–GP14; hast du diese Schaltung aufgebaut, änderst du die Liste PINLER einfach auf [9, 10, 11, 12, 13, 14]. Installation und Hochladen mit Thonny erklärt der Artikel Was ist der 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()

Auch jeder GPIO des Pico kann PWM erzeugen; mit machine.PWM und einem duty_u16()-Wert für jede LED überträgst du den Schweif-Effekt des ESP32 auf den Pico. Willst du WS2812B verwenden, steuert das eingebaute neopixel-Modul von MicroPython einen Streifen über einen einzigen GPIO; ein mit 5 V versorgter WS2812B liest das 3,3-V-Datensignal des Pico aber nicht immer zuverlässig, also setz bei fehlerhaften Farben einen Pegelwandler dazwischen.

Projektideen mit dem Knight-Rider-Lauflicht

  • Pegelanzeige (VU-Meter): Bestimme anhand der mit dem Schallsensor KY-038 gemessenen Lautstärke, wie viele LEDs der Balkenanzeige leuchten.
  • LED-Balken für die Einparkhilfe: Lass mehr LEDs leuchten, je kleiner der mit dem HC-SR04 gemessene Abstand wird, und lass alle blinken, wenn es sehr eng wird.
  • Fang-das-Licht-Spiel: Während das Lauflicht schnell hin- und herläuft, versuchst du, genau dann einen Taster zu drücken, wenn die mittlere LED leuchtet; nach jedem Treffer wird die Schrittzeit kürzer.
  • Automatische Nachtdeko: Der Effekt startet von selbst, wenn ein LDR erkennt, dass es dunkel wird.
  • Rücklicht für Modellauto oder Fahrrad: Bau mit einem WS2812B-Stick ein rotes Knight-Rider-Licht mit Schweif und lass beim Druck auf die Bremstaste alle LEDs voll aufleuchten.
  • Füllstandsanzeige: Zeig die Stellung eines Potentiometers oder eine Akkuspannung als sich füllenden Balken an.
  • Größere Anzeigen: Übertrag dieselbe Logik auf eine MAX7219-LED-Matrix oder einen LED-Würfel.

Häufige Fehler und ihre Lösungen

SymptomUrsacheLösung
Die LEDs leuchten nur sehr schwachpinMode(OUTPUT) fehlt; digitalWrite schaltet nur den internen Pull-up-Widerstand einIn setup() alle Pins per Schleife auf OUTPUT setzen
Eine LED leuchtet nieDie LED ist verpolt, oder ein Widerstand oder Kabel steckt eine Reihe danebenLanges Bein an Widerstand und Pin, kurzes an GND; LED einzeln mit 5V und Widerstand testen
Die End-LEDs leuchten doppelt so langeBeide Schleifen enthalten die End-LEDsIn der Vorwärtsschleife i < LED_SAYISI − 1, in der Rückwärtsschleife i > 0 verwenden
Ein zufälliger Pin flackert, das Programm verhält sich seltsamZugriff über das Array-Ende hinaus: i <= LED_SAYISIBedingung auf i < LED_SAYISI ändern; ein Element LEDS[8] gibt es nicht
Der Sketch lässt sich nicht hochladen, oder die LEDs flackern dabeiLEDs hängen an D0 und D1Das Array bei D2 beginnen lassen
Das Potentiometer ändert das Tempo nichtAn A0 hängt ein äußeres statt des mittleren Beins, oder der Wert wird nur einmal außerhalb der Schleife gelesenMittleres Bein an A0; analogRead bei jedem Schritt aufrufen
Nach etwa 32 Sekunden spielt der Effekt verrücktDer millis()-Wert steckt in einer int-VariablenZeitvariablen als unsigned long anlegen
Die WS2812B leuchten gar nicht oder in zufälligen FarbenKein gemeinsames GND, kein Datenwiderstand, oder der Streifen ist am falschen Ende (DOUT) angeschlossenGNDs verbinden, 330 Ω ergänzen, am DIN-Ende anschließen, an dem die Pfeile beginnen
Bevor du die Schaltung aufbaust, kannst du den Code in Tinkercad mit 8 LEDs und einem Potentiometer ausprobieren. Klappt in der echten Schaltung etwas nicht, lade einen kurzen Sketch hoch, der alle Pins für ein paar Sekunden auf HIGH setzt, um die LEDs einzeln zu prüfen; so siehst du sofort, welche LED nicht leuchtet.

Das Knight-Rider-Lauflicht sieht einfach aus, steckt aber voller Grundideen, die du später in jedem Projekt brauchst: Arrays, Schleifen, analoges Einlesen, map(), nicht blockierendes Timing, Bitoperationen und adressierbare LEDs. Als nächsten Schritt kannst du dir das Projekt Arduino Ampel oder die Liste mit Arduino-Projektideen ansehen. In der BlueGrays-App findest du das einfache Lauflicht, das Knight-Rider-Licht und ihre Versionen mit Tempoeinstellung, Stapel- und Knight-Rider-Effekte mit WS2812B sowie die Projekte ESP32-Lauflicht und Pico-Knight-Rider, jeweils mit Schritt-für-Schritt-Schaltplan und fertigem Code zum Ausprobieren auf deinem eigenen Board.

Häufige Fragen

Wie viele LEDs kann ein Arduino Uno ansteuern?

Am Uno lassen sich 20 Pins als digitale Ausgänge nutzen, D0–D13 und A0–A5; hältst du D0 und D1 für die serielle Kommunikation frei, kannst du 18 LEDs direkt ansteuern. Gib jeder LED einen eigenen Vorwiderstand und halte den Gesamtstrom unter 200 mA; leuchten alle 18 gleichzeitig, nimm 330 Ω oder mehr. Für mehr LEDs nutzt du ein Schieberegister 74HC595 oder einen WS2812B-Streifen, der Hunderte LEDs an einem Pin betreibt.

Welchen Vorwiderstand brauche ich für ein Lauflicht?

Am Arduino Uno mit 5 V passt für rote LEDs 220 Ω, das ergibt etwa 13,6 mA pro LED; 330 Ω geht auch, die LEDs leuchten dann etwas schwächer. Am ESP32 mit 3,3 V empfiehlt sich 220 Ω, am Pico 330 Ω. Bei Effekten, in denen nur eine LED leuchtet, funktioniert auch ein gemeinsamer Widerstand, aber sobald mehrere LEDs leuchten, sinkt die Helligkeit; deshalb ist ein eigener Widerstand pro LED die richtige Wahl.

Kann man ein Lauflicht ohne Arduino bauen?

Ja, der Klassiker ist ein NE555-Timer mit dem Zählerbaustein CD4017. Der 555 erzeugt Taktimpulse, und der 4017 schaltet seine 10 Ausgänge nacheinander auf HIGH, was allein schon ein einfaches Lauflicht ergibt. Für das Hin und Her werden die Ausgänge mit Dioden zusammengeführt: Die 10 Ausgänge gehen in der Reihenfolge 1-2-3-4-5-6-5-4-3-2 an 6 LEDs, und das Tempo stellst du mit einem Potentiometer am 555 ein.

Was ist der Unterschied zwischen Lauflicht und Knight-Rider-Effekt?

Beim einfachen Lauflicht wandert das Licht in eine Richtung und beginnt nach der letzten LED von vorn; mit 8 LEDs sind das 8 Schritte pro Durchlauf. Beim Knight-Rider-Effekt kehrt das Licht am Ende um und pendelt zwischen den beiden Enden; mit 8 LEDs sind das 14 Schritte. Auch im Code ist der Unterschied klein: Für Knight Rider kommt eine zweite, rückwärts zählende Schleife hinzu.

Warum millis() statt delay() beim Lauflicht?

Während delay() läuft, kann der Arduino nichts anderes tun; er verpasst Tastendrücke und kann keine Sensoren lesen. Mit millis() macht die Schleife nur dann einen Schritt, wenn die Zeit abgelaufen ist, und in der übrigen Zeit laufen andere Aufgaben. So reagieren Taster, Potentiometer oder serielle Befehle sofort, während das Lauflicht läuft.

Wie bekommt das Knight-Rider-Lauflicht einen Schweif?

Für den Schweif müssen die LEDs hinter dem Licht stufenweise gedimmt werden, und dafür brauchst du PWM. Am Uno gibt es PWM nur an den Pins 3, 5, 6, 9, 10 und 11, an diesen Pins kannst du also ein Knight-Rider-Licht mit 6 LEDs und Schweif bauen. Einfacher geht es mit einem WS2812B-Streifen, bei dem du jede LED einzeln steuerst, oder mit einem ESP32 oder Pico, die PWM an jedem Pin bieten.

Alle Projekte ansehen
Knight-Rider-Lauflicht
#6Mittel

Knight-Rider-Lauflicht

Das klassische Lauflicht, das hin und her wandert: Ein Lichtpunkt gleitet über sechs LEDs von einem Ende zum anderen und kommt wieder zurück. Der Arduino lässt jede LED eine Zehntelsekunde leuchten, d

4.8(106)
202
LED-Lauflicht
#5Mittel

LED-Lauflicht

Lichter, die nacheinander aufleuchten, als würden sie laufen. Der Arduino schaltet sechs LEDs einzeln ein; jede leuchtet kurz auf und geht wieder aus, sodass das Licht von vorn nach hinten wandert und

4.6(85)
207
Knight-Rider-Lauflicht mit einstellbarer Geschwindigkeit
#8Mittel

Knight-Rider-Lauflicht mit einstellbarer Geschwindigkeit

Ein Lichtpunkt läuft über sechs LEDs von einem Ende zum anderen, kehrt um und läuft wieder zurück. Mit dem Knopf des Potentiometers stellst du das Tempo sofort ein: Auf der einen Seite fliegt das Lich

4.5(60)
120
LED-Lauflicht mit einstellbarer Geschwindigkeit
#7Mittel

LED-Lauflicht mit einstellbarer Geschwindigkeit

Sechs LEDs leuchten nacheinander auf, sodass das Licht von einem Ende zum anderen zu laufen scheint. Drehst du am Knopf des Potentiometers, ändert sich das Tempo sofort: in die eine Richtung rast das

4.6(72)
146
WS2812B Knight-Rider-Lauflicht
#73Mittel
Premium

WS2812B Knight-Rider-Lauflicht

Auf einem smarten LED-Streifen gleitet ein roter Lichtpunkt von einem Ende zum anderen und wieder zurück, ein Hin und Her ohne Pause. Bei jedem Schritt lässt der Arduino nur eine LED leuchten, wartet

4.9(73)
94
WS2812B-Lauflicht (auffüllend)
#72Mittel
Premium

WS2812B-Lauflicht (auffüllend)

Ein Lichtstreifen, der sich füllt und leert wie ein Glas Wasser. Der Arduino schaltet zehn Farb-LEDs nacheinander in Orange ein und lässt sie an; ist der Streifen voll, schaltet er sie in derselben Re

4.7(50)
65
ESP32 Lauflicht LED
#108Anfänger

ESP32 Lauflicht LED

6 LEDs, die sich nacheinander von links nach rechts und von rechts nach links bewegen (Knight Rider Stil). Grundlegendes Beispiel für die Verwendung von for-Schleifen und Arrays. Lehrt die Logik des Richtungswechsels.

4.5(19)
32
Raspberry Pi Pico Knight Rider LED-Scanner (6 LED Hin-Zurück)
#154Anfänger

Raspberry Pi Pico Knight Rider LED-Scanner (6 LED Hin-Zurück)

Klassischer "Knight Rider"-LED-Scanner-Effekt mit Pico! 6 LEDs gehen von links nach rechts, dann von rechts nach links, für immer. Lerne reversed() und zwei getrennte for-Schleifen für Hin-Zurück-Muster.

0.0(0)
13