Rehberler · 11 dk okuma

Arduino Karaşimşek ve Yürüyen LED: Devre, Kod ve Hız Ayarı

Arduino karaşimşek ve yürüyen LED: 8 LED ve 220 Ω ile devre, dizi ve for döngüsüyle kod, potansiyometreyle hız, millis, 74HC595, WS2812B, ESP32 ve Pico.

Arduino karaşimşek devresi, yan yana dizilmiş LED'lerin bir uçtan öbür uca gidip geri dönerek sırayla yandığı, adını 80'lerin ünlü dizisi Kara Şimşek'teki (Knight Rider) konuşan araba KITT'in ön ışığından alan klasik bir LED efektidir. Kurmak için bir Arduino Uno, 6 ya da 8 LED, her LED için bir 220 Ω direnç ve birkaç jumper kablo yeter. Işık yalnızca tek yönde akıp baştan başlıyorsa buna yürüyen LED denir. İkisi de yeni başlayanların trafik lambasından hemen sonra yaptığı klasik projelerdir ve programlamanın en önemli iki aracını, yani dizileri ve for döngüsünü öğretmenin en eğlenceli yoludur.

Bu rehberde devreyi kurup önce yürüyen LED, sonra git-gel yapan karaşimşek kodunu yazacaksın. Ardından bir potansiyometreyle hızı ayarlayacak, LED'lerin bir uca birikerek dolduğu efekti ekleyecek ve aynı efekti millis() ile kodu hiç bekletmeden çalıştıracaksın. Son bölümlerde 74HC595 entegresiyle 8 LED'i yalnızca 3 pinden sürmeyi, WS2812B adreslenebilir LED'lerle tek pinden kuyruklu karaşimşek yapmayı, ESP32 ve Raspberry Pi Pico (MicroPython) sürümlerini ve en sık yapılan hataların çözümlerini bulacaksın.

Kırmızı, sarı, mavi, yeşil ve beyaz 5 mm LED'ler
Klasik karaşimşek görünümü için 6 ya da 8 adet aynı renkte (tercihen kırmızı) 5 mm LED kullan; uzun bacak anot (+), kısa bacak katottur (−).

Karaşimşek efekti nedir, yürüyen LED'den farkı ne?

Dizide KITT'in ön tamponundaki kırmızı ışık, sağa sola tarayan bir göz gibi durmadan gidip gelir. Elektronikte bu efekte, dizinin yapımcısı Glen A. Larson'ın adıyla Larson tarayıcı (Larson scanner) da denir; aynı yapımcının Battlestar Galactica dizisindeki Cylon robotlarının gözü de aynı mantıkla çalışır. Gerçek tarayıcıda yanan noktanın arkasında yavaşça sönen kızıl bir iz, yani kuyruk görünür. Basit bir LED devresinde her LED ya tam yanar ya tam söner; kuyruğu taklit etmek için LED'in parlaklığını PWM ile kademeli düşürmek gerekir. Bunu yazının ilerleyen bölümlerinde WS2812B ve ESP32 ile yapacağız. Aşağıdaki tablo bu yazıda kodlayacağın efektleri ve 8 LED'de bir turun kaç adım sürdüğünü özetler.

EfektNe yapar?8 LED'de bir turBu yazıda
Yürüyen LEDTek bir ışık soldan sağa akar, sonra baştan başlar8 adım1. adım
KaraşimşekTek bir ışık iki uç arasında gidip gelir14 adım2. ve 3. adım
Birikerek dolanHer ışık en sağdaki boş yere kadar gider ve orada kalır36 adım4. adım
Ortada buluşmaİki ışık uçlardan ortaya gelir, sonra açılır8 adım74HC595 bölümü
Kuyruklu karaşimşekBaştaki LED tam parlak, arkadakiler giderek söner14 adımWS2812B ve ESP32 bölümleri

Malzemeler ve direnç seçimi

