Donanım & Firmware
Donanım & Firmware

Arduino ve C# ile PC Kontrollü WS2812B LED Sistemi

WS2812B adreslenebilir LED şeridini Arduino ile kontrol edip C# Windows Forms arayüzünden seri port üzerinden efekt/parlaklık değiştirdiğim eski maker projem: bağlantı, mod mantığı, komut protokolü ve kod.

Arduino + C# ile PC kontrollü WS2812B LED sistemi kapak görseli

Bu yazıda WS2812B adreslenebilir LED şeridini Arduino üzerinden kontrol ettiğim ve bilgisayardan C# ile yazdığım küçük bir Windows arayüzüyle efektleri değiştirdiğim eski bir maker projemi anlatıyorum. Benim için bu sadece "LED yakma" denemesi değildi; Arduino, seri port haberleşmesi, C# Windows Forms arayüzü ve adreslenebilir LED efektlerini bir araya getirdiğim küçük ama öğretici bir sistemdi.

Bu Proje Neydi?

Amacım, WS2812B şeridini Arduino içinde sabit çalışan efektlerle bırakmak değil, bilgisayardan kontrol edilebilir hale getirmekti. Temel fikir şuydu:

text
Bilgisayardaki C# arayüzü

Seri port üzerinden komut gönderme

Arduino

WS2812B LED şerit

Efekt / renk / parlaklık değişimi

Yani bilgisayarda küçük bir kontrol paneli olacak, seçtiğim mod Arduino’ya seri port üzerinden gidecek, Arduino da gelen komuta göre şeritte ilgili efekti çalıştıracaktı. Elektronik ve yazılımı birleştiren güzel bir öğrenme projesiydi.

Kullandığım Malzemeler

Kullanılan Malzemeler
  • Arduino Uno / Nanokontrolcü
  • WS2812B adreslenebilir LED şerit
  • 5V adaptörşerit beslemesi
  • Jumper kablolar
  • C# / .NET Framework Windows FormsPC arayüzü
  • Arduino IDE + Adafruit NeoPixel kütüphanesi

WS2812B LED’ler adreslenebilir olduğu için her LED’i ayrı kontrol edebiliyorsun. Bu da basit renk değiştirmenin ötesinde animasyon, geçiş, meteor, fire, rainbow gibi çok daha hareketli sonuçlar üretmeyi sağlıyor.

Bağlantı Mantığı

Bağlantı tarafında mantık oldukça basitti. Veri hattı Arduino’nun D8 pininden şeridin DIN ucuna gidiyor:

text
Arduino GND       -> WS2812B GND -> Adaptör GND
Arduino D8 (DATA) -> WS2812B DIN
Adaptör 5V        -> WS2812B 5V

En önemli nokta GND ortaklamasıydı: Arduino ile şeridi besleyen adaptörün GND hattı ortaklanmadığında veri hattı sağlıklı çalışmayabiliyor. Ayrıca WS2812B üzerindeki ok yönüne dikkat etmek gerekiyor; veri hattı şeride doğru yönden, DIN ucundan girmeli.

Sistem Mimarisi

Proje iki ana parçadan oluşuyordu: LED şeridi süren Arduino tarafı ve komutları gönderen C# arayüzü.

text
1. Arduino tarafı
   - WS2812B şeridi kontrol eder.
   - Seri porttan gelen komutları okur.
   - Gelen komuta göre efekti değiştirir.
   - Parlaklık komutlarını yorumlar.

