Siemens Simatic S7 SCL Programlama Dili

Alıntıdır:Katkılarından dolayı james_sr üyemize teşekkür ederiz.

Ethernet üzerinden gelen karışık karakter bilgisini (8 karakter 8 byte) gerçek sayı olarak okunmasını sağlayan FB yi ekledim. KG bilgisi ethernet üzerinden karakter olarak gelmekteydi ve karakterlerin sırası her bağlantı koptuğunda değişkenlik gösteriyordu ve programda gerçek sayıya ihtiyacım vardı. bu program bu ihtiyaç yüzünden doğdu.


Kod:
FUNCTION_BLOCK FB207

TITLE = 'BYTE_TO_REAL_FB'
//
// Gelen "Byte" tipindeki karakterleri "real" dönüştür
//Created by xx 2010
VERSION: '1.0'
AUTHOR:'xx'
NAME:'BB_to_RE'
FAMILY:'BB_to_RE'
VAR_INPUT
db_byte_1 :BYTE; //nport'tan gelen veri -ethrnet
db_byte_2 :BYTE;
db_byte_3 :BYTE;
db_byte_4 :BYTE;
db_byte_5 :BYTE;
db_byte_6 :BYTE;
db_byte_7 :BYTE;
db_byte_8 :BYTE;

END_VAR

VAR_OUTPUT

db_real_out :REAL:=0.0;
value_ok: BOOL:=false;

END_VAR

VAR_TEMP
    // Temporary Variables

END_VAR
VAR
db_word: ARRAY[1..8] OF WORD:=0;
db_int: ARRAY[1..8] OF INT:=0; 
db_dint: ARRAY[1..8] OF DINT:=0; 
shift_real: ARRAY[1..9] OF REAL:=0.0; 


// buffer byte  kaydırmayı gerçekleştirir.
adim         :INT;   
i            :INT;

END_VAR


BEGIN
      value_ok    :=false;
      db_real_out := 0.0;

       db_word[1]    := BYTE_TO_WORD (db_byte_1) ;
       db_word[2]    := BYTE_TO_WORD (db_byte_2) ; 
       db_word[3]    := BYTE_TO_WORD (db_byte_3) ; 
       db_word[4]    := BYTE_TO_WORD (db_byte_4) ; 
       db_word[5]    := BYTE_TO_WORD (db_byte_5) ; 
       db_word[6]    := BYTE_TO_WORD (db_byte_6) ; 
       db_word[7]    := BYTE_TO_WORD (db_byte_7) ; 
       db_word[8]    := BYTE_TO_WORD (db_byte_8) ; 
                        
      
    FOR i:=1 TO 8 BY 1 DO
      db_int[i]     := WORD_TO_INT (db_word [i]) ;  
      IF db_int[i] = 32 THEN    
         db_int[i]:=0 ;
      ELSIF db_int[i] >=176 THEN
          db_int[i]:= ( db_int[i]- 176);
      ELSIF db_int[i] >=48 AND db_int[i] <=57  THEN
          db_int[i]:= ( db_int[i]- 48);
      END_IF;
   END_FOR;
 
   FOR i:=1 TO 8 BY 1 DO
     db_dint[i]    := INT_TO_DINT (db_int [i]) ;   
     shift_real[i] := DINT_TO_REAL (db_dint [i]) ;  
   END_FOR;


       
    FOR adim:=0 TO 8 BY 1 DO
      IF shift_real[1] = 45.0 OR shift_real[1] = 43.0 THEN
       db_real_out:=0.0;
       db_real_out:=(shift_real[2]*100000.0)+(shift_real[3]*10000.0)+(shift_real[4]*1000.0)+(shift_real[5]*100.0)+(shift_real[6]*10.0)+(shift_real[7]*1.0);
         IF shift_real[1] = 45.0 THEN
            db_real_out  := (-1.0)*(db_real_out);
         END_IF;  // hesaplama işlemi yap çık
      value_ok:=true;
      db_real_out := (db_real_out/1000.0);
      EXIT;
    ELSE
        // kaydırma işlemi
            shift_real[9] := shift_real[1] ; // ilk byte buffera at
            shift_real[1] := shift_real[2] ; // B2 -> B1 e taşır
            shift_real[2] := shift_real[3] ; // B3 -> B2 e taşır
            shift_real[3] := shift_real[4] ; // B4 -> B3 e taşır
            shift_real[4] := shift_real[5] ; // B5 -> B4 e taşır
            shift_real[5] := shift_real[6] ; // B6 -> B5 e taşır
            shift_real[6] := shift_real[7] ; // B7 -> B6 e taşır
            shift_real[7] := shift_real[8] ; // B8 -> B7 e taşır
            shift_real[8] := shift_real[9] ; // B1 -> B8 e taşır

       END_IF;
      
    END_FOR;
 