MalzemeAdetNot
Arduino Uno (ya da Nano)1ESP32 ya da Raspberry Pi Pico da olur
5 mm LED6–8Aynı renk ve aynı seriden olursa parlaklıklar eşit görünür
220 Ω direnç6–8Her LED için bir tane; Pico'da 330 Ω
10 kΩ potansiyometre (B10K)1Yalnızca hız ayarlı sürümler için
Breadboard1Yarım boy (400 delikli) yeterli
Jumper kablo12–15Erkek-erkek
74HC595 ya da 8'li WS2812B çubuk1İsteğe bağlı: pin tasarrufu ve kuyruklu efekt bölümleri için

LED akımı kendi kendine sınırlamaz, bu yüzden her LED'e seri bir direnç takarsın. Değeri Ohm Kanunu ile bulunur: R = (besleme gerilimi − LED ileri gerilimi) / akım. Kırmızı bir LED'in ileri gerilimi yaklaşık 2 V olduğundan 5 V'ta 220 Ω ile akım (5 − 2) / 220 ≈ 13,6 mA olur. Bu, LED'i rahatça parlak yakar ve Arduino pini için önerilen 20 mA sınırının altında kalır. Birikerek dolan efektte sekiz LED aynı anda yandığında toplam akım yaklaşık 109 mA olur; bu da Uno'nun tüm pinler için verdiği 200 mA toplam sınırının içindedir. 220 Ω'luk direnci renk bantlarından tanımak için direnç renk kodu aracını, farklı renk ve gerilimler için LED direnci hesaplayıcıyı kullanabilirsin.

Devre bağlantısı: 8 LED ve potansiyometre

Her LED'in uzun bacağı (anot) bir direnç üzerinden kartın dijital pinine, kısa bacağı (katot) GND'ye gider. Breadboard'da en düzenli yol, Arduino'nun GND pinini breadboard'un mavi (−) hattına bağlamak ve sekiz LED'in kısa bacaklarını bu hatta toplamaktır. LED'leri breadboard'a eşit aralıklarla, soldan sağa pin sırasıyla diz; böylece kodda dizinin sırası ile ışığın fiziksel sırası aynı olur. Potansiyometrenin iki uç bacağı 5V ve GND'ye, orta bacağı (silecek) A0'a bağlanır. Aşağıdaki tablo bu yazıdaki tüm kodların kullandığı pinleri gösterir; 6 LED kullanacaksan son iki satırı atla ve koddaki diziden son iki pini sil. Kartının pin dizilişini Pinout aracında görebilirsin.

GörevArduino UnoESP32Raspberry Pi Pico
LED 1 (en sol)D2GPIO 18GP8
LED 2D3GPIO 19GP9
LED 3D4GPIO 21GP10
LED 4D5GPIO 22GP11
LED 5D6GPIO 23GP12
LED 6D7GPIO 25GP13
LED 7D8GPIO 26GP14
LED 8 (en sağ)D9GPIO 27GP15
Potansiyometre orta bacakA0GPIO 34GP26 (ADC0)
Potansiyometre uç bacaklar5V ve GND3V3 ve GND3V3(OUT) ve AGND
LED katotları (kısa bacak)GNDGNDGND
Seri direnç220 Ω220 Ω330 Ω
LED'leri D0 ve D1 pinlerine bağlama: bu pinler USB üzerinden kod yükleme ve Seri Monitör için kullanılır; LED takılıyken yükleme hata verebilir ve LED'ler rastgele titrer. Bu yüzden dizi D2'den başlar. LED'lerin hiçbiri yanmıyorsa önce breadboard'un mavi hattının Arduino'nun GND pinine gerçekten bağlı olduğunu kontrol et.
Arduino Uno
Arduino Uno
Breadboard
Breadboard
R · Ω
R · Ω
Jumper
Jumper

1. adım: dizi ve for döngüsüyle yürüyen LED kodu

