11 Ağustos 2026 Salı

Siemens Unified RT Hmi Faceplate Oluşturmak - 2

https://ujk-ujk.blogspot.com/2026/08/siemens-unified-rt-hmi-faceplate_0788399095.html
İçindekiler +

 

Selam, önceki bölümden devam edeceğiz nasipse. Devam etmeden önce özellikle acil duruş butonu gibi dijital girişler için programa yaptığım bir ilaveden bahsedeyim. Ekranda dikkati o elemanın gösterildiği yere çekmek ve bir sıkıntı olduğunu belirtmek gerekiyor. Bu amaçla faceplate içinde yaptığımız alarm animasyonunu kullanabiliriz. Yapacağımız şey, PLC programı içerisinde o dijital girişin işlendiği yerde eğer fiziksel giriş beklenen gibi değilse girişi temsil eden tamsayı değerin ikinci bitini setlemek. Bu amaçla INPUTS programına şu ilaveyi yaptım.


Bu durumda fiziksel giriş yoksa ekranda acil stop girişinin sembolü sürekli kırmızı yanıp sönecektir. Eğer operatör manuel olarak girişi gösterirse otomasyon programını kandırabilir ama hala ekranda bu sefer kırmızı-yeşil olarak yanıp sönmeye devam eder. Tabi bu arada bu girişin alarmının kontrolünü tamamen fiziksel girişe bağladığınızı unutmayın, gerekirse başka alarmlar için bu kod değişebilir.



Dijital Çıkışlar

Sıra geldi dijital çıkışlara. Proses otomasyonu ve daha birçok otomasyon tekniklerinde çıkışlar üzerinde geri besleme alarak istediğimiz işlemin gerçekleştiğine dair emin olmak isteriz. Örneğin bir motora start verdiğimizde , motorun döndüğüne dair geri besleme bilgisi alabiliriz. Bir vanayı açtığımızda bir süre içinde kapalı olduğunu gören swicin görmeyi bırakıp açık olduğunu gören swicin görmesini bekleriz gibi. 

Ayrıca dijital çıkışlar için de manuel kontrol edilebilmesi proses otomasyonunun vazgeçilmez bir ihtiyacıdır. Otomasyonda beklenmeyen bir durum oluştuğunda yetkili kişi üretimi kurtarmak adına bir vanayı veya pompayı manuel olarak durdurmak ya da çalıştırmak isteyebilir. Özellikle gıda proses otomasyonunda bir üretimin çökmesi hem ürün kaybına hem de siparişlerin yetiştirilmesinde çok önemli olan zaman kaybına neden olabilir. 


Geri Besleme (feedback) Mantığı

Bir dijital çıkışın sağlıklı çalıştığına dair 2 adet geri besleme girişi alabiliriz. Biri çıkışta enerji yokken beklenen geri besleme, mesela bir vananın kapalı olduğunu gören swiç. Diğeri çıkışta enerji varken beklenen giriş, örneğin pompanın çalışıyor olduğunu belirten bir kontak bilgisi veya vananın açık olduğunu gören swiç. Bu geri besleme girişlerinin olup olmamasına göre değişik modlarda belli bir süre sonunda alarm veririz. Bu alarm tipleri için şöyle bir öngörüde bulunalım.

  • Alarm tipi 0 : Alarm yok, yani bu çıkışla ilgili bir geri besleme sinyali almıyoruz. 
  • Alarm tipi 1 : Sadece enerjili olduğuna dair geri besleme alıyoruz. Başka bir deyişle çıkış yokken enerjili olduğuna dair sinyal geliyorsa ya da çıkış varken enerjili olduğuna dair sinyal gelmiyorsa bir süre sonra alarm vereceğiz. 
  • Alarm tipi 2 : Sadece enerjisiz olduğuna dair geri besleme alıyoruz. Bu tip nadir kullanılır, en yaygın kullanımı bazı önemli vanaların kesinlikle kapalı olduklarından emin olmaktır. Mantığı öncekinin tersi. Yani enerji yokken gelecek, enerji varken gelmeyecek.
  • Alarm tipi 3 : Hem enerjili hem de enerjisiz durum için geri besleme sinyali alıyoruz. Buna çift feedback de diyoruz. 