Son düzenleme:
Kod:
FUNCTION FC19:VOID
VAR_INPUT
GIRIS:BOOL:=FALSE;
RESET:BOOL;
END_VAR
VAR_OUTPUT
    CIKIS:REAL;
    
END_VAR
VAR
    y:REAL;
END_VAR

BEGIN
IF GIRIS =TRUE THEN
    CIKIS:=CIKIS+1;
ELSIF RESET=1 THEN
    CIKIS:=0;
END_IF;
END_FUNCTION

cıkıs degerı 1 artmıyor nedenini bilen var mı acaba
 
Moderatör tarafında düzenlendi:
Sorun şurda GIRIS degeri true oldugunda PLC programı sürekli bir döngü halinde programı taradıgından sürekli IF döngüsüne girecek ve CIKIS degişkenini sürekli 1 arttıracaktır, GIRIS değişkenin çıkan kenarında 1 arttırırsanız program sürekli IF döngüsüne girmeyecektir, çözüm aşağıdaki gibi olmalı.
Kod:
FUNCTION FC19:VOID
VAR_INPUT
GIRIS:BOOL:=FALSE;
RESET:BOOL;
END_VAR
VAR_OUTPUT
CIKIS:REAL;

END_VAR
VAR
y:REAL;
CikanKenar:BOOL;     // Çıkan kenarı test etmek için bir değişken
END_VAR

BEGIN
IF GIRIS =TRUE AND NOT CikanKenar THEN  //Çıkan kenar test ediliyor.
   CIKIS:=CIKIS+1;
ELSIF RESET=1 THEN
   CIKIS:=0;
END_IF;
CikanKenar:=GIRIS;            //Çıkan kenar tekrar kuruluyor bu bir tekniktir...
END_FUNCTION
 
Son düzenleme:
arkadaşlar scl dilinde pozitif kenar tetikleme nasıl komut olarak yazılıyor.
 
arkadaşlar scl dilinde pozitif kenar tetikleme nasıl komut olarak yazılıyor.
Çıkan ve düşen kenarları yakalamak için "Edge_flag_pos ve Edge_flag_neg" değişkenlerini kullandım, bu değişkenler S7 300-400 deki çıkan kenar işlemi yaparken harcanan hafıza bitleri gibi düşünülebilir bundan dolayı lokal değişken olmaz ve başka yerde kullanılmazlar, yani sadece kenar değişkenini testte kullanıyoruz.

Kod:
FUNCTION FC10 : VOID

VAR_INPUT
    In_Var:         BOOL;         //Bu degişkenin çıkan kenarı test edilecek
END_VAR

VAR_OUTPUT
    Pulse_pos_Var:  BOOL;   //anlık positive pulse çıkışı
    Pulse_neg_Var:  BOOL;   //anlık negative pulse çıkışı
END_VAR

VAR_IN_OUT
    Edge_flag_pos:  BOOL;  //Pozitif kenar hafıza elemanı,bu deişkeni lokal değişken kullanamassınız
    Edge_flag_neg:  BOOL;  //Negatif kenar hafıza elemanı, bu degişkeni lokal değişken kullanamassınız
END_VAR

BEGIN
// Pozitif kenarı yakalama
    Pulse_pos_Var   := In_Var AND NOT Edge_flag_pos;
    Edge_flag_pos   := In_Var;
     