Sekiz LED için sekiz ayrı pinMode ve on altı ayrı digitalWrite satırı yazmak mümkündür, ama kod uzar ve LED sayısını değiştirmek zahmetli hale gelir. Bunun yerine pin numaralarını bir diziye koyar, bir for döngüsüyle sırayla dolaşırsın. Dizinin ilk elemanı LEDS[0], yani D2'dir; son elemanı LEDS[7], yani D9'dur. Böylece aynı kod 6, 8 ya da 12 LED ile değişmeden çalışır, yalnızca diziyi düzenlersin. Dizilerin ve döngülerin temelini Arduino programlama temelleri yazısında daha ayrıntılı bulabilirsin.

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}
SatırNe yapar?
const int LEDS[] = {2, ..., 9};LED pinlerini soldan sağa sırasıyla tutan dizi; LEDS[0] = 2, LEDS[7] = 9
sizeof(LEDS) / sizeof(LEDS[0])Dizideki eleman sayısını hesaplar: Uno'da 16 bayt / 2 bayt = 8; diziye pin ekleyip çıkarınca kendiliğinden güncellenir
for (int i = 0; i < LED_SAYISI; i++)i değişkenini 0'dan 7'ye kadar sayar; her turda dizinin bir elemanı işlenir
pinMode(LEDS[i], OUTPUT)Sekiz pini tek bir döngüyle çıkış yapar
digitalWrite, delay(BEKLE), digitalWriteLED'i yakar, BEKLE kadar bekler, söndürür ve sıradakine geçer

BEKLE değeri 100 ms olduğunda ışık sekiz LED'i 0,8 saniyede geçer ve hemen baştan başlar. Değeri 30 ms'ye indirirsen akış çok hızlı, 300 ms'ye çıkarırsan ağır ve tek tek yanan lambalar gibi görünür. Kodu yüklemek için Araçlar menüsünden kartı ve portu seç, ardından Yükle düğmesine bas; yükleme hata verirse Arduino kod yüklenmiyor yazısındaki kontrol listesine bak.

2. adım: karaşimşek (git-gel) kodu

Karaşimşek için ışığın sağ uca varınca geri dönmesi gerekir. Bunu iki döngüyle yaparsın: ilki soldan sağa, ikincisi sağdan sola sayar. Buradaki ince nokta uç LED'lerdir. İki döngü de 0'dan 7'ye ve 7'den 0'a tam sayarsa, en sağdaki LED bir kez ileri döngünün sonunda, bir kez de geri döngünün başında yanar; uçlarda ışık iki kat uzun durur ve hareket takılıyormuş gibi görünür. Bu yüzden ileri döngü 6'da, geri döngü 1'de durur. Sonuç olarak her tur tam 14 adım sürer ve ışık uçlarda da ortadaki kadar kalır. LED'i yakıp söndüren üç satırı da yakSondur() adlı küçük bir fonksiyona taşıdık; kod hem kısalır hem okunur hale gelir.

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}
Gerçek dizideki görünüme en yakın hız, adım başına yaklaşık 60–120 ms'dir. 8 LED ve 80 ms ile bir git-gel turu 14 × 80 = 1,12 saniye sürer. 20 ms civarına inince göz birkaç LED'i aynı anda yanıyor gibi algılar ve ışık bulanık bir çizgiye dönüşür.

3. adım: potansiyometreyle hız ayarı

Hızı her seferinde kodu değiştirip yeniden yükleyerek ayarlamak yerine bir potansiyometre kullanabilirsin. Potansiyometre bir gerilim bölücüdür: orta bacağın gerilimi milin konumuna göre 0 ile 5 V arasında değişir, analogRead() bunu 0–1023 arasında bir sayıya çevirir. map(deger, 0, 1023, 400, 20) bu sayıyı 400 ile 20 ms arasında bir adım süresine dönüştürür; aralık ters yazıldığı için okunan değer büyüdükçe adım süresi kısalır ve ışık hızlanır. Mili hangi yöne çevirince hızlanacağı, uç bacakların hangisini 5V'a bağladığına bağlıdır; ters geliyorsa iki uç kabloyu yer değiştir ya da map'teki 400 ile 20'nin yerini değiştir. Potansiyometrenin iç yapısını Potansiyometre Nedir? yazısında okuyabilirsin.

10 kΩ potansiyometre
10 kΩ potansiyometre: uç bacaklar 5V ve GND'ye, ortadaki silecek bacak A0'a bağlanır.
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}