Bu mantık doğrultusunda plan yapmaya başlayalım. Öncelikle her dijital çıkışın alarm verme süresini hesaplamak için bir timer veya bir data blok harcamak pek akıl karı değil. Bana lazım olan süreler 5 bilemedin 10 saniye olacak. Benim kullandığım ekipmanlar en en fazla bu sürede feedback sinyali gönderir. Bu da 4 bilemedin 5 bitlik bir sayaç bana yeter demek oluyor. Elimde de 16 bitlik çıkışı (aynı girişlerde olduğu gibi) temsil eden bir hafıza bulunursa bunun 5 bitini alarm sayacı olarak kullanabilirim. 

Bu sayacı saydıracak saniyede bir tarama çıkış veren bir bit lazım ilk önce. Bu puls'i Task100ms fonksiyonum içinde üretebilirim. Biliyoruz ki bu fonksiyon 100 ms'de bir çalışıyor. 


counter adında bir değişken tanımlayıp bunun değerini bu fonksiyon her çağırıldığında bir arttırıyoruz. Yani 100 ms'de bir counter değeri artıyor. Bu değer 10 olunca (yani 1 saniye olunca) SEC adında bool bir değişkene çıkış veriyoruz. Daha sonra da counter değerini sıfırlıyoruz. Mantık kafanızı karıştırmasın, mikro işlemcilere assembler kod yazmaktan geldiğim için bu tip şeyleri çok yaparım. SEC değişkeni bir kere True değer aldı, counter değerini ondan sonra sıfırlasak da artık SEC değeri bir sonraki taramaya kadar True kalacaktır. Program geri gitmez hep ileri akıyor. 

Dijital çıkışları (daha doğrusu dijital/analog tüm çıkışları) işleyen OTUPUTS fonksiyonunu da bu Task100ms fonksiyonundan çağırırsak SEC değişkeni o fonksiyon içinde saniyede sadece bir tarama True olacaktır. Artık bu SEC değişkenini geri besleme hatalarının sayaçlarında kullanabiliriz. 


DIGOUT_FC (FC201)

Bu fonksiyon DIGIN_FC fonksiyonuna benzer şekilde ama bu sefer dijital çıkışlar için çalışacak. Çıkışların ne olacağına otomasyon programı karar verecek, yani otomasyon programı DIGOUT_BITS data bloğundaki dijital çıkışla aynı isme sahip bite yazacak. Biz o değeri alıp DIGOUT_FC fonksiyonumuza sokacağız manuel işlemleri ve alarmları işledikten sonra fiziksel çıkışa vereceğiz. Dikkat ederseniz girişlerin tersine bir işlem var. Orada fiziksel giriş alınıp işlendikten sonra otomasyon programına veriliyordu, burada otomasyon programı çıktısı alınıp işlendikten sonra fiziksel çıkışa verilecek. Zavallı otomasyon programı da bir şeyleri kontrol ettiğini zannedecek. 

Öncelikle fonksiyonumuzun giriş ve çıkışlarında neler olacak ona bir karar verelim. 


