Tüm yazılar
Programlama İpucu

Aynı Tag'e Üç Farklı Network'ten Yazıyordum: Son Yazan Kazandı

Bir 'adım' değişkenine üç farklı network'ten yazıyordum, makine ise yalnızca sonuncunun yazdığını yapıyordu. Bir scan içinde aynı tag'e birden fazla yazmanın neden 'son yazan kazanır' (last-writer-wins) kuralı olduğunu, ve bu kuralın neden bir adımı sessizce ezdiğini kendi vaka üzerinden anlatıyorum.

Aynı Tag'e Üç Farklı Network'ten Yazıyordum: Son Yazan Kazandı

Pazartesi, sabah. Adım makinesi garip davranıyordu: 3. adıma geçiyordu, sonra bir scan içinde 5’e sıçrayıp 4’ü atlıyordu. Üç ayrı network’te yazıyordum, üçü de “doğru” yazıyordu. Ama makine, yalnızca sonuncunun yazdığını çalıştırıyordu. Ben de o sabah, bir tag’e bir scan içinde birden fazla yazmanın, “son yazan kazanır” kuralı olduğunu öğrendim.

Bir Scan İçinde Aynı Tag’e Üç Yazma

Programda bir adim değişkeni vardı. Üç network de ona yazıyordu:

// Network A
if (#sise_geldi)  #adim := 3;

// Network B
if (#kalk_geldi)  #adim := 4;

// Network C
if (#bas_geldi)   #adim := 5;

Her network, kendi koşulunu görüyorsa adim’e yazıyordu. Sorun: bir scan içinde, üç sensör de kısa bir aralıkla aynı anda ON olabiliyordu. O scan’da, Network A adim := 3 yazdı, Network B adim := 4 yazdı, Network C adim := 5 yazdı. PLC, network’leri sırayla çalıştırır. Son yazan, C’dir. adim, 5 oldu. 3 ve 4, sessizce ezildi. Makine, 3’ten 5’e sıçradı; 4’ü (şişeyi yerleştir) atladı.

PLC sana bir hata vermedi. “Aynı tag’e üç kez yazdın” diye bir uyarı yok. Sadece, son yazan kazandı. Ve “son” olan, programda en altta olan network’tür.

Son Yazan Kazanır, En Alttaki Yazan Kazanır

Kural şu: bir scan içinde aynı tag’e birden fazla yazma varsa, sonuncu (en alttaki) network’ün yazdığı değer, o scan’ın sonunda geçerli olur. Üsttekiler, “yazıldı” gibi görünür ama kalıcı değildir; alttaki onları ezer.

Bu, adım makinesinde felakettir, çünkü adım, “tek bir yazıcı” olmalı. Adımı birden fazla yerden yazarsan, “hangisi gerçek?” sorusu, “en alttaki” ile cevaplanır — ve en alttaki, senin “asıl” adım mantığın olmak zorunda değil.

Çözüm: Bir Tag’e Bir Yazıcı

Kural şu: bir değişkeni, bir scan içinde yalnızca bir yerden yaz. Adım makinesinde, adim’e yalnızca bir network’ten, merdiven mantığıyla yaz:

// Tek yazıcı: adım merdiveni
case #adim of
  3: if (#sise_geldi)  #adim := 4;
  4: if (#kalk_geldi)  #adim := 5;
  5: if (#bas_geldi)   #adim := 6;
end case;

case bloğu, yalnızca mevcut adımın geçişini değerlendirir. Üç sensör aynı anda ON olsa bile, yalnızca #adim == 3 olan satır çalışır, adim := 4 yazar. 5’e sıçrama, imkânsız hale gelir.

Ama bu, “bir tag’e bir yazıcı” kuralının tek uygulaması. Kuralın kendisi şu: bir değişkeni yazacaksan, nereden ve kaç yerden yazdığını bil. Bir scan içinde iki yerden yazıyorsan, ikincisi birinciyi ezer. Üç yerden yazıyorsan, üçüncüsü öncekileri ezer.

Bir de ek: “son yazan kazanır”ı bilerek kullan. Bazen istersin: temel bir değer, sonra bir düzeltme, sonra bir kısıtlama (clamp). O zaman sıralama, “temel → düzeltme → kısıtlama” olmalı, ve en alttaki kısıtlama olmalı. Ama bunu bilerek yap, rastgele değil. Rastgele “son yazan” bir adımı, bir alarmı, bir güvenlik sinyalini sessizce ezebilir.

O pazartesi, o “3’ten 5’e sıçrama,” bir case bloğuyla gitti. Üç network’ten yazan adim, tek bir merdivene dönüştü. Operatör “abi artık 4’ü atlamıyor” dedi. Ben de o an anladım ki, üç yazıcı, bir “son kazanan” üretmişti; ve o son kazanan, benim adım mantığım değildi. Tek yazıcı, tek gerçek.

Bir sonraki yazıda, “acil stop ile reset aynı anda geldi, latch hangisini tuttu?” diye anlatıyorum. Bir SR latch’in, set ve reset’in aynı scan’da ON olduğu anda neden “öncelik” kuralı gerektiğini, ve çoğu latch’in neden reset’i kazandırdığını.