//Negatif kenarı yakalama
    Pulse_neg_Var   := NOT In_Var AND Edge_flag_neg;
    Edge_flag_neg   := In_Var;
END_FUNCTION
 
Kod:
FUNCTION FC1 : void


VAR_INPUT
    frekans_Hz: REAL;  //çalışması istenilen frekansın griş değeri
    ON_value: REAL;     // çalışması istenen ON oranı yüzde cinsinden
END_VAR

VAR_OUTPUT
    pwm_out: BOOL;      // çıkış olarak darbe genlik modülasytonlu talkt
END_VAR

VAR_TEMP
    k:REAL;             // katsayı
    T:REAL;             // periyot
    ON:REAL;            // pwm çıkışının açık kaldı değer
    OFF:REAL;           // pwm çıkışının kapalı kaldığı değer
    ON_time:TIME;       // pwm çıkışının açık kaldığı sürenin time cinsinden değeri
    OFF_time:TIME;      // pwm çıkışının kapalı kaldığı sürenin TIME cinsinden değeri   
    p_edge:BOOL;        // üretilen sinyalin pozitif alternansının hissedilmesini sağlayan değişken
    n_edge:BOOL;        // üretilen sinyalin negatif aternansının hissedilmesini sağlayan değişken  
    x:BOOL;             // kenar algılanmasında kullanılacak
    y:BOOL;             // kenar algılanmasında kullanılacak

    
    //timer1(ON) için gereli değişkenler
    ON_time_out:WORD;   //timer1 word cinsinden atanacağı değişken
    ON_time_BI:WORD;    //timer1 in hex cinsinden aktarılacağı değişken
    ON_time_Q:BOOL;     //timer1 in çıkış değişkeni
    
    //timer2(OFF) için gereli değişkenler
    OFF_time_out:WORD;  //timer2 word cinsinden atanacağı değişken
    OFF_time_BI:WORD;   //timer2 nin hex cinsinden atanacağı değişken
    OFF_time_Q:BOOL;    //timer2 nin çıkış değişkeni
END_VAR

BEGIN

// periyodun bulun ma işlemi
T:=1/frekans_Hz;

// ON ve OFF sürelerinin hesaplanması için gereken katsayının hesabı
k:=1/T;

// pwm çıkışında çıkışın aktif(1) olduğu sürenin hesaplanması (REAL cinsinden)
ON:=k*ON_value;

//pwm çıkışında çıkışın pasif(0) olduğu sürenin hesaplanması  (REAL cinsinden)
OFF:=k*(100 - ON_value);

//dönüşüm işlemleri
ON_time:=DINT_TO_TIME(REAL_TO_DINT(ON));
OFF_time:=DINT_TO_TIME(REAL_TO_DINT(OFF));


// zamanlayıcıların kurulması
ON_time_out:=S_PULSE(T_NO:=T1,  S:=true,    TV:=ON_time,    R:=OFF_time_Q,   BI:=ON_time_BI,    Q:=ON_time_Q);
OFF_time_out:=S_ODTS(T_NO:=T2,  S:=true,    TV:=OFF_time,   R:=ON_time_Q,    BI:=OFF_time_BI,   Q:=OFF_time_Q);


// çıkışın kenar algılanmalarına göre kurulması

    // negatif kenar tetiklemenin yapılması
    IF NOT ON_time_Q AND NOT y THEN y:=true;   n_edge:=true;
            IF n_edge AND NOT p_edge THEN  pwm_out:=false;  n_edge:=false;  END_IF; //pwm çıkışın oluştrulması
        ELSE n_edge:=false;      
    END_IF;

    IF ON_time_Q AND  y THEN y:=false;
    END_IF;


    //pozitif kenar tetiklemenin yapılması
    IF OFF_time_Q AND NOT x THEN x:=true;    p_edge:=true;  
            IF p_edge AND NOT n_edge THEN   pwm_out:=true;  p_edge:=false;  END_IF; // pwm çıkışın oluştrulması   
        ELSE    p_edge:=false;       
    END_IF;
    
    IF NOT OFF_time_Q AND x THEN x:=false;  
    END_IF;