Sırayla bakalım,

  • LOG_INP : Lojik giriş olarak adlandırdım. Otomasyon programından gelecek olan bool çıkış değeri buraya bağlanacak. Yani DIGOUT_BITS... değişkeni.
  • ALR_TYP : Feedback alarm tipi. Yukarıda bahsetmiştik. Çıkış için kullanılacak feedback'lere göre bu alarm tipi değerine 0,1,2 ya da 3 değeri sabit olarak girilecek. 
  • ALR_TIME : Saniye olarak feedback alarmı verme süresi. Bu süre kadar beklenen geri besleme sinyalleri gelmezse alarm biti (bit-2) setlenecek. Tabi ki bunları yaparken alarm tipine de bakacağız.
  • FBON : Çıkış enerjilendirildiğinde gelmesi beklenen geri besleme sinyalinin fiziksel girişi buraya bağlanacak. FB yoksa False değeri girilecek.
  • FBOFF : Çıkış enerjisizkengelmesi beklenen geri besleme sinyalinin fiziksel girişi buraya bağlanacak. FB yoksa False değeri girilecek.
  • AL_RST : Alarm sıfırlama girişi. Dijital çıkışların alarmlarını sıfırlamak için tanımlayacağımız bir bool değişkeni buraya bağlayacağız. HMI üzerinden bu değişkene bağlı bir butonla alarm sıfırlama işi yapılacak. 
  • FIZ_OUT : İşlenmiş olan dijital çıkış değeri burada olacak ve direk fiziksel çıkışa bağlanacak. 
  • OUT_WORD : Çıkışı temsil eden tamsayı değişken , buraya DIGOUT_INTS data bloğu içindeki o dijital çıkışı temsil eden değişken bağlanacak. 
  • GEÇİCİ DEĞİŞKENLER : Bunların dışında fonksiyon içerisinde değişik bilgileri tutmak için kullanacağımız geçici değişkenler var, bunlar fonksiyonun kodunun akışı esnasında bazı bilgileri saklayacak. Örneğin FB_FAULT değişkeni çıkışa göre geri besleme sinyallerinin uygun olmadığı bilgisi, ama bu bir alarm değil bu değer True iken verilen süre kadar normale dönmezse alarm vereceğiz. 

Öncelikle data bloklarımızın içini IO listemizdeki dijital çıkışlara göre düzenleyelim.

ve


Sırada fonksiyon içinde kullandığımız kod var.

#FIZ_OUT := (#OUT_WORD.%X1 AND #OUT_WORD.%X4) OR (NOT #OUT_WORD.%X1 AND #LOG_INP);  
    // OUT_WORD.X1 = Force Enable
    // OUT_WORD.X4 = Force Bit
#OUT_WORD.%X0 := #FIZ_OUT;    // Copy of log out

#ALARM := #OUT_WORD.%X2;

// * Feedback alarm tipi :
// 0 - Alarm Yok
// 1 - Sadece Enerjili feedback
// 2 - Sadece Enerjisiz feedback
// 3-  Çift Yönlü feedback