2. PC tarafı (C# Windows Forms)
   - Seri portları listeler, Arduino’ya bağlanır.
   - Butonlarla efekt komutu gönderir.
   - Scrollbar ile parlaklık komutu gönderir.

Bu yapı sayesinde şerit, Arduino kodunu değiştirmeden bilgisayar üzerinden kontrol edilebilir hale geldi.

Arduino Tarafı

Arduino kodunda Adafruit NeoPixel kütüphanesini kullandım. Başlangıçta LED pini (D8) ve LED sayısı tanımlanıyordu:

cpp
#include <Adafruit_NeoPixel.h>

#define PIN 8
#define NUM_LEDS 171

Adafruit_NeoPixel strip = Adafruit_NeoPixel(NUM_LEDS, PIN, NEO_GRB + NEO_KHZ800);

Burada PIN, şeridin data hattının bağlı olduğu Arduino pinini (D8); NUM_LEDS ise şeritteki toplam LED sayısını ifade ediyor. setup içinde şerit başlatılıp seri haberleşme açılıyor:

cpp
void setup() {
  strip.begin();
  strip.show();
  Serial.begin(9600);
  veri.reserve(5);
}

Seri haberleşmenin 9600 baud ile başlaması, PC tarafındaki C# programın da aynı baud rate ile bağlanması gerektiği anlamına geliyor.

Mod Mantığı

Arduino tarafında gelen komutlar bir mod değişkeni üzerinden yorumlanıyordu:

text
PC'den "1"  gelirse -> RGBLoop
PC'den "2"  gelirse -> Strobe
PC'den "14" gelirse -> Fire
PC'den "16" gelirse -> Meteor Rain
PC'den "21" gelirse -> OFF

Kod içinde bu yapı switch (mod) ile yönetiliyordu:

cpp
switch (mod) {
  case 1:  RGBLoop(); break;
  case 2:  Strobe(0xff, 0xff, 0xff, 10, 50, 1000); break;
  case 14: Fire(55, 120, 15); break;
  case 16: meteorRain(0xff, 0xff, 0xff, 10, 64, true, 30); break;
  case 21: setAll(0, 0, 0); break;
}

Basit ama pratik: PC tarafından sadece bir sayı göndererek Arduino’daki farklı efektleri tetikleyebiliyordum.

Desteklenen Efektler

Projede birden fazla LED efekti vardı; bazıları sabit renk, bazıları animasyon, bazıları rastgelelik içeren hareketli efektlerdi:

text
RGBLoop      Strobe        HalloweenEyes
NewKITT      Twinkle       Sparkle
SnowSparkle  RunningLights colorWipe
rainbowCycle theaterChase  theaterChaseRainbow
Fire         meteorRain    Red / Green / Blue
Random mode  OFF

Benim için güzel olan şey, Arduino’nun "bir LED yakma" cihazı değil, bir efekt motoru gibi çalışmasıydı. PC uygulaması da bu motora komut gönderen kontrol paneli oldu.

Seri Port Üzerinden Küçük Bir Komut Protokolü

Projede çok basit bir komut protokolü oluştu. Efekt değiştirmek için sayısal komutlar:

text
1  -> RGBLoop      14 -> Fire        19 -> Blue
2  -> Strobe       16 -> Meteor Rain 20 -> Random
17 -> Red          18 -> Green       21 -> OFF

Parlaklık için farklı bir format kullandım:

text
b0
b20
b50
b100

Buradaki b, Arduino tarafında bunun bir parlaklık komutu olduğunu anlamak için; devamındaki sayı ise 0-100 arası değerdi. Arduino bunu 0-255 aralığına çevirip uyguluyordu:

cpp
if (veri.charAt(0) == 'b') {
  veri = veri.substring(1, 4);
  parlaklik = veri.toInt();
  parlaklik = map(parlaklik, 0, 100, 0, 255);
  strip.setBrightness(parlaklik);
}

Bu küçük protokol projenin en sevdiğim kısımlarından biri: çok basit ama yeterince işlevsel.

Uzun Animasyonlarda Yeni Komut Yakalama Problemi

Problem

meteorRain, rainbowCycle, Fire gibi efektler uzun döngülerden oluşuyor. Bu efektler çalışırken PC’den yeni bir komut gelirse, Arduino bunu ancak mevcut animasyon bittikten sonra fark ediyordu. Bir efektten diğerine geçmek için uzun süre beklemek gerekiyordu.

Çözüm için efektlerin içinde sık sık seri portu kontrol ettim:

cpp
if (serialEvent() != false) break;

Böylece animasyon sürerken yeni komut gelirse döngü kırılıp yeni moda geçilebiliyor. Bu küçük detay projeyi belirgin şekilde daha kullanılabilir yaptı.

Mikrodenetleyici tarafında sadece efekti yazmak yetmiyor; dışarıdan gelen komutlara ne kadar hızlı tepki vereceğini de düşünmek gerekiyor.

PC Tarafı: C# Windows Forms Arayüzü

PC tarafında C# ve .NET Framework ile küçük bir Windows Forms uygulaması vardı. Seri portları listeleyip seçilen porta bağlanıyor, butonlarla efekt, scrollbar ile parlaklık komutu gönderiyordu. Uygulama açıldığında mevcut seri portlar listeleniyordu:

csharp
foreach (var serialPort in SerialPort.GetPortNames()) {
    comboBoxSeriPortlar.Items.Add(serialPort);
}

Bağlantı sırasında seri port ayarları yapılıyordu:

csharp
serialPort1.PortName = comboBoxSeriPortlar.Text;
serialPort1.BaudRate = 9600;
serialPort1.StopBits = StopBits.One;
serialPort1.DataBits = 8;

Butona basıldığında Arduino’ya doğrudan efekt numarası gidiyordu:

csharp
private void button1_Click(object sender, EventArgs e)
{
    serialPort1.Write("1");
}

Sade ama öğretici: C# tarafındaki bir UI aksiyonu, seri port üzerinden Arduino tarafında fiziksel bir LED efektine dönüşüyordu.

Parlaklık Kontrolü

PC uygulamasında parlaklık için bir scrollbar kullandım. Değer değiştiğinde b ön ekiyle gönderiliyordu:

csharp
int parlaklik = hScrollBar1.Value;
serialPort1.Write(string.Concat("b", parlaklik));

Böylece Arduino, gelen verinin ilk karakterine bakarak bunun efekt mi yoksa parlaklık komutu mu olduğunu ayırt edebiliyordu:

text
"14"  -> efekt komutu
"b50" -> parlaklık komutu

Bu kadar küçük bir ayrım bile sistemi daha düzenli hale getiriyor; benim için basit bir "mini protokol tasarımı" örneğiydi.

Öğrendiklerim

Bu proje bana birkaç şey öğretti. Arduino ile bilgisayar arasında seri port haberleşmesi basit ama güçlü; küçük bir C# arayüzüyle fiziksel bir LED sistemini kontrol etmek keyifli. Adreslenebilir LED’ler klasik RGB’den çok daha esnek; her LED’i ayrı kontrol etmek animasyonda büyük özgürlük veriyor. Mikrodenetleyici projelerinde dışarıdan gelen komutlara hızlı tepki verebilmek önemli. Ve küçük projelerde bile dokümantasyon (pin, komut listesi, kütüphane, çalışma mantığı) net yazıldığında proje yıllar sonra bile tekrar anlaşılabiliyor.

Repo

Projenin GitHub reposu (Arduino kodu, C# seri port programı, bağlantı şeması):

text
https://github.com/YasarKah/WS2812B-Arduino-PC

Sonuç

Bu proje, elektronik ve yazılımı bir araya getirdiğim erken dönem maker projelerimden biriydi. Temel fikir hâlâ güzel:

Bilgisayardan küçük bir arayüzle komut gönder, Arduino bu komutu yorumlasın ve WS2812B şeritte fiziksel bir efekt olarak göstersin.

yasarkah.com’da bu tarz eski projelerimi de arşivlemek istiyorum; çünkü bunlar sadece sonuç değil, nasıl düşündüğümü ve elektronik/yazılım tarafında nasıl öğrendiğimi de gösteriyor.