END_FUNCTION

deneyemedim bile daha!!! yapmaya çalıştığım şey pwm darbe üreteci umarım mantıkta hata yok tur ama ben aşağıda yazdığım sorunu bir türlü çözemedim yardımcı olusanız sevinirim

//dönüşüm işlemleri
ON_time:=DINT_TO_TIME(REAL_TO_DINT(ON));
OFF_time:=DINT_TO_TIME(REAL_TO_DINT(OFF));

değerlerin çıkışı "time" formatındadır değil mi?

eğer öyleyse bunu "timer-(S_PULSE)" da kullandığım zaman niye gecersiz data tipi diyor
 
Son düzenleme:
Değişken tanımlamalarında hata var aşağıdaki gibi olmalı, dönüşüm işlemlerini tanımlanan tiplere göre yapmalısın hata vermez.
Sistem ve standart fonksiyonların içinde "FC33 S5TI_TIM" fonksiyonu var bu fonksiyon "The function FC33 converts the data type format S5TIME to the format TIME." diyor, yani S5TIME'dan TIME formatına dönüşte bu fonksiyonu kullanabilirsiniz, kolay gelsin...


Kod:
FUNCTION FC1 : void


VAR_INPUT
    frekans_Hz: REAL;  //çalışması istenilen frekansın griş değeri
    ON_value: REAL;     // çalışması istenen ON oranı yüzde cinsinden
END_VAR

VAR_OUTPUT
    pwm_out: BOOL;      // çıkış olarak darbe genlik modülasytonlu talkt
END_VAR

VAR_TEMP
    k:REAL;             // katsayı
    T:REAL;             // periyot
    ON:REAL;            // pwm çıkışının açık kaldı değer
    OFF:REAL;           // pwm çıkışının kapalı kaldığı değer
 [B]   ON_time:S5TIME; [/B]      // pwm çıkışının açık kaldığı sürenin time cinsinden değeri
 [B]   OFF_time:S5TIME;   [/B]   // pwm çıkışının kapalı kaldığı sürenin TIME cinsinden değeri   
    p_edge:BOOL;        // üretilen sinyalin pozitif alternansının hissedilmesini sağlayan değişken
    n_edge:BOOL;        // üretilen sinyalin negatif aternansının hissedilmesini sağlayan değişken  
    x:BOOL;             // kenar algılanmasında kullanılacak
    y:BOOL;             // kenar algılanmasında kullanılacak

    
    //timer1(ON) için gereli değişkenler
[B]    ON_time_out:S5TIME;[/B]   //timer1 word cinsinden atanacağı değişken
    ON_time_BI:WORD;    //timer1 in hex cinsinden aktarılacağı değişken
    ON_time_Q:BOOL;     //timer1 in çıkış değişkeni
    
    //timer2(OFF) için gereli değişkenler
[B]    OFF_time_out:S5TIME;[/B]  //timer2 word cinsinden atanacağı değişken
    OFF_time_BI:WORD;   //timer2 nin hex cinsinden atanacağı değişken
    OFF_time_Q:BOOL;    //timer2 nin çıkış değişkeni
END_VAR
 
Son düzenleme:
Scl tımer yapmak nasıl oluyor... Odt tımer yapmak istiyorum. Yrd edersenız sevınırım
 
Scl tımer yapmak nasıl oluyor... Odt tımer yapmak istiyorum. Yrd edersenız sevınırım

Kod:
FUNCTION_BLOCK TIMER
VAR_INPUT 
  mytime : TIMER ; 
END_VAR 
VAR_OUTPUT
  result : S5TIME ;
END_VAR 
VAR
  set            : BOOL ; 
  reset       : BOOL ; 
  bcdvalue           : S5TIME ;
  binvalue           : WORD ; 
  initialvalue      : S5TIME ;
END_VAR 
BEGIN 
  Q0.0              := 1;
  set            := I0.0 ;
  reset       := I0.1;
  initialvalue      := T#25S ; 
  bcdvalue           := S_ODT (T_NO := mytime ,
                       S  := set ,
                       TV := initialvalue ,
                       R  := reset ,
                       BI := binvalue ,
                       Q  := Q0.7) ; 
