Бегущие огни Knight Rider на Arduino: схема, код и регулировка скорости
Собираем бегущие огни Knight Rider на Arduino: 8 светодиодов и резисторы 220 Ω, код с массивом и циклом for, регулировка скорости потенциометром, millis, 74HC595, WS2812B, ESP32 и Pico.
Схема Arduino Knight Rider — классический светодиодный эффект: ряд светодиодов загорается один за другим, и огонёк пробегает от одного края к другому и обратно. Название взято от сканера на передней части KITT, говорящей машины из знаменитого сериала 1980-х «Рыцарь дорог» (Knight Rider). Понадобятся только Arduino Uno, 6 или 8 светодиодов, по резистору 220 Ω на каждый светодиод и несколько перемычек. Если огонёк бежит только в одну сторону, а затем начинает снова с начала, это бегущий огонь (LED chaser). Оба проекта — классика, которую новички собирают сразу после светофора, и самый весёлый способ освоить два важнейших инструмента программирования: массивы и цикл for.
В этом руководстве сначала собирается схема и пишется код бегущего огня, затем — код Knight Rider с движением туда и обратно. После этого ты задашь скорость потенциометром, добавишь эффект, в котором светодиоды накапливаются у одного края, и запустишь тот же эффект на millis(), вообще не блокируя код. В последних разделах ты найдёшь, как управлять 8 светодиодами всего с 3 пинов через микросхему 74HC595, как сделать Knight Rider с затухающим хвостом от одного пина на адресных светодиодах WS2812B, версии для ESP32 и Raspberry Pi Pico (MicroPython), а также решения самых частых ошибок.