Bu sürümde adım süresi her LED'de yeniden okunur, bu yüzden mili çevirdiğin anda hız değişir. Ancak delay() çalışırken Arduino başka hiçbir şey yapamaz: 400 ms'lik yavaş bir adımın ortasında mili çevirsen bile yeni hız ancak bir sonraki adımda uygulanır. Birkaç LED'lik bir efekt için bu sorun değildir, ama butonlu mod seçimi ya da sensör okuma eklediğinde 5. adımdaki millis() yöntemine geçmen gerekir.

4. adım: birikerek dolan efekt

Birikerek dolan efektte ilk ışık soldan sağa kadar koşar ve en sağda yanık kalır. İkinci ışık da koşar ama bu kez bir solda durur; her tur hedef bir LED sola kayar ve sonunda bütün çubuk dolar. Kodda bunu iç içe iki döngüyle yaparsın: dıştaki döngü kaç LED'in biriktiğini (dolu), içteki döngü de bu turda ışığın kaç adım koşacağını sayar. Hedef yere varan LED söndürülmez; if (i < hedef) satırı tam olarak bunu sağlar. Sekiz LED'de bütün çubuğun dolması 8 + 7 + 6 + ... + 1 = 36 adım sürer.

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}

Kodun sonunda dolu çubuk 0,6 saniye gösterilir, ardından LED'ler sağdan sola tek tek söner ve efekt baştan başlar. Daha basit bir dolan çubuk istiyorsan iç döngüyü kaldırıp LED'leri sırayla yakman ve hiç söndürmemen yeterlidir; bu görünüm şarj göstergesi ya da ses seviyesi çubuğu için idealdir. Bu efektte sekiz LED'in aynı anda yandığını unutma: her LED'e ayrı direnç taktığın sürece parlaklık düşmez.

5. adım: millis() ile bekletmesiz karaşimşek

delay() kullanan kodlarda Arduino her adımda belirtilen süre boyunca donar; bu sırada butona basılsa bile fark etmez. millis() ise kart açıldığından beri geçen süreyi milisaniye olarak verir. Mantık şudur: döngü sürekli döner, her turda "son adımdan beri yeterli süre geçti mi?" diye bakar, geçtiyse yalnızca bir adım atar ve hemen çıkar. Aşağıdaki kodda karaşimşek ile dahili LED birbirinden bağımsız iki görev olarak aynı anda çalışır: karaşimşek potansiyometrenin belirlediği hızda akarken D13'teki LED kendi temposunda saniyede bir yanıp söner. Konu hakkında daha fazlası için Arduino millis() ve delay() farkı yazısına bakabilirsin.

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}

Burada iki ayrıntı önemlidir. Birincisi, zaman değişkenleri unsigned long olmalıdır; int kullanırsan Uno'da yaklaşık 32,7 saniye sonra değer taşar ve zamanlama bozulur: efekt durur ya da kontrolsüz hızlanır. İkincisi, karşılaştırma simdi - sonAdim >= aralik biçiminde çıkarma ile yapılır; millis() yaklaşık 49,7 günde bir sıfıra döndüğünde bile bu yöntem doğru çalışır. Işığın konumunu ve yönünü de iki değişkende (konum ve yon) tuttuğumuz için artık döngüler yoktur; her adımda konum bir artar ya da azalır, uçlara gelince yon işaret değiştirir.

74HC595 ile 3 pinden 8 LED

Sekiz LED, Uno'nun sekiz pinini kaplar; projene LCD, sensör ve buton eklemek istediğinde pin yetmemeye başlar. 74HC595 kaydırmalı yazmacı, sekiz çıkışını yalnızca üç Arduino pininden (veri, saat ve latch) sürer. Her LED'in durumu bir baytın bir bitidir: 1 << i ifadesi yalnızca i. biti 1 yapar, yani tek bir LED'i yakar. Bit işlemleriyle desen kurmak da kolaylaşır: (1 << i) | (0x80 >> i) aynı anda iki uçtan ortaya doğru gelen iki ışık üretir. İki entegreyi zincirleyerek aynı üç pinle 16 LED'lik bir karaşimşek de yapabilirsin; zincirleme, SPI ile hızlı sürme ve 7 segment kullanımı 74HC595 Shift Register yazısında adım adım anlatılıyor.