#FB_FAULT := (#FIZ_OUT AND NOT #FBON AND ( #ALR_TYP = 1 OR #ALR_TYP=3) )
        OR (NOT #FIZ_OUT AND #FBON AND ( #ALR_TYP = 1 OR #ALR_TYP=3) )
        OR (NOT #FIZ_OUT AND NOT #FBOFF AND ( #ALR_TYP = 2 OR #ALR_TYP=3))
        OR (#FIZ_OUT AND #FBOFF AND ( #ALR_TYP = 2 OR #ALR_TYP=3));

#MASK := #OUT_WORD.%X3;

#SAYAC := SHR(IN := #OUT_WORD, N := 11) +
    BOOL_TO_INT("SEC" AND NOT #ALARM AND NOT #MASK AND #FB_FAULT);

IF #ALARM THEN  // Alarm varsa sayacı durdurmak için
    #SAYAC := #ALR_TIME + 1; // Sayaca alarm süresinin bir fazlasını atıyoruz
END_IF;

IF #AL_RST OR #MASK OR (NOT #FB_FAULT AND NOT #ALARM) THEN
    #SAYAC := 0; // alarm reset
END_IF;

#ALARM_NEW := (#SAYAC > #ALR_TIME AND NOT (#AL_RST OR #MASK));

#OUT_WORD.%X2 := #ALARM_NEW;

// Sayacı Yerine Koy

#OUT_WORD := (SHL(IN := #SAYAC, N := 11) OR (#OUT_WORD AND 2047));

#OUT_WORD.%X6 := #FBON;

#OUT_WORD.%X5 := #FBOFF;


Püff bu ne? Tek tek açıklayalım. En başta FIZ_OUT çıkışının değerini belirliyoruz. Buna benzer bir kodu DIGIN_FC fonksiyonumuzda da yazmıştık. Manuel bitlerinin durumuna göre ya otomasyon programından geleni fiziksel çıkışa yazıyoruz ya da manuel olarak istenen değeri çıkışa yazıyoruz. Böylece yetkili kişi ekranda animasyonun üzerine tıklayarak açılan pencereden çıkışı otomatiğe ya da manuele alarak istediği kontrolü yapabilecek.

İkinci olarak dijital çıkışı temsil eden OUT_WORD değişkeninin bit 0'ına fiziksel çıkış değerini kopyalıyoruz. Bu biti animasyonda çıkışı gösterirken beyaz ya da yeşil renk olması için kullanacağız. 

Üçüncü olarak dahili ALARM değişkenine OUT_WORD değişkeninin bit 2'sini kopyalıyoruz. Yani daha önceden bu dijital çıkışta bir alarm oluşmuşsa bu satırdan itibaren ALARM değişkeni True olacak.

Daha sonraki yorum satırlarında bir kez daha hatırlamak için alarm tipine girilecek sayıların ne anlama geldiğini tekrar yazdım, neydi bunlar diye düşünmeyeyim.

Dördüncü işlem olarak dahili FB_FAULT değerini hesaplıyorum, bu değer o andaki FB değerlerinin belirlenen alarm tipine göre beklendiği gibi olmaması durumunda True olacak. Alarm tipi 1 ya da 3 se çıkış varken ONFB gelmemesi bir hatadır. Dikkat ederseniz direk olarak fiziksel çıkışa verilen değeri kullanıyoruz. FB alarmları işlerken çıkışın manuelde ya da otomatikte olması bizi ilgilendirmez. Az öncenin tersini düşünerek alarm tipi 1 ya da 3 se çıkış yokken ONFB geliyorsa bu yine bir hata durumudur. Alarm tipi 2 ya da 3 se ve çıkış yokken FBOFF yani enerjisiz feedback'i gelmiyorsa bu da bir hatadır. Bunun tersine alarm tipi 2 ya da 3 se ve çıkış varken hala FBOFF geliyorsa bu da bir hatadır. Böylece olası tüm hata durumlarını işlemiş olduk. Eğer feedback'lerde herhangi bir yanlış varsa FB_FAULT değeri bu satılardan itibaren True olacak. 

Beşinci işlemde dahili MASK değişkenine çıkışı temsil eden OUT_WORD değerinin bit 3'ünü kopyalıyorum. Bu bit sadece ekrandan resetleniyor veya setleniyor ve alarmın engellenmesi için kullanılıyor, daha önce bahsetmiştik. Direk bit 3'üde kullanabilirdik ama her seferinde neydi bu bit 3 demeyelim.

Altıncı işlemde OUT_WORD değerinin içindeki bitlere sakladığımız SAYAC değerini çekiyoruz. Bütün dijital çıkışa ait bilgiler bir tek yerde bulunsun diye böyle düşündüm. 16 bitlik OUT_WORD değişkeninin en değerli 5 bitinde sayaç değerini saklayacağım. Bu yüzden değeri 11 bit sağa kaydırıyorum ki bizim sayaç için kullandığımız 5 bit en alta gelsin (bit 0 dan itibaren olsun) ki normal matematik işlem yapabileyim, kafam karışmasın. Peki sayaç nasıl artacak? BOOL_TO_INT metodu parantez içindeki işlemin sonucu True ise 1 değeri False ise 0 değeri çıkartır. Burada daha önceden zaten verilmiş alarm yok ve alarm maskelenmemiş (yani engellenmemiş) ve o anda feedbeck'ler uygun değilse (FB_FAULT değeri) saniyede bir kere (SEC değeri) sayaca 1 eklenecektir.

Yedinci işlem eğer daha önceden verilmiş alarm varsa sayaca alarm süresinin bir fazlasını yazmak. Bu işlemin amacı sayacı hala alarm verir bir değerde tutmak. Eğer bir şekilde sayaç sıfırlanmışsa (mesela PLC'ye online değer yazarak) alarm silinmesin diye.

Sekizinci işlem eğer AL_RST (operatörün ekrandan alarm silme isteği) veya MASK (ekrandan çıkışın alarm vermesi engellenmiş) varsa sayacı sıfırlamak. Buradaki üçüncü koşul alarm oluşmadan önce feedback'ler düzelirse sayacı sıfırlamak için. Örneğin bir vanayı açmak için çıkış verdiğinizde ONFB hemen gelmez 1-2 saniye bazen 8 saniye sonra gelir, vana daha açılıyor. Bu arada sayaç FB gelmediği için saniyeleri saymaya başlar. Eğer süre bitmeden önce FB gelirse sayacı da sıfırlamamız gerekir.

Dokuzuncu işlemde yeni bir alarm oluştuğunu belirten ALARM_NEW yerel değişkenini belirliyor. Eğer AL_RST ve MASK yoksa (veya'larının değili, değillerinin  ve'sine eşittir) ve sayaç değeri de verilen alarm süresini geçtiyse alarm oluşmuş demektir. 

Onuncu işlemde hesaplanan alarm biti değeri ALARM_NEW , çıkışı temsil eden OUT_WORD değişkeni bit 2'sine kopyalanıyor. Hatırlarsak animasyonda bit 2 kırmızı yakıp söndürerek alarm olduğunu belirtiyordu.

On birinci işlem SAYAC değerini OUT_WORD içinde yerine koymak. Önce OUT_WORD değerini 2047 ile AND'leyerek en değerli 5 bitini resetliyoruz. 2047 sayısının binary ifadesi 0000 0111 1111 1111'dir. Sonra sayaç değerini sola doğru 11 bit kaydırarak bu en üstteki 5 bite OR işlemi ile monte ediyoruz.

Son olarak da OUT_WORD değişkeni beşinci ve altıncı bitlerine FBOFF ve FBON değerlerini yazıyoruz ki ekran animasyonlarında gerekirse o çıkışa ait FB değerlerini de gösterebilelim.




OUTPUTS Programı (FC 251)

Bu program 100ms'de bir çağırılacak (yani Task100ms içinde çağırılacak) ve PLC'mize bağlı tüm dijital ve analog çıkıları işlemek için kullanılacak. Hazırladığımız DIGOUT_FC yardımıyla dijital çıkışlarımızı işleyen programları buraya ekleyelim.

//  ****     **     **   **  ********    **    **        
//  **  **   **     **   **  ********   ****   **        
//  **   **  **     **   **     **     **  **  **    
//  **   **  **     **   **     **    ******** **      
//  **  **   **  ** **   **     **    ******** *******  
//  ****     **   ***    **     **    **    ** *******  


// O40_0_0 - P01 - Ürün Pompası 1
"DIGOUT_FC"(LOG_INP := "DIGOUT_BITS".P01,
            ALR_TYP := 1,
            ALR_TIME := 5,
            FBON := "I40_0_1",
            FBOFF := FALSE,
            AL_RST := "AL_RST",
            FIZ_OUT => "O40_0_0",
            OUT_WORD := "DIGOUT_INTS".P01);


// O40_0_1 - V01 - Vana 1
"DIGOUT_FC"(LOG_INP := "DIGOUT_BITS".V01,
            ALR_TYP := 2,
            ALR_TIME := 8,
            FBON := FALSE,
            FBOFF := "I40_0_2",
            AL_RST := "AL_RST",
            FIZ_OUT => "O40_0_1",
            OUT_WORD := "DIGOUT_INTS".V01);


// O40_0_2 - V02 - Vana 2
"DIGOUT_FC"(LOG_INP := "DIGOUT_BITS".V02,
            ALR_TYP := 3,
            ALR_TIME := 5,
            FBON := "I40_0_3",
            FBOFF := "I40_0_4",
            AL_RST := "AL_RST",
            FIZ_OUT => "O40_0_2",
            OUT_WORD := "DIGOUT_INTS".V02);


// O40_0_3 - V03 - Vana 3
"DIGOUT_FC"(LOG_INP := "DIGOUT_BITS".V03,
            ALR_TYP := 0,
            ALR_TIME := 5,
            FBON := FALSE,
            FBOFF := FALSE,
            AL_RST := "AL_RST",
            FIZ_OUT => "O40_0_3",
            OUT_WORD := "DIGOUT_INTS".V03);


Gördüğümüz üzere feedback tipleri IO listemizde yer alan FB girişlerine göre belirlendi ve listede mevcut olan FB girişleri DIGOUT_FC parametrelerinde ilgili yerlere kondu. Olmayan FB girişleri için ise FALSE değeri girildi, zaten bu girişler fonksiyon içinde değersiz olacaklar. 

Sıra geldi bu dijital çıkışlar için ekranda faceplate'ler tanımlayıp animasyonlarını ve manuel kontrollerini oluşturmaya.



Unified HMI Ekranında Pompa İçin Faceplate

Önce pompa şekli için basit bir şekili grup içinde toplayalım.


İki tane silindir gibi görünsün diye gradient boyanmış dikdörtgen ve 4 tane ayak ifade edecek çizgi var. Özellikleri şöyle.

  • Dikdörtgen : left=0, top=5, height=20, width=10, fill pattern = Vertical tricolor gradient, BG = 51,51,51 , BG alternative = 192,192,192
  • Dikdörtgen : left=10, top=0, height=30, width=40, fill pattern = Vertical tricolor gradient, BG = 51,51,51 , BG alternative = 192,192,192
  • Çizgiler 1 piksel siyah ölçüler left, top, start x, start y, end x, end y  olarak 11-30-0-5-3-0, 14-30-3-5-0-0, 43-30-0-5-3-0, 46-30-3-5-0-0 

Çizgileri ve dikdörtgenleri rastgele çizip grupladıktan sonra grup edit yapıp bu ölçüleri girerseniz kolay olur.

Daha önce dijital giriş için içinde yuvarlaklar olan bir faceplate tasarlamıştık. Şimdi de bu pompa resminin üzerine koymak için karelerden oluşan bir faceplate hazırlayalım. Property, Tag ve Event interface'ler aynı olacağı için eskisinden yararlanalım. Libraries > Project Library > Types > DijitalGiriş nesnesine sağ tıklayıp Dublicate type tıklayalım. Açılan pencerede Name of type değerine Motor yazalım. Yeni faceplate Motor adıyla kütüphanemize eklenecektir. Sağ tıklayıp Edit type seçerek düzenlemek üzere faceplate'i açalım. 

Butonu kenara çekip faceplate içinde geride kalan tüm yuvarlakları silelim. Şimdi buraya 4 tane kare ekleyeceğiz.

  • Çıkış manuel kontrolde karesi : bg color = sarı, bg fill pattern = solid, border width = 0, left = 5, top = 5, width = 30, height = 30. Animasyonu ConnectTag bit 1 ile görünür olacak (Visibility)
  • Alarmı maskelenmiş karesi : border color = kırmızı, border width = 2, background fill pattern = transparent, left = 6, top = 6, width = 28, height = 28. Animasyonu ConnectTag bit 3 ile görünür olacak (Visibility)
  •  Aktivasyon karesi : bg color = beyaz, solid, border color = siyah, border width = 2, left = 11, top = 11, width = 18, height = 18.Animasyonu bg color, ConnectedTag bit 0 sıfırken beyaz bir'ken yeşil.
  • Alarm yanıp sönen kare : bg color = beyaz, border width = 0, left = 12, top = 12, width = 16, height = 16. Animasyonu ConnectedTag bit 2 ile görünür olacak ve bit 0 sıfırken beyaz-kırmızı, bir'ken yeşil-kırmızı flashing yapacak. Flashing seçince alternetive value yanıp sönecek diğer rengi belirler unutmayın.

Bu kareleri ekleyince garibim buton en altta kaldı ona da sağ tıklayıp Arrange > Bring to front ile en üste getirin ve yerine taşıyın. Release the version tıklayarak faceplate'imizi kaydedelim, artık kullanıma hazır. 








Devam edecek...



Hiç yorum yok:

Yorum Gönder