Что такое эффект Knight Rider и чем он отличается от бегущего огня?
В сериале красный огонь на переднем бампере KITT без остановки бегает влево и вправо, как сканирующий глаз. В электронике этот эффект называют ещё сканером Ларсона (Larson scanner) — по имени продюсера сериала Глена А. Ларсона; глаза роботов-сайлонов из другого его сериала, «Звёздный крейсер „Галактика“» (Battlestar Galactica), устроены так же. У настоящего сканера за светящейся точкой виден медленно гаснущий красный след — хвост. В простой схеме каждый светодиод либо горит полностью, либо полностью погашен; чтобы изобразить хвост, светодиоды нужно постепенно приглушать с помощью ШИМ. Именно это мы и сделаем дальше с WS2812B и ESP32. В таблице ниже собраны эффекты, которые программируются в этой статье, и сколько шагов занимает один круг с 8 светодиодами.
| Эффект | Что делает | Один круг с 8 светодиодами | В этой статье |
|---|---|---|---|
| Бегущий огонь | Один огонёк бежит слева направо, затем начинает снова | 8 шагов | Шаг 1 |
| Knight Rider | Один огонёк отскакивает между двумя краями | 14 шагов | Шаги 2 и 3 |
| Накопление | Каждый огонёк бежит до крайнего правого свободного места и остаётся там | 36 шагов | Шаг 4 |
| Встреча в центре | Два огонька идут от краёв к центру, затем расходятся | 8 шагов | Раздел о 74HC595 |
| Knight Rider с хвостом | Головной светодиод горит на полной яркости, следующие за ним гаснут | 14 шагов | Разделы о WS2812B и ESP32 |
Список деталей и выбор резистора
| Деталь | Кол-во | Примечание |
|---|---|---|
| Arduino Uno (или Nano) | 1 | Подойдёт и ESP32 или Raspberry Pi Pico |
| Светодиод 5 мм | 6–8 | Одного цвета и из одной партии, чтобы яркость была одинаковой |
| Резистор 220 Ω | 6–8 | По одному на светодиод; на Pico — 330 Ω |
| Потенциометр 10 kΩ (B10K) | 1 | Только для версий с регулировкой скорости |
| Макетная плата | 1 | Хватит половинной (400 отверстий) |
| Провода-перемычки | 12–15 | Типа «папа–папа» |
| 74HC595 или линейка WS2812B на 8 светодиодов | 1 | Необязательно: для разделов об экономии пинов и эффекте хвоста |
Светодиод не ограничивает свой ток, поэтому каждому светодиоду нужен последовательный резистор. Номинал находится по закону Ома: R = (напряжение питания − прямое напряжение светодиода) / ток. У красного светодиода прямое напряжение около 2 V, поэтому при 5 V и 220 Ω ток равен (5 − 2) / 220 ≈ 13,6 mA. Светодиод горит ярко, а ток остаётся ниже рекомендуемых для пина Arduino 20 mA. В эффекте накопления, когда одновременно горят все восемь светодиодов, суммарный ток около 109 mA — это всё ещё в пределах лимита Uno в 200 mA на все пины вместе. Чтобы узнать резистор 220 Ω по цветным полосам, воспользуйся утилитой цветового кода резисторов; для других цветов и напряжений попробуй калькулятор резистора для светодиода.
Подключение: 8 светодиодов и потенциометр
Длинная ножка (анод) каждого светодиода идёт через резистор к цифровому пину платы, а короткая (катод) — к GND. На макетной плате аккуратнее всего соединить пин GND Arduino с синей (−) шиной макетки и вывести на эту шину короткие ножки всех восьми светодиодов. Расставь светодиоды на равном расстоянии слева направо в порядке пинов: тогда порядок в массиве кода совпадёт с физическим порядком огонька. Два крайних вывода потенциометра идут к 5V и GND, а средний (движок) — к A0. В таблице ниже указаны пины, которые используют все скетчи этой статьи; если светодиодов 6, пропусти две последние строки со светодиодами и удали два последних пина из массива в коде. Расположение пинов твоей платы можно посмотреть в утилите распиновки.
| Назначение | Arduino Uno | ESP32 | Raspberry Pi Pico |
|---|---|---|---|
| Светодиод 1 (крайний левый) | D2 | GPIO 18 | GP8 |
| Светодиод 2 | D3 | GPIO 19 | GP9 |
| Светодиод 3 | D4 | GPIO 21 | GP10 |
| Светодиод 4 | D5 | GPIO 22 | GP11 |
| Светодиод 5 | D6 | GPIO 23 | GP12 |
| Светодиод 6 | D7 | GPIO 25 | GP13 |
| Светодиод 7 | D8 | GPIO 26 | GP14 |
| Светодиод 8 (крайний правый) | D9 | GPIO 27 | GP15 |
| Средний вывод потенциометра | A0 | GPIO 34 | GP26 (ADC0) |
| Крайние выводы потенциометра | 5V и GND | 3V3 и GND | 3V3(OUT) и AGND |
| Катоды светодиодов (короткая ножка) | GND | GND | GND |
| Последовательный резистор | 220 Ω | 220 Ω | 330 Ω |




