Sahne ışıklarını kendi yazdığım yazılımla sürmek istiyordum. Elimde bir USB-DMX arayüzü vardı; üreticinin kendi programı dışında hiçbir şeyle çalışmıyordu.
Önce protokolü anlamak gerekti. DMX512’yi öğrenmek beklediğimden kısa sürdü — çünkü öğrenilecek neredeyse hiçbir şey yok.
Bütün protokol bu
BREAK ≥ 88 µs boyunca hat düşük "yeni çerçeve başlıyor"
MAB ≥ 8 µs boyunca hat yüksek "hazır ol"
START CODE 1 bayt, 0x00 "bu dimmer verisi"
KANAL 1 1 bayt (0–255)
…
KANAL 512 1 bayt
Hepsi bu. Kontrolcü bu çerçeveyi saniyede kırk küsur kez, durmadan gönderiyor. Işıklar hattı dinliyor, kendi adresinden itibaren kaç kanal kullanıyorlarsa onları okuyor, gerisini yok sayıyor.
Sağlama toplamı yok. Onay yok. Yeniden gönderim yok. Cihaz keşfi yok. Adres çakışması denetimi yok. Hata bildirimi yok. Geri kanal yok — ışık kontrolcüye hiçbir şey söyleyemiyor, yanıp yanmadığını bile.
Neden bu kadar ilkel ve neden hâlâ ayakta
İlk bakışta bunlar kusur gibi görünüyor. Düşündükçe tersine döndü.
Bir konserde kontrolcü ile fixture arasında el sıkışma olsaydı, cihazlardan biri cevap vermediğinde kontrolcü beklerdi. Beklerken diğer 40 ışık da donardı.
Oysa DMX’te bir cihaz düşerse sadece o cihaz düşüyor. Kablo akmaya devam ediyor. Yeni bir cihaz takılırsa bir sonraki çerçevede akışa katılıyor — kurulum yok, keşif yok, gecikme yok.
Ve her çerçeve tam durumu taşıyor; fark değil. Bir çerçeve kaybolursa 23 milisaniye sonra gelen bir sonrakiyle düzeliyor. Kayıp kendini onarıyor.
Güvenilirliğini hata denetiminden değil, durumu sürekli tekrarlamaktan alan bir protokol.
Cihazı konuşturmak
Protokolü anladım; sorun arayüzdü. Cihaz takılıyordu ama Windows onu bilinen bir sınıftan bir şey olarak görmüyordu — kendi sınıfını bildiriyor, kendi sürücüsünü bekliyordu.
İki yol vardı: üreticinin kapalı SDK’sını kullanmak, ya da cihaza doğrudan konuşmak. İkincisini seçtim. Cihazın sürücüsünü genel amaçlı bir USB sürücüsüyle değiştirdim; böylece işletim sistemi araya girmeden ham veri yazabilir hale geldim.
1. cihazın tanımlayıcılarını oku → hangi uç nokta, ne tipte?
2. bulk OUT uç noktası bulundu
3. 513 bayt yaz: [0x00] + 512 kanal
4. döngüyü 44 Hz'de sürdür
Üçüncü denemede ışıklar yandı.
Cihaz takıldıktan hemen sonra ilk çerçeveleri yutuyordu. Sebep: iç devresinin hazır olması birkaç yüz milisaniye sürüyor. Çözüm, ilk saniyede tamamı sıfır olan çerçeveler göndermek — hem cihazı uyandırıyor hem de takılı ışıkların önceki durumda kalmasını engelliyor.
Bir cihazın “açıldı” demesi ile “hazır” olması aynı an değil.
En yorucu kısım: hangi kanal ne yapıyor
Protokolü çözmek bir gündü. Asıl iş şuydu: elimdeki fixture’ların hangi kanalı neyi kontrol ediyor?
Kılavuzlar ya yok, ya yanlış, ya da başka bir modelin kılavuzu. Tek güvenilir yöntem ölçmek: tek bir kanalı 0’dan 255’e yavaşça sürüp ışığa bakmak.
| kanal | ölçüm sonucu |
|---|---|
| ch1–ch4 | pan / tilt (kaba + ince) |
| ch5 | renk çarkı — ayrık basamaklar, ara değer yok |
| ch6 | gobo; 200–230 arası “shake” aralığı |
| ch9–ch12 | ölü — hiçbir etkisi yok |
| ch13–ch15 | sıfırda tutulmalı: dolu bırakılırsa cihazın dahili programı devreye giriyor |
Son satır iki akşamımı aldı. Işık kendi kendine dans ediyordu ve ben gönderdiğim değerlerde hata arıyordum. Gönderdiklerimde hata yoktu — göndermediklerimde vardı.
Bir kanalı boş bırakmak onu sıfır yapmıyor; cihazın orada ne bulduğuna bağlı.
Bir de mercek gerçeği
Çok kollu bir efekt ışığında her kolun ara renk üretebildiğini varsaymıştım. Ölçtüm: mercekler ara renk üretemiyor. Her kol yalnız kırmızı, yeşil, mavi veya beyaz olabiliyor.
Bu bir kısıt. Ama kurguyu bu kısıt üzerine kurunca sonuç daha iyi oldu: ara tonları taklit eden bulanık bir görüntü yerine keskin ve kararlı renkler. Donanımın yapamadığını zorlamak yerine yapabildiğini kullanmak — ışıkta da yazılımda da aynı kural.
Ne öğrendim
Kırk yıllık bir protokolün hâlâ ayakta olmasının sebebi, kırk yıl önce doğru soruyu sormuş olması: bir ışık kontrolcüsünün gerçekten neye ihtiyacı var?
Cevap: durumu sürekli tekrarlamaya. Gerisi — el sıkışma, onay, keşif — sahnede fayda değil, risk.