74HC595 piniBağlantı (Arduino Uno)
DS (14)D11
SH_CP (11)D13
ST_CP (12)D10
OE (13)GND (çıkışlar hep açık)
MR (10)5V (sıfırlama kapalı)
VCC (16) / GND (8)5V / GND, yanına 100 nF kondansatör
Q0 (15), Q1–Q7 (1–7)Her biri 470 Ω üzerinden bir LED'in anoduna
Potansiyometre orta bacakA0
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}

74HC595'in çıkışlarında 220 Ω yerine 470 Ω önerilir: entegrenin VCC ve GND pinlerinden geçen toplam akım 70 mA'i aşmamalıdır. 470 Ω ile LED başına yaklaşık 6,4 mA akar ve sekiz LED birden yandığında bile toplam 51 mA'de kalır. Karaşimşekte zaten bir ya da iki LED yandığı için LED'ler yine de rahatça görünür.

WS2812B ile tek pinden kuyruklu karaşimşek

Gerçek KITT tarayıcısına en çok benzeyen sürüm, WS2812B adreslenebilir LED'lerle yapılır. Her WS2812B'nin içinde kendi sürücüsü vardır; şerit ne kadar uzun olursa olsun tek bir veri kablosuyla her LED'in rengini ve parlaklığını ayrı ayrı ayarlarsın. Kuyruk için bir dizi tutarız: her adımda bütün LED'lerin parlaklığı üçe bölünür, baştaki LED ise 255 yapılır. Böylece arkadaki LED'ler 255, 85, 28, 9 diye hızla söner ve ışığın arkasında doğal bir iz oluşur. Bölen 3 yerine 2 yaparsan kuyruk uzar, 5 yaparsan kısalır. Aynı yöntemle LED sayısını 8'den 60'a çıkarmak için yalnızca NUM_LEDS değerini değiştirmen yeterlidir.

WS2812B adreslenebilir RGB LED
WS2812B: her LED'in içinde kendi sürücüsü vardır; DIN, 5V ve GND ile bağlanır, DOUT sonraki LED'e gider.
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}
WS2812B'yi bağlarken veri hattına 330 Ω seri direnç, 5V ile GND arasına 1000 µF kondansatör koy ve harici adaptör kullanıyorsan GND'yi Arduino ile ortak yap. Her LED tam beyazda yaklaşık 60 mA çekebilir; 8 LED'lik çubuk USB'den çalışır, ama 30 LED ve üzeri için ayrı bir 5 V adaptör gerekir. Kütüphane kurulumu, renk sırası ve güç hesabı için WS2812B NeoPixel LED yazısına bak.

ESP32 ile karaşimşek: her pinde PWM kuyruğu

Uno'da kuyruklu bir karaşimşeği normal LED'lerle yapmak zordur, çünkü PWM yalnızca 3, 5, 6, 9, 10 ve 11 numaralı pinlerde vardır; bizim D2–D9 dizimizde bunlardan yalnızca dördü bulunur. ESP32'de ise LEDC donanımı sayesinde neredeyse her çıkış pini PWM üretebilir ve klasik ESP32'de 16 PWM kanalı vardır. Güncel ESP32 Arduino çekirdeğinde analogWrite() doğrudan çalıştığı için WS2812B'deki kuyruk mantığını sıradan LED'lere uygulayabilirsin. Pinler tablodaki gibi açılışı etkilemeyen güvenli GPIO'lardır; potansiyometre, Wi-Fi açıkken de sorunsuz okunan ADC1 kanalındaki GPIO 34'e bağlanır ve ESP32'nin ADC'si 12 bit olduğu için değer 0–4095 arasındadır. ESP32'nin pinleri 3,3 V verdiği için 220 Ω ile kırmızı LED'den yaklaşık 6 mA akar; LED'ler Uno'dakinden biraz daha soluk görünür. Kart kurulumu için ESP32 Nedir? yazısına bakabilirsin.

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}

Raspberry Pi Pico ve MicroPython ile karaşimşek

