Rehberler · 9 dk okuma

Yılbaşı Ağacı LED Arduino: WS2812B ile Kar ve Gökkuşağı Efekti

Arduino ile yılbaşı ağacı LED ışıkları yap: WS2812B şerit, kar yağışı, gökkuşağı ve yanıp sönme efektleri, butonla mod değiştirme, 5 V güç hesabı ve kodlar.

Yılbaşı ağacı LED projesi için Arduino ve WS2812B şerit LED kullanmak, hazır ağaç ışıklarının sunduğu birkaç sabit modun ötesine geçmenin en eğlenceli yoludur. Her LED'in rengini ve parlaklığını tek tek kontrol edebildiğin için ağacına tepeden aşağı süzülen kar taneleri, dalların etrafında dönen bir gökkuşağı ya da rastgele yanıp sönen kırmızı, yeşil ve altın sarısı yıldızlar ekleyebilirsin. Üstelik bütün bunlar için yalnızca tek bir veri kablosu, bir buton ve doğru seçilmiş bir 5 V adaptör yeterlidir.

Bu rehberde malzeme listesinden başlayıp şerit uzunluğuna göre güç kaynağı hesabını, adaptör, kart ve şerit arasındaki doğru bağlantıyı, butonla efekt değiştiren eksiksiz bir Arduino Uno programını (FastLED) ve aynı projenin ESP32 (Adafruit NeoPixel) ile Raspberry Pi Pico (MicroPython) sürümlerini adım adım kuracağız. Sonunda şeridi ağaca nasıl saracağını, güvenlikte nelere dikkat edeceğini ve en sık karşılaşılan sorunları nasıl çözeceğini de öğreneceksin.

WS2812B NeoPixel adreslenebilir RGB LED
WS2812B: içinde kendi sürücü yongası olan, tek veri hattıyla zincirlenebilen 5 V adreslenebilir RGB LED.

Yılbaşı ağacı için neden WS2812B şerit LED?

Klasik yılbaşı ışıklarında bütün ampuller aynı anda yanar ya da birkaç grup hâlinde sırayla çalışır. WS2812B'de ise her LED'in içinde küçük bir sürücü yonga bulunur. Arduino veri hattından art arda renk bilgisi gönderir; ilk LED kendi 24 bitlik payını alır, kalanını bir sonraki LED'e aktarır. Böylece 100 ya da 300 LED'lik bir şeridi tek bir pinle yönetirsin ve her LED'e ayrı bir renk verebilirsin. Bu yapı sayesinde kar yağışı gibi hareketli efektler, sabit ışıklarla imkânsız olan bir canlılık kazanır. Adreslenebilir LED'lerin çalışma mantığını daha derinlemesine öğrenmek istersen WS2812B NeoPixel LED yazısına göz atabilirsin.