//Further processing as output parameter 
  result := bcdvalue ;
//To output for display
  QW4 := binvalue ;
END_FUNCTION_BLOCK
 
Kod:
FUNCTION FC1 : VOID

VAR_INPUT
    frekans_Hz: REAL;           //çalışması istenilen frekansın griş değeri
    ON_value: REAL;             // çalışması istenen ON oranı yüzde cinsinden
END_VAR  

VAR_OUTPUT
    pwm_out: BOOL;              // çıkış olarak darbe genlik modülasytonlu talkt
END_VAR    

VAR_TEMP 
    // dönüşüm için gerekli değişkenler
    ON_s5time:S5TIME;
    OFF_s5time:S5TIME;
    ON_time:TIME;               // pwm çıkışının açık kaldığı sürenin time cinsinden değeri
    OFF_time:time;              // pwm çıkışının kapalı kaldığı sürenin TIME cinsinden değeri 
    ON:REAL;                    // pwm çıkışının açık kaldı değer
    OFF:REAL;                   // pwm çıkışının kapalı kaldığı değer  
         
    // hesaplar için gerekli değişkenler
    T:REAL;                     // periyot
                             
    //timer1(ON) için gereli değişkenler
    ON_time_out:S5TIME ;        //timer1 word cinsinden atanacağı değişken
    ON_time_BI:WORD ;           //timer1 in hex cinsinden aktarılacağı değişken
    ON_time_Q:BOOL;             //timer1 in çıkış değişkeni
    
    //timer2(OFF) için gereli değişkenler
    OFF_time_out:S5TIME;        //timer2 word cinsinden atanacağı değişken
    OFF_time_BI:WORD;           //timer2 nin hex cinsinden atanacağı değişken
    OFF_time_Q:BOOL;            //timer2 nin çıkış değişkeni
END_VAR

BEGIN
// periyodun bulun ma işlemi
T:=1/frekans_Hz;

// pwm çıkışında çıkışın aktif(1) olduğu sürenin hesaplanması (REAL cinsinden)
ON:=((T*ON_value)/100);

//pwm çıkışında çıkışın pasif(0) olduğu sürenin hesaplanması  (REAL cinsinden)
OFF:=((T*(100 - ON_value))/100);

//dönüşüm işlemleri
ON_time:=DINT_TO_TIME(REAL_TO_DINT(ON*1000));
OFF_time:=DINT_TO_TIME(REAL_TO_DINT(OFF*1000));

        //iec zaman fonksiyonu FC40 kullanarak time formatındaki verileri S5Time formatına dönüştürmek
        ON_s5time:=FC40(in:=ON_time );
        OFF_s5time:=FC40(in:=OFF_time);
    

// zamanlayıcıların kurulması
ON_time_out := S_PULSE(T_NO:=T1,  S:= NOT OFF_time_Q,    TV:=ON_s5time,    R:=OFF_time_Q,   BI:=ON_time_BI,    Q:=ON_time_Q);
OFF_time_out:= S_PULSE(T_NO:=T2,  S:=NOT ON_time_Q,      TV:=OFF_s5time,   R:=ON_time_Q,    BI:=OFF_time_BI,   Q:=OFF_time_Q);

// çıkışın oluştrulması
IF ON_time_Q AND NOT OFF_time_Q THEN pwm_out:=true; END_IF;     // mantıksam "1" değerinin oluştrulması
IF OFF_time_Q AND NOT ON_time_Q THEN pwm_out:=false; END_IF;    // mantıksal "0" değerinin oluştrulması

END_FUNCTION

freaks_hz := hz cinsinden bir değer girişi(real)
on_value:= çıkışın aktif olma yüzdesinin girişi(real)
out:= belirlediğiniz değerlere göre çıkış(bool cinsinden)

umarım faydalı olmuşumdur
 
Son düzenleme:
Bu siteyi kullanmak için çerezler gereklidir. Siteyi kullanmaya devam etmek için onları kabul etmelisiniz. Daha fazla bilgi edin…