Raspberry Pi Pico'da aynı efekti MicroPython ile birkaç satırda yazarsın. Pin nesnelerini bir listede tutmak, Arduino'daki diziyle aynı işi görür. time.ticks_ms() ve time.ticks_diff() ise millis() ve taşmaya karşı güvenli çıkarmanın MicroPython karşılığıdır. Potansiyometre GP26'ya (ADC0) bağlanır; read_u16() değeri 0–65535 arasında verir ve kod bunu 400–20 ms arasına çevirir. Pico'nun bütün GPIO'larından çekilen toplam akımın 50 mA'i aşmaması önerilir; bu yüzden tabloda 330 Ω seçtik: LED başına yaklaşık 4 mA akar ve sekiz LED birden yansa bile toplam 32 mA civarında kalır. BlueGrays'teki Pico karaşimşek projesi 6 LED ile GP9–GP14 pinlerini kullanır; o devreyi kurduysan PINLER listesini [9, 10, 11, 12, 13, 14] yapman yeterli. Kurulum ve Thonny ile kod yükleme için Raspberry Pi Pico Nedir? yazısına bakabilirsin.

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()

Pico'nun her GPIO'su da PWM üretebilir; machine.PWM ile her LED'e duty_u16() değeri vererek ESP32'deki kuyruklu efekti Pico'ya taşıyabilirsin. WS2812B kullanmak istersen MicroPython'un yerleşik neopixel modülü tek bir GPIO'dan şeridi sürer; ancak 5 V ile beslenen WS2812B, Pico'nun 3,3 V'luk veri sinyalini her zaman güvenilir okumayabilir; renkler bozulursa araya bir seviye dönüştürücü ekle.

Karaşimşek ile proje fikirleri

  • Ses seviye göstergesi (VU metre): KY-038 ses sensörüyle ölçtüğün ses şiddetine göre dolan çubuğun kaç LED'inin yanacağını belirle.
  • Park sensörü LED çubuğu: HC-SR04 ile mesafe azaldıkça daha fazla LED yak, çok yaklaşınca hepsini yanıp söndür.
  • Işığı yakala oyunu: Karaşimşek hızla gidip gelirken tam ortadaki LED yandığı anda butona basmaya çalış; her başarıda adım süresi kısalsın.
  • Gece otomatik dekor ışığı: Bir LDR ortamın karardığını algılayınca efekt kendiliğinden başlasın.
  • Maket araba ya da bisiklet arka ışığı: WS2812B çubukla kırmızı kuyruklu karaşimşek yap, fren butonuna basınca bütün LED'ler tam parlak yansın.
  • Seviye göstergesi: Potansiyometre konumunu ya da pil gerilimini dolan çubuk olarak göster.
  • Daha büyük ekranlar: Aynı mantığı MAX7219 LED matrise ya da LED küpe taşı.

Sık yapılan hatalar ve çözümleri

BelirtiSebepÇözüm
LED'ler çok soluk yanıyorpinMode(OUTPUT) unutulmuş; digitalWrite yalnızca dahili pull-up direncini açıyorsetup() içinde döngüyle tüm pinleri OUTPUT yap
Bir LED hiç yanmıyorLED ters takılmış, direnç ya da kablo bir sıra kaymışUzun bacak dirence ve pine, kısa bacak GND'ye; LED'i 5V ve dirençle tek başına dene
Uçlardaki LED iki kat uzun yanıyorİki döngü de uç LED'leri içeriyorİleri döngüde i < LED_SAYISI − 1, geri döngüde i > 0 kullan
Rastgele bir pin titriyor, program tuhaflaşıyorDizinin dışına taşma: i <= LED_SAYISIKoşulu i < LED_SAYISI yap; LEDS[8] diye bir eleman yoktur
Kod yüklenmiyor ya da LED'ler yüklemede titriyorLED'ler D0 ve D1'e bağlıDiziyi D2'den başlat
Potansiyometre hızı değiştirmiyorA0'a orta bacak değil uç bacak bağlı ya da değer döngü dışında bir kez okunuyorOrta bacağı A0'a bağla; analogRead'i her adımda çağır
Efekt yaklaşık 32 saniye sonra bozuluyormillis() değeri int bir değişkende tutuluyorZaman değişkenlerini unsigned long yap
WS2812B'ler hiç yanmıyor ya da rastgele renkte yanıyorOrtak GND yok, veri direnci yok ya da şerit yanlış uçtan (DOUT) bağlanmışGND'leri birleştir, 330 Ω ekle, okların başladığı DIN ucundan bağlan
Devreyi kurmadan önce kodu Tinkercad üzerinde 8 LED ve bir potansiyometreyle deneyebilirsin. Gerçek devrede bir sorun çıkarsa LED'leri tek tek test etmek için tüm pinleri birkaç saniye HIGH yapan kısa bir kod yükle; yanmayan LED'in yerini hemen görürsün.