Шаг 1: код бегущего огня с массивом и циклом for
Для восьми светодиодов можно написать восемь отдельных строк pinMode и шестнадцать отдельных строк digitalWrite, но код получится длинным, а менять количество светодиодов станет мучением. Вместо этого номера пинов кладутся в массив, и по нему проходит цикл for. Первый элемент массива — LEDS[0], это D2; последний — LEDS[7], это D9. Так один и тот же код без изменений работает с 6, 8 или 12 светодиодами; правится только массив. Основы массивов и циклов подробнее объяснены в статье Основы программирования Arduino.
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}| Строка | Что делает |
|---|---|
| const int LEDS[] = {2, ..., 9}; (массив пинов) | Массив с пинами светодиодов по порядку слева направо; LEDS[0] = 2, LEDS[7] = 9 |
| sizeof(LEDS) / sizeof(LEDS[0]) (число элементов) | Вычисляет количество элементов: на Uno 16 байт / 2 байта = 8; при добавлении или удалении пинов значение пересчитывается автоматически |
| for (int i = 0; i < LED_SAYISI; i++) (цикл) | Считает переменную i от 0 до 7; каждый проход обрабатывает один элемент массива |
| pinMode(LEDS[i], OUTPUT) (режим выхода) | Делает все восемь пинов выходами одним циклом |
| digitalWrite, delay(BEKLE), digitalWrite (включить, ждать, выключить) | Включает светодиод, ждёт BEKLE миллисекунд, выключает его и переходит к следующему |
При BEKLE (время шага) 100 мс огонёк проходит все восемь светодиодов за 0,8 секунды и сразу начинает снова. Уменьши до 30 мс — и бег станет очень быстрым; подними до 300 мс — и он будет выглядеть медленным, словно лампы загораются одна за другой. Чтобы загрузить код, выбери плату и порт в меню «Инструменты» (Tools) и нажми «Загрузка» (Upload); если загрузка не проходит, пройдись по списку проверок в статье Код не загружается в Arduino.
Шаг 2: код Knight Rider (туда и обратно)
Для эффекта Knight Rider огонёк должен развернуться, дойдя до правого края. Это делается двумя циклами: первый считает слева направо, второй — справа налево. Тонкий момент здесь — крайние светодиоды. Если оба цикла считают полностью, от 0 до 7 и от 7 до 0, крайний правый светодиод загорается один раз в конце прямого цикла и ещё раз в начале обратного; на краях огонёк задерживается вдвое дольше, и движение выглядит рваным. Поэтому прямой цикл останавливается на 6, а обратный — на 1. В итоге каждый круг занимает ровно 14 шагов, и на краях огонёк стоит столько же, сколько в середине. Ещё три строки, которые включают и выключают светодиод, вынесены в маленькую функцию yakSondur() («зажечь и погасить»); код стал и короче, и понятнее.
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}Шаг 3: регулировка скорости потенциометром
Чтобы не менять код и не загружать его заново каждый раз ради другой скорости, можно использовать потенциометр. Потенциометр — это делитель напряжения: напряжение на среднем выводе меняется от 0 до 5 V в зависимости от положения вала, а analogRead() превращает его в число от 0 до 1023. map(deger, 0, 1023, 400, 20) переводит это число во время шага от 400 до 20 мс; поскольку диапазон записан наоборот, чем больше показание, тем короче шаг и тем быстрее огонёк. В какую сторону крутить вал для ускорения, зависит от того, какой крайний вывод подключён к 5V; если направление кажется обратным, поменяй местами два крайних провода или числа 400 и 20 в map(). Как потенциометр устроен внутри, читай в статье Что такое потенциометр?.

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}В этой версии время шага считывается заново для каждого светодиода, поэтому скорость меняется сразу, как только поворачивается вал. Однако пока работает delay(), Arduino не может делать ничего другого: даже если повернуть вал посреди медленного шага в 400 мс, новая скорость применится только со следующего шага. Для эффекта с несколькими светодиодами это не проблема, но как только появляются кнопка режимов или чтение датчиков, нужно переходить на метод millis() из шага 5.
Шаг 4: эффект накопления
В эффекте накопления первый огонёк пробегает до самого правого края и остаётся гореть справа. Второй огонёк тоже бежит, но на этот раз останавливается на одну позицию левее; с каждым кругом цель сдвигается на один светодиод влево, пока вся полоса не заполнится. В коде это делается двумя вложенными циклами: внешний считает, сколько светодиодов уже накопилось (dolu, то есть «заполнено»), а внутренний — сколько шагов пробегает огонёк в этом круге. Светодиод, дошедший до своей цели (hedef), не выключается; за это отвечает строка if (i < hedef). С восемью светодиодами заполнение всей полосы занимает 8 + 7 + 6 + ... + 1 = 36 шагов.
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}В конце скетча заполненная полоса показывается 0,6 секунды, затем светодиоды гаснут по одному справа налево, и эффект начинается заново. Если нужна более простая заполняющаяся шкала, просто убери внутренний цикл и включай светодиоды по порядку, ни разу не выключая; такой вид идеален для индикатора заряда или шкалы уровня звука. Помни, что в этом эффекте все восемь светодиодов горят одновременно: пока у каждого светодиода свой резистор, яркость не упадёт.
Шаг 5: неблокирующий Knight Rider на millis()
В коде с delay() Arduino на каждом шаге замирает на заданное время; даже если в это время кто-то нажмёт кнопку, плата этого не заметит. millis() же возвращает время в миллисекундах с момента включения платы. Логика такая: loop крутится постоянно, на каждом проходе проверяет, прошло ли достаточно времени с последнего шага, если да — делает ровно один шаг и сразу выходит. В коде ниже Knight Rider и встроенный светодиод работают одновременно как две независимые задачи: пока сканер бегает со скоростью, заданной потенциометром, светодиод на D13 мигает раз в секунду в своём темпе. Подробнее об этом — в статье Arduino: millis() или delay().
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}Здесь важны две детали. Во-первых, переменные времени должны быть unsigned long; если взять int, на Uno значение переполнится примерно через 32,7 секунды, и тайминг сломается: эффект либо остановится, либо неконтролируемо ускорится. Во-вторых, сравнение делается вычитанием в форме simdi - sonAdim >= aralik (текущее время минус время последнего шага сравнивается с интервалом); этот способ продолжает работать правильно, даже когда millis() примерно раз в 49,7 дня обнуляется. Поскольку позиция и направление огонька хранятся в двух переменных (konum и yon), циклов больше нет: на каждом шаге позиция увеличивается или уменьшается на единицу, а на краях направление меняет знак.
8 светодиодов от 3 пинов с 74HC595
Восемь светодиодов занимают восемь пинов Uno; как только в проект захочется добавить LCD, датчики и кнопки, пинов начинает не хватать. Сдвиговый регистр 74HC595 управляет своими восемью выходами всего через три пина Arduino (данные, тактовый сигнал и защёлка). Состояние каждого светодиода — один бит байта: выражение 1 << i ставит в 1 только бит i, и загорается один светодиод. Узоры на битовых операциях тоже строятся легко: (1 << i) | (0x80 >> i) даёт два огонька, которые одновременно идут от обоих краёв к центру. Соединив две микросхемы цепочкой, можно сделать и 16-светодиодный Knight Rider на тех же трёх пинах; цепочки, быстрое управление по SPI и работа с 7-сегментными индикаторами пошагово разобраны в статье Сдвиговый регистр 74HC595.
| Вывод 74HC595 | Подключение (Arduino Uno) |
|---|---|
| DS (14) | D11 |
| SH_CP (11) | D13 |
| ST_CP (12) | D10 |
| OE (13) | GND (выходы всегда включены) |
| MR (10) | 5V (сброс отключён) |
| VCC (16) / GND (8) | 5V / GND, рядом конденсатор 100 nF |
| Q0 (15), Q1–Q7 (1–7) | Каждый через 470 Ω к аноду светодиода |
| Средний вывод потенциометра | A0 |
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}На выходах 74HC595 рекомендуется 470 Ω вместо 220 Ω: суммарный ток через выводы VCC и GND микросхемы не должен превышать 70 mA. С 470 Ω через каждый светодиод течёт около 6,4 mA, и даже когда горят все восемь светодиодов, сумма остаётся на уровне 51 mA. В Knight Rider одновременно горят только один-два светодиода, так что они всё равно хорошо видны.
Knight Rider с затухающим хвостом от одного пина на WS2812B
Версия, больше всего похожая на настоящий сканер KITT, делается на адресных светодиодах WS2812B. У каждого WS2812B встроен собственный драйвер; какой бы длинной ни была лента, цвет и яркость каждого светодиода задаются по отдельности по одному проводу данных. Для хвоста хранится массив: на каждом шаге яркость всех светодиодов делится на три, а головному светодиоду ставится 255. Светодиоды позади него быстро гаснут через 255, 85, 28, 9 и оставляют за огоньком естественный след. Возьми делитель 2 вместо 3 — хвост станет длиннее; возьми 5 — короче. Чтобы тем же методом перейти с 8 на 60 светодиодов, достаточно изменить NUM_LEDS.

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}Knight Rider на ESP32: ШИМ-хвост на каждом пине
На Uno Knight Rider с хвостом на обычных светодиодах сделать трудно: ШИМ есть только на пинах 3, 5, 6, 9, 10 и 11, а в нашем массиве D2–D9 из них только четыре. На ESP32 благодаря аппаратному блоку LEDC ШИМ может выдавать почти любой выходной пин, а у классической ESP32 16 каналов ШИМ. Поскольку в актуальном ядре ESP32 для Arduino analogWrite() работает напрямую, логику хвоста от WS2812B можно применить к обычным светодиодам. Пины в таблице — безопасные GPIO, которые не влияют на загрузку платы; потенциометр подключается к GPIO 34 на канале ADC1, который надёжно читает даже при включённом Wi-Fi, а поскольку АЦП ESP32 12-битный, значение меняется от 0 до 4095. Пины ESP32 выдают 3,3 V, поэтому через красный светодиод с 220 Ω течёт около 6 mA; светодиоды выглядят чуть тусклее, чем на Uno. О настройке платы — в статье Что такое ESP32?.
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 на Raspberry Pi Pico с MicroPython
На Raspberry Pi Pico тот же эффект пишется в несколько строк MicroPython. Список объектов Pin выполняет ту же роль, что массив на Arduino. time.ticks_ms() и time.ticks_diff() — аналоги millis() и защищённого от переполнения вычитания в MicroPython. Потенциометр подключается к GP26 (ADC0); read_u16() возвращает значение от 0 до 65535, и код переводит его в 400–20 мс. Суммарный ток со всех GPIO Pico рекомендуется держать ниже 50 mA; поэтому в таблице выбрано 330 Ω: через каждый светодиод течёт около 4 mA, и даже когда горят все восемь, сумма остаётся около 32 mA. В проекте BlueGrays «Огни Knight Rider на Pico» используются 6 светодиодов на пинах GP9–GP14; если собрана именно эта схема, просто замени список PINLER на [9, 10, 11, 12, 13, 14]. Об установке и загрузке кода через Thonny — в статье Что такое Raspberry Pi Pico?.
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()Каждый GPIO на Pico тоже умеет выдавать ШИМ; с machine.PWM и значением duty_u16() для каждого светодиода эффект хвоста с ESP32 переносится на Pico. Если нужны светодиоды WS2812B, встроенный в MicroPython модуль neopixel управляет лентой от одного GPIO; однако WS2812B с питанием 5 V не всегда надёжно читает сигнал данных 3,3 V от Pico, поэтому если цвета сбоят, поставь между ними преобразователь уровней.
Идеи проектов с Knight Rider
- Индикатор уровня звука (VU-метр): громкость, измеренная датчиком звука KY-038, определяет, сколько светодиодов заполняющейся шкалы загорится.
- Светодиодная шкала парктроника: зажигай больше светодиодов по мере того, как уменьшается расстояние, измеренное HC-SR04, а при сильном приближении мигай всеми сразу.
- Игра «Поймай огонёк»: пока сканер быстро бегает, старайся нажать кнопку ровно в тот момент, когда горит средний светодиод; после каждого успеха сокращай время шага.
- Автоматическое ночное украшение: эффект запускается автоматически, когда фоторезистор (LDR) замечает, что темнеет.
- Задний фонарь для модели машины или велосипеда: сделай красный Knight Rider с хвостом на линейке WS2812B, а при нажатии кнопки тормоза зажигай все светодиоды на полную яркость.
- Индикатор уровня: показывай положение потенциометра или напряжение батареи заполняющейся шкалой.
- Дисплеи побольше: перенеси ту же логику на светодиодную матрицу MAX7219 или светодиодный куб.
Частые ошибки и как их исправить
| Симптом | Причина | Решение |
|---|---|---|
| Светодиоды светят очень тускло | Нет pinMode(OUTPUT); digitalWrite лишь включает встроенный подтягивающий резистор | Сделай все пины OUTPUT циклом в setup() |
| Один светодиод никогда не загорается | Светодиод перевёрнут, или резистор либо провод сдвинут на один ряд | Длинная ножка — к резистору и пину, короткая — к GND; проверь светодиод отдельно с 5V и резистором |
| Крайние светодиоды горят вдвое дольше | Оба цикла включают крайние светодиоды | В прямом цикле используй i < LED_SAYISI − 1, в обратном — i > 0 |
| Случайный пин мигает или программа ведёт себя странно | Чтение за пределами массива: i <= LED_SAYISI | Измени условие на i < LED_SAYISI; элемента LEDS[8] не существует |
| Код не загружается, или светодиоды мигают во время загрузки | Светодиоды подключены к D0 и D1 | Начни массив с D2 |
| Потенциометр не меняет скорость | К A0 подключён крайний вывод вместо среднего, или значение читается только один раз вне цикла | Подключи средний вывод к A0; вызывай analogRead на каждом шаге |
| Эффект сбивается примерно через 32 секунды | Значение millis() хранится в переменной int | Сделай переменные времени unsigned long |
| WS2812B вообще не горят или показывают случайные цвета | Нет общей земли, нет резистора в линии данных, или лента подключена не с того конца (DOUT) | Соедини GND, добавь 330 Ω, подключай к концу DIN, от которого указывают стрелки на ленте |
Knight Rider выглядит просто, но в нём есть базовые идеи, которые пригодятся потом в каждом проекте: массивы, циклы, аналоговое чтение, map(), неблокирующие задержки, битовые операции и адресные светодиоды. Для следующего шага загляни в проект Светофор на Arduino или в список идей проектов на Arduino. В приложении BlueGrays есть проекты «Бегущий огонь», «Огни Knight Rider» и «Огни Knight Rider с регулировкой скорости», эффекты накопления и Knight Rider на WS2812B, а также «Бегущий огонь на ESP32» и «Огни Knight Rider на Pico» — каждый с пошаговой схемой подключения и готовым кодом, чтобы попробовать на своей плате.
Частые вопросы
Сколькими светодиодами может управлять Arduino Uno?
У Uno 20 пинов, которые можно использовать как цифровые выходы: D0–D13 и A0–A5; если оставить D0 и D1 свободными для последовательной связи, напрямую можно управлять 18 светодиодами. Дай каждому светодиоду свой резистор и держи суммарный ток ниже 200 mA; если все 18 будут гореть одновременно, выбери 330 Ω или больше. Для большего количества светодиодов используй сдвиговый регистр 74HC595 или ленту WS2812B, которая управляет сотнями светодиодов от одного пина.
Какой резистор нужен для бегущих огней?
На Arduino Uno с 5 V для красных светодиодов подходит 220 Ω, это около 13,6 mA на светодиод; 330 Ω тоже подойдёт, но светодиоды будут чуть тусклее. На ESP32 с 3,3 V рекомендуется 220 Ω, на Pico — 330 Ω. В эффектах, где горит только один светодиод, работает и один общий резистор, но когда загораются несколько светодиодов, яркость падает, поэтому правильный выбор — по резистору на каждый светодиод.
Можно ли собрать схему Knight Rider без Arduino?
Да, классический способ — таймер 555 и микросхема-счётчик CD4017. 555 выдаёт тактовые импульсы, а 4017 по очереди ставит в HIGH свои 10 выходов, что уже даёт бегущий огонь. Для движения туда и обратно выходы объединяются диодами: 10 выходов подключаются к 6 светодиодам в порядке 1-2-3-4-5-6-5-4-3-2, а скорость задаётся потенциометром на 555.
Чем бегущий огонь отличается от эффекта Knight Rider?
В бегущем огне огонёк движется в одну сторону и после последнего светодиода начинает заново; с 8 светодиодами один круг — 8 шагов. В Knight Rider огонёк на краю разворачивается и отскакивает между двумя краями; с 8 светодиодами один круг — 14 шагов. Разница в коде тоже небольшая: для Knight Rider добавляется второй цикл, который считает в обратную сторону.
Зачем в бегущих огнях использовать millis() вместо delay()?
Пока работает delay(), Arduino не может делать ничего другого: она пропускает нажатия кнопок и не может читать датчики. С millis() каждый проход loop делает шаг, только когда подошло время, а в оставшееся время выполняются другие задачи. Поэтому, пока сканер бегает, кнопки, потенциометры или команды по последовательному порту срабатывают мгновенно.
Как добавить затухающий хвост к эффекту Knight Rider?
Для хвоста светодиоды за головным нужно постепенно приглушать, а для этого нужен ШИМ. На Uno ШИМ есть только на пинах 3, 5, 6, 9, 10 и 11, так что Knight Rider с хвостом на 6 светодиодах можно собрать на этих пинах. Путь проще — лента WS2812B, где каждый светодиод задаётся отдельно, или ESP32 либо Pico, у которых ШИМ есть на каждом пине.
Что собрать после прочтения
Все проекты
Светодиодный эффект Knight Rider
Классический бегущий огонь-сканер: светящаяся точка скользит от одного края шести светодиодов к другому и возвращается обратно. Arduino зажигает каждый светодиод на десятую долю секунды и переходит к