ÖzellikDeğer
Paket5050 SMD, sürücü yonga LED'in içinde
Besleme5 V (yaklaşık 3,5–5,3 V arası)
AkımRenk başına yaklaşık 20 mA, tam beyazda yaklaşık 60 mA
VeriTek hat, 800 kHz, LED başına 24 bit (G-R-B sırası)
Veri süresiLED başına 30 µs; 100 LED yaklaşık 3 ms
Veri girişi eşiğiMantık 1 için en az 0,7 × VDD (5 V'ta 3,5 V)
RenkKanal başına 256 seviye, toplam 16,7 milyon renk
Şerit yoğunluğu30, 60 ve 144 LED/m
KesmeHer LED arasındaki bakır pedlerin ortasından kesilebilir

Malzeme listesi

  • WS2812B şerit LED: 1,5–1,8 m boyunda bir ağaç için 60 LED/m yoğunluklu 2,5 m ya da 30 LED/m'lik 5 m şerit iyi bir başlangıçtır. Silikon kaplı IP65 modeller dallara takılmaya ve tozlanmaya karşı daha dayanıklıdır.
  • Kontrol kartı: Arduino Uno, Nano, ESP32 ya da Raspberry Pi Pico.
  • 5 V adaptör: Akım değerini aşağıdaki tabloya göre seç; 100 LED için 5 V 4 A rahat bir seçimdir.
  • Dişi DC jak (vidalı klemensli): Adaptörün fişini lehim yapmadan kablolara bağlamak için.
  • 1000 µF / 10 V elektrolitik kondansatör: Şerit girişindeki ani akım dalgalanmalarını yumuşatır.
  • 330 Ω direnç: Veri hattına seri bağlanır; sinyaldeki yansımaları ve ilk LED'in giriş akımını sınırlar.
  • Push buton: Efektler arasında geçiş yapmak için.
  • Kalın kablo: 5V ve GND hatları için en az 0,75–1,5 mm² kesitli kablo.
  • İsteğe bağlı 74AHCT125 ya da 74HCT245: ESP32 ve Pico'nun 3,3 V'luk veri sinyalini 5 V'a yükseltmek için.

Güç kaynağı hesabı: kaç amperlik adaptör gerekir?

WS2812B'nin içindeki kırmızı, yeşil ve mavi yongaların her biri tam parlaklıkta yaklaşık 20 mA çeker; yani bir LED tam beyazda yaklaşık 60 mA harcar. En kötü durum akımını I = LED sayısı × 60 mA formülüyle bulursun. 100 LED'lik bir şerit bütün LED'ler bembeyaz ve tam parlaklıktayken 6 A çeker; bu da P = 5 V × 6 A = 30 W demektir. Gökkuşağı, kar ve yıldız efektlerinde LED'lerin çoğu tek renkte ya da kısık olduğu için pratikte akım en kötü durumun üçte biri civarında kalır. Güvenli bir seçim için bu tipik akımı 2 ile çarpıp en yakın adaptör değerine yuvarla, yazılımdaki akım sınırını da adaptörün yaklaşık %80'ine ayarla. Akım, gerilim ve güç arasındaki ilişkiyi Ohm Kanunu hesaplayıcısıyla kolayca kontrol edebilirsin.

LED sayısıEn kötü durum (tam beyaz)Tipik efekt akımıÖnerilen adaptörYazılım sınırı (MAX_MA)
301,8 Ayaklaşık 0,6 A5 V 2 A1600 mA
603,6 Ayaklaşık 1,2 A5 V 3 A2400 mA
1006 Ayaklaşık 2 A5 V 4 A3200 mA
1509 Ayaklaşık 3 A5 V 6 A4800 mA
300 (5 m, 60 LED/m)18 Ayaklaşık 6 A5 V 12 A9600 mA

Uzun şeritlerde ikinci sorun gerilim düşümüdür. Şeridin üzerindeki ince bakır yollar direnç gösterdiği için 5 m'lik bir şeridin sonunda gerilim 4 V'un altına inebilir; bu durumda mavi ve yeşil yongalar zayıflar, beyaz renk sarımsı ve soluk görünür. Çözüm, 5V ve GND'yi yalnızca şeridin başından değil, her 1–1,5 metrede bir (ya da her 100–150 LED'de bir) adaptörden gelen ayrı kablolarla yeniden beslemektir. Buna güç enjeksiyonu denir. Bu kablolarda 5 amper için en az 0,75 mm², 10 amper için 1,5 mm² kesit kullan; veri hattını ise yalnızca şeridin başına bağla.

Şeridi asla Arduino'nun 5V pininden beslemeye çalışma. USB'den beslenen bir Uno'nun 5V pini en fazla 400–500 mA verebilir; bu ancak birkaç LED'i kısık parlaklıkta yakmaya yeter. Daha fazlasında kart resetlenir, USB'nin koruma sigortası atar ya da kartın üzerindeki ince yollar ısınır. Şeridi her zaman doğrudan adaptörden besle.

Bağlantı şeması: 5 V adaptör, şerit ve kart