Karaşimşek basit görünür, ama içinde diziler, döngüler, analog okuma, map(), bekletmeden zamanlama, bit işlemleri ve adreslenebilir LED'ler gibi ileride her projede kullanacağın temel fikirler vardır. Sıradaki adım için Arduino trafik lambası projesine ya da Arduino proje fikirleri listesine göz atabilirsin. BlueGrays uygulamasında yürüyen LED, karaşimşek ve hız ayarlı sürümlerini, WS2812B ile birikerek dolan ve karaşimşek efektlerini, ESP32 yürüyen LED ve Pico karaşimşek projelerini adım adım devre şeması ve hazır koduyla bulup kendi kartında deneyebilirsin.

Sıkça sorulan sorular

Arduino Uno ile kaç LED kontrol edebilirim?

Uno'nun D0–D13 ve A0–A5 olmak üzere 20 pini dijital çıkış olarak kullanılabilir; seri haberleşme için D0 ve D1'i boş bırakırsan 18 LED'i doğrudan sürebilirsin. Her LED'e ayrı direnç takmalı ve toplam akımı 200 mA'in altında tutmalısın; 18 LED birden yanacaksa 330 Ω ya da daha büyük direnç seç. Daha fazla LED için 74HC595 kaydırmalı yazmaç ya da tek pinden yüzlerce LED süren WS2812B şerit kullanılır.

Karaşimşek devresinde hangi direnç kullanılır?

5 V ile çalışan Arduino Uno'da kırmızı LED'ler için 220 Ω uygundur ve LED başına yaklaşık 13,6 mA akım verir; 330 Ω da olur ama LED'ler biraz daha soluk yanar. 3,3 V'luk ESP32'de 220 Ω, Pico'da 330 Ω önerilir. Tek LED'in yandığı efektlerde ortak tek direnç de çalışır, ama birden fazla LED yandığında parlaklık düşer; bu yüzden her LED'e ayrı direnç en doğrusudur.

Karaşimşek devresi Arduino'suz yapılabilir mi?

Evet, klasik yöntem bir 555 zamanlayıcı ve CD4017 sayıcı entegresidir. 555 saat darbesi üretir, 4017 de 10 çıkışını sırayla HIGH yapar; bu tek başına yürüyen LED verir. Git-gel için çıkışlar diyotlarla birleştirilir: 10 çıkış 6 LED'e 1-2-3-4-5-6-5-4-3-2 sırasıyla bağlanır ve hız 555'e takılan potansiyometreyle ayarlanır.

Yürüyen LED ile karaşimşek arasındaki fark nedir?

Yürüyen LED'de ışık tek yönde akar ve son LED'den sonra baştan başlar; 8 LED'de bir tur 8 adımdır. Karaşimşekte ışık uca varınca geri döner ve iki uç arasında gidip gelir; 8 LED'de bir tur 14 adımdır. Kod farkı da küçüktür: karaşimşek için ikinci, geriye sayan bir döngü eklersin.

Karaşimşekte delay yerine millis kullanmak neden daha iyi?

delay() çalışırken Arduino başka hiçbir şey yapamaz; buton basışlarını kaçırır ve sensör okuyamaz. millis() ile her döngüde yalnızca süre dolduysa bir adım atılır, kalan zamanda başka görevler de çalışır. Böylece karaşimşek akarken buton, potansiyometre ya da seri port komutları anında tepki verir.