Бегущие огни на светодиодах
Огни, которые загораются друг за другом, будто бегут. Arduino зажигает шесть светодиодов по одному; каждый светится короткое мгновение и гаснет, так что свет проходит от начала до конца и начинает сно

Светодиодный эффект Knight Rider с регулируемой скоростью
Свет бежит от одного края шести светодиодов к другому, разворачивается и бежит обратно. Поверни ручку потенциометра, и скорость этого бега сразу изменится: в одном крайнем положении свет почти летит,

Бегущие огни с регулируемой скоростью
Шесть светодиодов загораются друг за другом, и кажется, что свет бежит от одного края к другому. Поверни ручку потенциометра, и скорость этого бега сразу меняется: в одну сторону свет мчится, в другую

Эффект Knight Rider на WS2812B
Красная светящаяся точка скользит от одного края умной светодиодной ленты к другому, затем возвращается и бегает туда-обратно без остановки. На каждом шаге Arduino зажигает только один светодиод, ждёт

Бегущий огонь на WS2812B (эффект заполнения)
Световая лента, которая наполняется и пустеет, как стакан с водой. Arduino по одному зажигает десять цветных светодиодов оранжевым и оставляет их гореть; когда лента заполнена, выключает их по одному

Светодиоды Knight Rider на ESP32
6 светодиодов по очереди бегают слева направо и справа налево (в стиле Knight Rider). Базовый пример использования циклов for и массивов. Учит логике смены направления.

Сканер Knight Rider на Pico (6 светодиодов туда-обратно)
Классический эффект светодиодного сканера Knight Rider на Pico! 6 светодиодов бегут слева направо, затем справа налево, и так бесконечно. Как передняя решётка машины KITT из культового сериала 80-х. Этот проект — доработка проекта «Бегущие огни»: та же схема из 6 светодиодов (GP9–GP14), но другой узор в коде. Изучи функцию reversed() для разворота списка, два отдельных цикла for для движения туда-обратно и несколько анимаций на одной схеме.
Другие статьи
Приложение BlueGrays
Собери эту схему шаг за шагом в телефоне
Схема подключения, код и список деталей на одном экране. 200+ проектов на Arduino, ESP32 и Pico готовы к сборке.
Наведи камеру телефона
Наведи камеру на код — откроется магазин приложений на телефоне.
или открыть магазин