BağlantıArduino UnoESP32Raspberry Pi Pico
Şerit DIN (veri)D6 (330 Ω üzerinden)GPIO 13 (330 Ω üzerinden)GP0 (330 Ω üzerinden)
Şerit 5VAdaptör +5 VAdaptör +5 VAdaptör +5 V
Şerit GNDAdaptör GND + Uno GNDAdaptör GND + ESP32 GNDAdaptör GND + Pico GND
ButonD2 ve GNDGPIO 4 ve GNDGP15 ve GND
1000 µF kondansatörŞerit girişinde 5V–GNDŞerit girişinde 5V–GNDŞerit girişinde 5V–GND
Kartın beslemesi (bitmiş hâli)5V pini ya da USB5V (VIN) pini ya da USBVSYS (Schottky diyot üzerinden) ya da USB
  1. Şeridin üzerindeki okları bul ve okun başladığı uca (DIN) kablo lehimle. Ok yönünün tersinden, yani DOUT ucundan veri gönderirsen hiçbir LED yanmaz.
  2. Adaptörün +5 V çıkışını şeridin 5V (bazı şeritlerde +5V ya da VCC yazar) ucuna, adaptörün GND'sini şeridin GND ucuna bağla.
  3. 1000 µF kondansatörü şeridin girişinde 5V ile GND arasına bağla; uzun bacak (artı) 5V'a, gövdesinde şerit işareti olan bacak (eksi) GND'ye gelmeli.
  4. Kartın GND pinini adaptörün GND'sine bağla. Ortak GND olmadan veri sinyalinin bir referansı olmaz.
  5. Kartın veri pinini (Uno'da D6) 330 Ω direnç üzerinden şeridin DIN ucuna bağla; direnci şeride yakın tarafa koymak daha iyi sonuç verir.
  6. Butonun bir bacağını D2'ye, diğerini GND'ye bağla; dahili pull-up direnci kodda açılacak.
  7. 150'den fazla LED kullanıyorsan şeridin ortasına ve sonuna da adaptörden ayrı 5V ve GND kabloları çek.
  8. Geliştirme sırasında kartı USB'den, şeridi adaptörden besle. Proje bitince adaptörün 5 V'unu Uno'nun 5V pinine verebilirsin; bu durumda USB kablosunu aynı anda takma.
En sık yapılan hata kartın GND'si ile adaptörün GND'sini birleştirmeyi unutmaktır; bu durumda LED'ler rastgele renklerde titrer ya da hiç tepki vermez. Konunun ayrıntıları ortak GND yazısında. İkinci sık sorun ESP32 ve Pico'nun 3,3 V'luk veri sinyalidir: WS2812B, 5 V beslemede mantık 1'i güvenle algılamak için en az 3,5 V ister. Çoğu şerit 3,3 V ile de çalışır, ama ilk LED'ler titriyorsa araya bir lojik seviye dönüştürücü (74AHCT125) koy.

Arduino Uno kodu (FastLED): üç efekt ve butonla mod değiştirme

Arduino IDE'de Kütüphane Yöneticisi'ni açıp FastLED aratarak kütüphaneyi kur; ayrıntılı anlatım için Arduino'ya kütüphane ekleme yazısına bakabilirsin. Aşağıdaki program gökkuşağı, kar yağışı ve yıldız gibi yanıp sönme efektlerini içerir; butona her basışta bir sonraki efekte geçer. Kod delay() yerine millis() kullandığı için efekt çalışırken buton her an algılanır. Bu yöntemin mantığını millis ve delay farkı yazısında bulabilirsin.

C++ (Arduino IDE)
1#include <FastLED.h>
2
3#define LED_PIN     6      // şeridin DIN girişi (330 ohm üzerinden) / strip DIN input (via 330 ohm)
4#define BUTTON_PIN  2      // buton, diğer bacak GND / button, other leg to GND
5#define NUM_LEDS    100    // şeritteki LED sayısı / number of LEDs on the strip
6#define BRIGHTNESS  120    // genel parlaklık 0-255 / global brightness 0-255
7#define MAX_MA      3200   // 4 A adaptörün %80'i / 80% of a 4 A supply
8
9CRGB leds[NUM_LEDS];
10
11const uint8_t MODE_COUNT = 3;                          // 0 gökkuşağı, 1 kar, 2 yıldız / 0 rainbow, 1 snow, 2 twinkle
12const uint16_t FRAME_MS[MODE_COUNT] = {20, 60, 30};    // kare süreleri (ms) / frame times (ms)
13const CRGB XMAS[4] = {CRGB::Red, CRGB::Green, CRGB::Gold, CRGB::White};
14
15uint8_t mode = 0;
16uint8_t hue = 0;
17
18void setup() {
19  pinMode(BUTTON_PIN, INPUT_PULLUP);
20  FastLED.addLeds<WS2812B, LED_PIN, GRB>(leds, NUM_LEDS);
21  FastLED.setMaxPowerInVoltsAndMilliamps(5, MAX_MA);  // akım sınırı / current limit
22  FastLED.setBrightness(BRIGHTNESS);
23  FastLED.clear(true);                                // açılışta hepsini söndür / all off at start
24}
25
26void checkButton() {
27  static bool lastState = HIGH;
28  static unsigned long lastChange = 0;
29  bool state = digitalRead(BUTTON_PIN);
30  if (state != lastState && millis() - lastChange > 50) {  // 50 ms zıplama filtresi / 50 ms debounce
31    lastChange = millis();
32    lastState = state;
33    if (state == LOW) {                                     // basıldı / pressed
34      mode = (mode + 1) % MODE_COUNT;
35      FastLED.clear();
36    }
37  }
38}
39
40void rainbow() {
41  fill_rainbow(leds, NUM_LEDS, hue, 3);   // her LED'de ton 3 artar / hue +3 per LED
42  hue += 2;                               // renkler döner / colours rotate
43}
44
45void snowfall() {
46  for (int i = 0; i < NUM_LEDS - 1; i++) {
47    leds[i] = leds[i + 1];                // bir LED aşağı kaydır / shift one LED down
48  }
49  if (random8() < 38) {
50    leds[NUM_LEDS - 1] = CRGB::White;     // tepede yeni kar tanesi / new flake at the top
51  } else {
52    leds[NUM_LEDS - 1] = CRGB(0, 0, 24);  // koyu mavi gece / dark blue night
53  }
54}
55
56void twinkle() {
57  fadeToBlackBy(leds, NUM_LEDS, 20);      // hepsini biraz kıs / dim everything a little
58  if (random8() < 80) {
59    leds[random16(NUM_LEDS)] = XMAS[random8(4)];  // rastgele yıldız / random star
60  }
61}
62
63void loop() {
64  checkButton();
65  static unsigned long lastFrame = 0;
66  if (millis() - lastFrame >= FRAME_MS[mode]) {
67    lastFrame = millis();
68    if (mode == 0) rainbow();
69    else if (mode == 1) snowfall();
70    else twinkle();
71    FastLED.show();                       // renkleri şeride gönder / push colours to the strip
72  }
73}
Satır / ayarNe işe yarar?
NUM_LEDSŞeritteki LED sayısı; yanlış girilirse şeridin bir kısmı yanmaz ya da efektler kayar.
BRIGHTNESSGenel parlaklık (0–255). 120 civarı ağaç için yeterince parlaktır, akım ve ısı açısından da güvenlidir.
setMaxPowerInVoltsAndMilliamps(5, MAX_MA)FastLED her karede çekilecek akımı tahmin eder ve sınır aşılacaksa parlaklığı otomatik düşürür.
addLeds<WS2812B, LED_PIN, GRB>Şerit tipini, veri pinini ve renk sırasını tanımlar; WS2812B'de sıra GRB'dir.
FRAME_MSHer efektin kare süresi (ms); küçük değer daha hızlı animasyon demektir.
checkButton()Butonu 50 ms'lik zıplama filtresiyle okur ve her basışta modu bir artırır.
FastLED.show()Bellekteki renkleri şeride gönderir; çağrılmazsa hiçbir değişiklik görünmez.

Efektler nasıl çalışıyor?

Gökkuşağı: fill_rainbow fonksiyonu ilk LED'e verilen renk tonundan (hue) başlayarak her LED'de tonu 3 adım artırır. FastLED'de renk tonu 0–255 arasındadır; 100 LED'de ton toplam 300 adım ilerlediği için şeridin üzerinde bir tam renk çemberinden biraz fazlası görünür. Her karede hue değişkenini 2 artırdığımız için renkler ağacın etrafında yavaşça döner. Daha geniş renk bantları istersen 3 yerine 1 ya da 2 kullan.

Kar yağışı: Şerit ağaca alttan yukarı sarıldığında ilk LED en altta, son LED tepededir. Her karede bütün renkleri bir LED aşağı kaydırıp tepeye ya beyaz bir kar tanesi ya da koyu mavi bir gece pikseli ekliyoruz. random8() 0–255 arası bir sayı ürettiği için 38'den küçük çıkma olasılığı yaklaşık %15'tir; bu sayıyı büyütürsen kar yoğunlaşır. 60 ms'lik kare süresiyle bir kar tanesi 100 LED'i 6 saniyede iner. Yanıp sönme (yıldız): fadeToBlackBy her karede bütün LED'leri yaklaşık %8 kısar; aynı anda rastgele seçilen bir LED kırmızı, yeşil, altın sarısı ya da beyaz olarak tam parlaklıkta yanar. Sonuç, eski tip yılbaşı ışıklarını andıran ama çok daha canlı bir pırıltıdır.

Yeni bir efekt eklemek için bir fonksiyon yaz, MODE_COUNT değerini bir artır, FRAME_MS dizisine hızını ekle ve loop içindeki seçime yeni satırı koy. Örneğin bütün ağacı tek renge boyamak için fill_solid(leds, NUM_LEDS, CRGB::Red) yeterlidir; bunu her saniye kırmızı ve yeşil arasında değiştirirsen klasik bir yılbaşı efekti elde edersin.

ESP32 ile yılbaşı ağacı (Adafruit NeoPixel)

ESP32'de FastLED de çalışır, ancak burada aynı projeyi Adafruit NeoPixel kütüphanesiyle yazıyoruz; böylece iki popüler kütüphaneyi de tanımış olacaksın. Kütüphanenin güncel sürümü ESP32 Arduino çekirdeğinin 2.x ve 3.x sürümleriyle aynı kodla derlenir ve sinyali donanım RMT birimiyle üretir. Adafruit NeoPixel'de setBrightness ile kısılan renkler geri okunurken bozulabildiği için efektleri kendi parlaklık dizimizde (level) hesaplayıp her karede şeride baştan yazıyoruz. Veri pini GPIO 13, buton GPIO 4'tür. İleride ağacı telefondan yönetmek istersen WLED kurulumu yazısı hazır bir arayüz sunar.

C++ (Arduino IDE)
1#include <Adafruit_NeoPixel.h>
2
3#define LED_PIN     13     // şeridin DIN girişi (330 ohm üzerinden) / strip DIN input (via 330 ohm)
4#define BUTTON_PIN  4      // buton, diğer bacak GND / button, other leg to GND
5#define NUM_LEDS    100    // şeritteki LED sayısı / number of LEDs on the strip
6
7Adafruit_NeoPixel strip(NUM_LEDS, LED_PIN, NEO_GRB + NEO_KHZ800);
8
9const uint8_t MODE_COUNT = 3;                          // 0 gökkuşağı, 1 kar, 2 yıldız / 0 rainbow, 1 snow, 2 twinkle
10const uint16_t FRAME_MS[MODE_COUNT] = {20, 60, 30};    // kare süreleri (ms) / frame times (ms)
11const uint8_t PALETTE[4][3] = {{255, 0, 0}, {0, 255, 0}, {255, 160, 0}, {255, 255, 255}};
12
13uint8_t level[NUM_LEDS];      // LED başına parlaklık / per-LED level
14uint8_t colorIdx[NUM_LEDS];   // yıldız rengi / star colour index
15uint8_t mode = 0;
16uint16_t hue = 0;
17
18void setup() {
19  pinMode(BUTTON_PIN, INPUT_PULLUP);
20  strip.begin();
21  strip.setBrightness(110);   // genel parlaklık / global brightness
22  strip.clear();
23  strip.show();
24}
25
26void checkButton() {
27  static bool lastState = HIGH;
28  static unsigned long lastChange = 0;
29  bool state = digitalRead(BUTTON_PIN);
30  if (state != lastState && millis() - lastChange > 50) {  // 50 ms zıplama filtresi / 50 ms debounce
31    lastChange = millis();
32    lastState = state;
33    if (state == LOW) {                                     // basıldı / pressed
34      mode = (mode + 1) % MODE_COUNT;
35      memset(level, 0, sizeof(level));                      // efekt belleğini sıfırla / reset effect buffer
36      strip.clear();
37    }
38  }
39}
40
41void rainbow() {
42  for (int i = 0; i < NUM_LEDS; i++) {
43    uint16_t h = hue + (uint32_t)i * 65536UL / NUM_LEDS;   // LED'e göre ton / hue per LED
44    strip.setPixelColor(i, strip.gamma32(strip.ColorHSV(h)));
45  }
46  hue += 256;                                              // renkler döner / colours rotate
47}
48
49void snowfall() {
50  for (int i = 0; i < NUM_LEDS - 1; i++) level[i] = level[i + 1];   // bir LED aşağı kaydır / shift one LED down
51  level[NUM_LEDS - 1] = (random(100) < 15) ? 255 : 0;               // tepede yeni kar / new flake on top
52  for (int i = 0; i < NUM_LEDS; i++) {
53    if (level[i]) strip.setPixelColor(i, 255, 255, 255);            // kar tanesi / snowflake
54    else strip.setPixelColor(i, 0, 0, 24);                          // koyu mavi gece / dark blue night
55  }
56}
57
58void twinkle() {
59  for (int i = 0; i < NUM_LEDS; i++) {
60    level[i] = (level[i] > 12) ? level[i] - 12 : 0;                 // yavaşça sön / fade out
61  }
62  if (random(100) < 30) {
63    int p = random(NUM_LEDS);
64    level[p] = 255;                                                 // yeni yıldız / new star
65    colorIdx[p] = random(4);
66  }
67  for (int i = 0; i < NUM_LEDS; i++) {
68    const uint8_t *c = PALETTE[colorIdx[i]];
69    strip.setPixelColor(i, c[0] * level[i] / 255, c[1] * level[i] / 255, c[2] * level[i] / 255);
70  }
71}
72
73void loop() {
74  checkButton();
75  static unsigned long lastFrame = 0;
76  if (millis() - lastFrame >= FRAME_MS[mode]) {
77    lastFrame = millis();
78    if (mode == 0) rainbow();
79    else if (mode == 1) snowfall();
80    else twinkle();
81    strip.show();                                                   // renkleri şeride gönder / push colours to the strip
82  }
83}

Raspberry Pi Pico ve MicroPython ile yılbaşı ağacı

Raspberry Pi Pico'nun MicroPython yazılımında neopixel modülü hazır gelir; ayrıca bir şey kurman gerekmez. Modül WS2812B'nin hassas zamanlamasını kendisi hallettiği için herhangi bir GP pinini kullanabilirsin; aşağıda veri GP0'a, buton GP15'e bağlıdır. MicroPython'da genel bir parlaklık ayarı olmadığı için renkleri BRIGHT katsayısıyla kendimiz kısıyoruz. Python, C++'a göre daha yavaş çalıştığından 100 LED'de efektler akıcıdır; 300 LED'in üzerinde kare süreleri uzayabilir. MicroPython'a yeniysen MicroPython temelleri yazısıyla başlayabilirsin.

MicroPython
1from machine import Pin
2import neopixel, time, random
3
4NUM_LEDS = 100
5BRIGHT = 0.4                                   # 0-1 parlaklık / brightness
6np = neopixel.NeoPixel(Pin(0), NUM_LEDS)       # veri GP0 / data on GP0
7button = Pin(15, Pin.IN, Pin.PULL_UP)          # buton GP15-GND / button GP15-GND
8
9mode = 0
10MODE_COUNT = 3                                 # 0 gökkuşağı, 1 kar, 2 yıldız / 0 rainbow, 1 snow, 2 twinkle
11FRAME_MS = (20, 60, 30)                        # kare süreleri / frame times
12level = [0] * NUM_LEDS                         # LED başına parlaklık / per-LED level
13color_idx = [0] * NUM_LEDS                     # yıldız rengi / star colour index
14PALETTE = ((255, 0, 0), (0, 255, 0), (255, 160, 0), (255, 255, 255))
15hue = 0
16
17def scale(r, g, b):
18    return (int(r * BRIGHT), int(g * BRIGHT), int(b * BRIGHT))
19
20def wheel(pos):
21    # 0-255 -> gökkuşağı rengi / rainbow colour
22    pos = pos & 255
23    if pos < 85:
24        return (255 - pos * 3, pos * 3, 0)
25    if pos < 170:
26        pos -= 85
27        return (0, 255 - pos * 3, pos * 3)
28    pos -= 170
29    return (pos * 3, 0, 255 - pos * 3)
30
31def rainbow():
32    global hue
33    for i in range(NUM_LEDS):
34        np[i] = scale(*wheel(hue + i * 256 // NUM_LEDS))
35    hue = (hue + 2) & 255                      # renkler döner / colours rotate
36
37def snowfall():
38    for i in range(NUM_LEDS - 1):
39        level[i] = level[i + 1]                # bir LED aşağı kaydır / shift one LED down
40    level[-1] = 255 if random.randint(0, 99) < 15 else 0
41    for i in range(NUM_LEDS):
42        np[i] = scale(255, 255, 255) if level[i] else scale(0, 0, 24)
43
44def twinkle():
45    for i in range(NUM_LEDS):
46        level[i] = level[i] - 12 if level[i] > 12 else 0   # yavaşça sön / fade out
47    if random.randint(0, 99) < 30:
48        p = random.randint(0, NUM_LEDS - 1)
49        level[p] = 255                         # yeni yıldız / new star
50        color_idx[p] = random.randint(0, 3)
51    for i in range(NUM_LEDS):
52        r, g, b = PALETTE[color_idx[i]]
53        k = level[i] * BRIGHT / 255
54        np[i] = (int(r * k), int(g * k), int(b * k))
55
56effects = (rainbow, snowfall, twinkle)
57last_btn = 1
58last_change = time.ticks_ms()
59last_frame = time.ticks_ms()
60
61while True:
62    now = time.ticks_ms()
63    state = button.value()
64    if state != last_btn and time.ticks_diff(now, last_change) > 50:   # zıplama filtresi / debounce
65        last_change = now
66        last_btn = state
67        if state == 0:                         # basıldı / pressed
68            mode = (mode + 1) % MODE_COUNT
69            for i in range(NUM_LEDS):
70                level[i] = 0
71    if time.ticks_diff(now, last_frame) >= FRAME_MS[mode]:
72        last_frame = now
73        effects[mode]()
74        np.write()                             # şeride gönder / push to the strip

Şeridi ağaca yerleştirme ve güvenlik

  • Alttan başla: Şeridin DIN ucunu ağacın dibine, kontrol kutusunun yanına koy ve şeridi spiral şeklinde yukarı doğru sar. Böylece kar efekti tepeden aşağı akar ve veri kablosu kısa kalır.
  • Spiral aralığı: 1,8 m'lik bir ağaçta 20–25 cm aralıkla sarmak, 5 m'lik şeridi dallara dengeli dağıtır; ağacın tepesine doğru tur çapı küçüldüğü için aralığı biraz daraltabilirsin.
  • Dikey şeritler: Şeridi tepeden aşağı ve aşağıdan yukarı zikzak şeklinde de döşeyebilirsin. Bu yerleşimde kar efektinin yönü her ikinci şeritte ters döner, bu yüzden LED sırasını şerit numarasına göre hesaplayan küçük bir düzenleme yapman gerekir.
  • Isı: WS2812B şerit yüksek parlaklıkta ısınır; kâğıt süslerin ve kuru dalların üzerine sıkıca bastırma. Parlaklığı 100–150 civarında tutmak hem ısıyı hem akımı azaltır.
  • Adaptör güvenliği: 220 V tarafında kendi devreni kurma; CE işaretli, kapalı kasalı hazır bir 5 V adaptör kullan. Kontrol kutusunu sudan ve saksı sulamasından uzak tut, evden çıkarken ağacı kapat.
  • Sigorta: 5 A'nın üzerindeki sistemlerde adaptör çıkışına uygun değerde bir bıçak sigorta eklemek, olası bir kısa devreye karşı iyi bir önlemdir.

Yılbaşı ağacı için proje fikirleri

  • Müziğe duyarlı ağaç: Bir mikrofonla ışıkları şarkının ritmine göre yak; ayrıntılar müziğe duyarlı LED yazısında.
  • Yılbaşı geri sayımı: Gece yarısına kalan süreyi bir ekranda göster, saat 00:00 olduğunda ağaçta havai fişek efekti başlat; yılbaşı geri sayım sayacı yazısına göz at.
  • Kendiliğinden açılan ağaç: Hava karardığında ışıkları bir LDR ışık sensörü ile otomatik aç.
  • Yaklaşınca parlayan ağaç: Odaya biri girdiğinde PIR hareket sensörü ile parlaklığı artır, oda boşken kıs.
  • Telefondan kontrol: ESP32 ile bir web sayfası açıp efektleri ve renkleri telefondan seç; ESP32 web sunucusu yazısı iyi bir başlangıç noktası.
  • Tepe yıldızı ekranı: Ağacın tepesine küçük bir WS2812B LED matris yerleştirip yıldız ya da kar tanesi animasyonu oynat.

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

BelirtiOlası nedenÇözüm
Hiçbir LED yanmıyorVeri DOUT ucuna bağlı ya da GND ortak değilOk yönüne bakıp DIN ucuna bağla, kartın ve adaptörün GND'lerini birleştir
İlk LED'ler titriyor, rastgele renklerZayıf veri sinyali, 3,3 V seviye, uzun veri kablosu330 Ω direnci şeride yaklaştır, veri kablosunu kısalt, 74AHCT125 kullan
Renkler yanlış (kırmızı yerine yeşil)Renk sırası hatalıFastLED'de GRB, NeoPixel'de NEO_GRB kullan; bazı şeritler RGB sırasındadır
Şeridin sonu sarımsı ve solukGerilim düşümüOrtaya ve sona güç enjeksiyonu yap, daha kalın kablo kullan
Beyaza geçince kart resetleniyorAdaptör yetersiz, ani akım çekimiAdaptörü büyüt, MAX_MA sınırını düşür, 1000 µF kondansatörü ekle
Butona bir basışta iki mod atlıyorButon zıplamasıZıplama süresini 50 ms'den 80 ms'ye çıkar, buton kablolarını kısa tut
Pico'da efekt yavaş akıyorÇok fazla LED ve Python hesaplarıNUM_LEDS'i azalt, kare süresini artır ya da C++ ile Arduino IDE'ye geç
Şeridi ağaca takmadan önce masada birkaç dakika yüksek parlaklıkta çalıştırıp adaptörün, klemenslerin ve kabloların ısınıp ısınmadığını elinle kontrol et. Kablolar ılıktan fazla ısınıyorsa daha kalın kablo kullan ya da MAX_MA değerini düşür. Butonun bağlantı mantığını tazelemek istersen buton bağlama yazısına bakabilirsin.

Birkaç metre şerit LED, tek bir buton ve doğru boyutlandırılmış bir 5 V adaptörle yılbaşı ağacın her yıl yeni efektlerle yenilenebilen, programlanabilir bir ışık gösterisine dönüşür. Renk paletleriyle ve kare süreleriyle oynayarak kendi efektlerini tasarlayabilir, güç ve bağlantı konusunda kafana takılanlar için Arduino güç besleme rehberine dönebilirsin. BlueGrays uygulamasında WS2812B ile yürüyen LED, karaşimşek, polis çakar ve animasyon projelerini, ayrıca ESP32 ile NeoPixel şerit kontrolünü adım adım devre şemaları ve kodlarıyla bulabilirsin.

Sıkça sorulan sorular

Yılbaşı ağacı için kaç LED gerekir?

1,5–1,8 m boyunda bir ağaç için 150–300 LED, yani 30 LED/m'lik 5 m ya da 60 LED/m'lik 2,5–5 m şerit dolu ve canlı bir görünüm verir. Daha az LED ile de çalışır ama efektler seyrek görünür. LED sayısı arttıkça adaptör akımını ve kartın RAM'ini de (LED başına 3 bayt) hesaba katmalısın.

WS2812B şerit LED için kaç amperlik adaptör gerekir?

Her LED tam beyazda yaklaşık 60 mA çeker; 100 LED için en kötü durum 6 A eder. Renkli efektlerde gerçek akım bunun üçte biri civarında kaldığı için 100 LED'e 5 V 4 A adaptör yeter, yeter ki FastLED'in setMaxPowerInVoltsAndMilliamps fonksiyonuyla akımı 3200 mA ile sınırla. Uzun süre tam beyaz kullanacaksan adaptörü en kötü duruma göre seç.

WS2812B şerit 12 V ile çalışır mı?

Hayır, WS2812B 5 V'luk bir şerittir ve 12 V bağlamak LED'leri anında bozar. 12 V ile çalışan adreslenebilir şerit istiyorsan WS2811 ya da WS2815 tipini seçmelisin. Elindeki 12 V adaptörü küçük bir şerit için kullanmak istersen LM2596 gibi bir voltaj düşürücüyle 5 V elde edebilirsin, ancak bu modüller yaklaşık 2–3 A ile sınırlıdır.

FastLED mi Adafruit NeoPixel mi kullanmalıyım?

İkisi de WS2812B'yi sorunsuz sürer. FastLED; hazır gökkuşağı, renk paleti, kısma ve akım sınırlama fonksiyonlarıyla efekt yazmayı kolaylaştırır ve genellikle daha hızlıdır. Adafruit NeoPixel daha sade bir API sunar; yeni başlıyorsan birinden başlayıp ardından diğerini denemek iyi bir yoldur.

Arduino Uno ile en fazla kaç WS2812B LED kontrol edilebilir?

Sınırı RAM ve hız belirler. Uno'nun 2 KB RAM'inde her LED 3 bayt kapladığı için diğer değişkenlerle birlikte pratikte 500 LED civarında bir sınır vardır. Ayrıca her LED'e veri göndermek 30 µs sürdüğünden 1000 LED'de tek kare 30 ms'yi bulur. ESP32 ve Pico'da RAM bol olduğu için binlerce LED mümkündür; asıl sınır güç kaynağı olur.

Şerit LED'in sonu neden sarı ya da soluk yanıyor?

Bu gerilim düşümünün işaretidir. Şeridin ince bakır yolları akım arttıkça gerilimi düşürür; sondaki LED'ler 4 V'un altında mavi ve yeşili zayıf üretir, beyaz sarıya kayar. Şeridin ortasına ve sonuna adaptörden ayrı 5V ve GND kabloları çekerek ve parlaklığı biraz düşürerek sorunu çözersin.

Tüm projeleri gör
WS2812B Kullanımı
#69Orta
Premium

WS2812B Kullanımı

Her ışığı ayrı ayrı renklendirebildiğin akıllı bir LED şeridiyle tanışırsın. Arduino önce şeritteki ilk beş LED'i kırmızı yakar, bir saniye sonra kalan beşini mavi yakar, sonra hepsini söndürür ve baş

4.8(54)
70
WS2812B İle Polis Çakar Yapımı
#70Orta
Premium

WS2812B İle Polis Çakar Yapımı

Polis arabalarının tepesindeki kırmızı-mavi çakarı masana getiriyorsun. On LED'lik WS2812B şeridin bir yarısı üç kez hızla kırmızı, öbür yarısı üç kez mavi yanıp söner ve bu sıra hiç durmadan tekrarla

4.8(67)
86
WS2812B Yürüyen Led
#71Orta
Premium

WS2812B Yürüyen Led

On LED'lik şeritte yeşil bir ışık noktası baştan sona tek tek ilerler, sona varınca yeniden başa döner; her LED'de üçte bir saniye durur. WS2812B şeritteki her LED'i tek bir veri kablosuyla ayrı ayrı

4.8(58)
75
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
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 Animasyon 1
#75Orta
Premium

WS2812B Animasyon 1

56 LED'lik şeritte gökkuşağının bütün renkleri yan yana dizilir ve hiç durmadan akar, sanki şeridin üstünde ışıktan bir nehir kayıyormuş gibi. Her LED bir öncekinden biraz farklı renkte yanar; renkler

4.9(69)
89
WS2812B Animasyon 2
#76Orta
Premium

WS2812B Animasyon 2

Odana kendi kendine renk değiştiren bir ışık gösterisi kur. Arduino 30 LED'lik şeritte renkleri durmadan akıtır ve birkaç saniyede bir yeni bir renk takımına geçer: gökkuşağı, mor yeşil şeritler, siya

4.8(65)
84
ESP32 WS2812B NeoPixel Şerit Kontrolü
#126Orta
Premium

ESP32 WS2812B NeoPixel Şerit Kontrolü

WS2812B (NeoPixel) adreslenebilir LED'ler, tek bir veri pini üzerinden zincirleme kontrol edilebilen akıllı RGB LED'lerdir. Bu projede 8 LED'lik bir WS2812B şeridi Adafruit_NeoPixel kütüphanesi ile kontrol edip akıcı bir gökkuşağı animasyonu üreteceğiz. ESP32'nin 3.3V mantık seviyesi çoğu WS2812B partisinde sorunsuz çalışsa da, kararsızlık durumunda 470Ω seri direnç ve 1000µF kondansatör çözümünü göstereceğiz. Animasyon, HSV renk uzayında ton (hue) değerini kaydırarak elde edilir.

4.9(19)
30