Karaşimşek efektine kuyruk (iz) nasıl eklenir?

Kuyruk için arkadaki LED'lerin parlaklığını kademeli düşürmen gerekir; bu da PWM ister. Uno'da PWM yalnızca 3, 5, 6, 9, 10 ve 11 numaralı pinlerdedir, bu yüzden 6 LED'li bir kuyruklu karaşimşeği bu pinlerle yapabilirsin. Daha kolay yol, her LED'i ayrı ayarlayabildiğin WS2812B şerit ya da her pininde PWM olan ESP32 veya Pico kullanmaktır.

Tüm projeleri gör
Karaşimşek Led
#6Orta

Karaşimşek Led

Karaşimşek ışığı adıyla bilinen efekt: ışık altı LED'in üzerinde bir uçtan öbür uca kayar, sonra geri döner. Arduino her LED'i saniyenin onda biri kadar yakıp sıradakine geçer; uca varınca yön değişti

4.8(106)
202
Yürüyen Led
#5Orta

Yürüyen Led

Sıra sıra yanıp sönen, koşar gibi ilerleyen ışıklar. Arduino altı LED'i tek tek yakar; her biri kısa bir an parlayıp söner ve ışık baştan sona yürür, sonra yeniden başlar. Birden çok ışığı tek bir düz

4.6(85)
207
Hız Ayarlı Karaşimşek Led
#8Orta

Hız Ayarlı Karaşimşek Led

Altı LED üzerinde bir ışık bir uçtan öbür uca koşar, döner ve yeniden koşar. Potansiyometrenin düğmesini çevirerek bu koşunun hızını anında ayarlarsın: düğme bir yandayken ışık neredeyse uçar, öbür ya

4.5(60)
120
Hız Ayarlı Yürüyen Led
#7Orta

Hız Ayarlı Yürüyen Led

Altı LED sırayla yanıp söner ve ışık sanki bir uçtan öbür uca koşar. Potansiyometrenin düğmesini çevirdikçe bu koşunun hızı anında değişir: bir yöne çevirince ışık uçar, öbür yöne çevirince her LED bi

4.6(72)
146
WS2812B Karaşimşek
#73Orta
Premium

WS2812B Karaşimşek

Akıllı LED şeridinde kırmızı bir ışık noktası bir uçtan öbür uca kayar, sonra geri döner ve bu gidip gelme hiç durmaz. Arduino her adımda yalnız tek bir LED'i yakar, saniyenin onda biri bekleyip yanın

4.9(73)
94
WS2812B Yürüyen Led(Birikerek)
#72Orta
Premium

WS2812B Yürüyen Led(Birikerek)

Bir bardağa su doldurur gibi dolup boşalan bir ışık şeridi. Arduino on renkli LED'i turuncuya boyayarak tek tek yakar ve hepsi yanık kalır, şerit dolunca aynı sırayla tek tek söndürür ve gösteri yenid

4.7(50)
65
ESP32 Yürüyen LED
#108Başlangıç

ESP32 Yürüyen LED

6 LED'in sırayla soldan sağa, sağdan sola hareket etmesi (Knight Rider tarzı). For döngüsü ve dizi (array) kullanımının temel örneği. Yön değişimi mantığını öğretir.

4.5(19)
32
Raspberry Pi Pico Karaşimşek / Knight Rider (6 LED Git-Gel)
#154Başlangıç

Raspberry Pi Pico Karaşimşek / Knight Rider (6 LED Git-Gel)

Pico ile klasik "Karaşimşek" (Knight Rider) LED efekti! 6 LED önce soldan sağa yürür, sonra sağdan sola geri döner, sonsuza kadar. 80'lerin ikonik dizisindeki KITT arabasının ön ızgarası gibi. Bu proje Yürüyen LED projesinin bir üst versiyonu: aynı 6 LED devresi (GP9-GP14), farklı kod pattern'i. Yeni öğrenme: reversed() fonksiyonu ile liste ters çevirme, iki ayrı for döngüsü ile git-gel pattern, ve aynı devrede birden fazla animasyon yaratma.

0.0(0)
13