CodeSYS ST Programlama Soru

murat_elm

Üye
Katılım
23 Ocak 2008
Mesajlar
1
Puanları
1
Yaş
39
Arkadaşlar merhaba,
Bir sorum olacak
CodeSys'te ST dilini kullanarak bir program yazmaya çalışıyorum fakat bir yerde problem yaşıyorum,
Aşağıdaki programda,
BEnim amacım
motorsıcaklık>=setdeger olarak 10 sn kalırsa,motorları 5dk boyunca durdur.5dk sonra tekrar check et;
halen sıcaklık çok yüksek ise(motorsıcaklık>=setdeger) çalışmadan,aynı şekilde devam et.
Eğer düşmüş ise(motorsıcaklık<=setdeger) programda başa dönmesini istiyorum.Yardımcı olabilecek biri var ise çok sevinirim.

IF (motorsıcaklik>=setdeger) THEN
Ton1Bit:=TRUE;
TON1(IN := (Ton1Bit AND (NOT TON4.Q)), PT:= T#10s);
IF (TON1.Q) THEN
SR1(SET1 := TON1.Q, RESET := TON4.Q);
TP1(IN := SR1.Q1 , PT:= T#300s);
TON4(IN := SR1.Q1, PT:= T#300s);
IF (TP1.Q=TRUE) THEN
MotorOff:=TRUE;
MotorOn:=FALSE;
END_IF;
END_IF
END_IF
 
KNX Standardı, küçük bir rezidansın içerisindeki aydınlatma, perde panjur, klima kontrolünden, Dünya’nın en büyük havalimanlarındaki aydınlatma otomasyonu gibi çözümler için tercih edilen bir Dünya standardıdır.
Yazımızda endüstrinin can damarı sayılabilecek PLC’yi inceleyeceğiz.
T_MOTOR(IN :=MOTOR_SICAKLIK>=SET_DEGER,PT:= T#10s); // TON 10 SN AŞARSA

T_MOTOR_SOGUT(IN :=NOT MOTOR,PT:= T#5m); // TON MOTOR DURUNCA SAYMAYA BAŞLAYACAK

IF (T_MOTOR.Q) AND (SOGUT=FALSE) THEN SOGUT:=TRUE;END_IF;

IF (T_MOTOR_SOGUT.Q) THEN SOGUT:=FALSE;END_IF; // 5 DK DOLUNCA SOGUT İPTAL

IF(SOGUT=0) THEN MOTOR:=TRUE;ELSE MOTOR:=FALSE; END_IF; // SOGUTMA AKTIF DEĞİLSE

deneyecegim bir yer yok ama aşagı yukarı böyle olması lazım
birde MotorOff:=TRUE;MotorOn:=FALSE; yazmışsın ayrı ayrı motorlar mı var
 
Kolay gelsin
Kod:
PROGRAM Motor
VAR
	motorsicaklik: INT;
	setdeger: INT;
	Motor: BOOL;
	TON_1: TON;
	TOF_1: TOF;
END_VAR

Kod:
(*10 sn sicakligin yuksek durmasi*)
TON_1(IN:=(motorsicaklik>=setdeger) ,
              PT:= T#10s);


TOF_1(IN:= (TON_1.Q = 1),
           PT:=T#5m );



IF (TOF_1.Q=1) THEN
Motor:=0;
ELSE
Motor:=1;
END_IF;
 
Son düzenleme:
Kolay gelsin. Tam olarak istediğiniz gibi çalışan program parçacığı aşağıdaki gibi yapılabilir.

PROGRAM PLC_PRG
VAR
bMOverTemp : BOOL; (* TRUE if Motor Actual Temperature > Motor Set Temperature*)
dMSetTemp : DINT; (* Motor Set Temperature*)
dMActTemp : DINT; (* Motor Actual Temperature*)

bLockMotor : BOOL; (*Motor Lock Control*)
tonOverTemp : TON; (*Q after 10 seconds of bMOverTemp*)
tonLockMotor : TON; (*Q after 5m of bLockMotor*)

qMotor : BOOL; (*simulation of %QX1.0 to inverter start signal*)
END_VAR

bMOverTemp := dMActTemp > dMSetTemp;
tonOverTemp (IN := bMOverTemp, PT := t#10s);

IF tonOverTemp.Q THEN
bLockMotor := TRUE;
END_IF

tonLockMotor(IN := bLockMotor, PT := t#5m);

IF tonLockMotor.Q AND NOT bMOverTemp THEN
bLockMotor := FALSE;
END_IF

(*OUTPUTS*)
qMotor := NOT bLockMotor;

ya da aşağıdaki şekilde durum diyagramı mantığı ile de yazabilirsiniz. Ben genelde alttaki modeli tercih ediyorum. Adım numaraları yerine enumeration tanımlayarak, adımları isimlendirebilir ve akışı daha anlaşılır hale getirebilirsiniz.

(*alttaki kodda state_machine DINT olarak tanıtılabilir*)
CASE state_machine OF
0:
qMotor := TRUE;
tonOverTemp (IN := dMActTemp > dMSetTemp, PT := t#10s);
IF tonOverTemp.Q THEN
state_machine := 10;
END_IF
10:
qMotor := FALSE;
tonLockMotor(IN:=TRUE, PT:=T#5M);
IF tonLockMotor.Q THEN
state_machine := 20;
END_IF

20:
IF dMActTemp < dMSetTemp THEN
state_machine := 0;
END_IF
ELSE (*STATE ERROR CASE*)
qMotor := FALSE;
state_machine := 20;
END_CASE
 
Son düzenleme:
Case içinde timer kullanmak sakıncalı, timer true kalabiliyor mümkünse case in dışında timer ı çalıştırıp kontaklarını(yani çıkışını) case içerisinde kullanmanızı tavsiye ederim tecrübeyle sabittir.
 
"Adım numaraları yerine enumeration tanımlayarak, adımları isimlendirebilir ve akışı daha anlaşılır hale getirebilirsiniz."

Sayın "gundoganfa" bununla ilgili bir örnek kod yazabilir misiniz?
 
değişkenleri aşağıdaki gibi tanımlayalım. state_machine değişkeninin tipini kullanıcı tarafından tanımlanan bir tip olarak tanıttığımıza dikkat edin.

Kod:
PROGRAM PLC_PRG
VAR
bMOverTemp    :    BOOL;     (* TRUE if Motor Actual Temperature > Motor Set Temperature*)
dMSetTemp    :    DINT;     (* Motor Set Temperature*)
dMActTemp    :    DINT;     (* Motor Actual Temperature*)

bLockMotor    :    BOOL;     (*Motor Lock Control*)
tonOverTemp    :    TON;     (*Q after 10 seconds of bMOverTemp*)
tonLockMotor    :    TON;     (*Q after 5m of bLockMotor*)

qMotor     :    BOOL;     (*simulation of %QX1.0 to inverter start signal*)

state_machine    :    STATES;
END_VAR
data types'ın altında STATES tipini enum olarak tanımlayalım.

TYPE STATES :
(
(*0*) S_CONTINIOUS_CONTROL_OF_MOTOR_TEMPERATURE :=0,
(*1*) S_OVER_TEMPERATURE_LOCK_MOTOR,
(*2*) S_WAIT_NOMINAL_TEMPERATURE
);
END_TYPE
daha sonra üstte yazdığım case'li kod parçasını, aşağıdaki gibi değiştirelim. Dediğiniz gibi TIMER'ları statelerin içinde tanımlayacaksak, FALSE olmasını garanti etmeliyiz.

farklı bir kullanım örneğini en alta ekleyeceğim.

Kod:
CASE state_machine    OF

S_CONTINIOUS_CONTROL_OF_MOTOR_TEMPERATURE:
qMotor    :=    TRUE;
tonOverTemp (IN    :=    dMActTemp > dMSetTemp, PT    :=    t#10s);
IF tonOverTemp.Q THEN
tonOverTemp(IN:=FALSE);
state_machine    :=    S_OVER_TEMPERATURE_LOCK_MOTOR;
END_IF

S_OVER_TEMPERATURE_LOCK_MOTOR:
qMotor    :=    FALSE;
tonLockMotor(IN:=TRUE, PT:=T#5M);
IF tonLockMotor.Q THEN
tonLockMotor(IN:=FALSE);
state_machine    :=    S_WAIT_NOMINAL_TEMPERATURE;
END_IF

S_WAIT_NOMINAL_TEMPERATURE:
IF dMActTemp < dMSetTemp THEN
state_machine    :=    S_CONTINIOUS_CONTROL_OF_MOTOR_TEMPERATURE;
END_IF

ELSE (*STATE ERROR CASE*)
qMotor    :=    FALSE;
state_machine    :=    S_WAIT_NOMINAL_TEMPERATURE;
END_CASE
aşağıdaki örnekte olduğu gibi geçişleri durum makinası(*case ifadesi*)dışında da tanımlayabilirsiniz. Ama ben o şekilde yaptığım zaman durumların kontrolünün daha zor olduğunu düşünüyorum.


Kod:
tonOverTemp (IN    :=    (dMActTemp > dMSetTemp) AND (state_machine = S_CONTINIOUS_CONTROL_OF_MOTOR_TEMPERATURE) , PT    :=    t#10s);
tonLockMotor(IN:=(state_machine = S_OVER_TEMPERATURE_LOCK_MOTOR), PT:=T#5M);

CASE state_machine    OF

S_CONTINIOUS_CONTROL_OF_MOTOR_TEMPERATURE:
qMotor    :=    TRUE;
IF tonOverTemp.Q THEN
state_machine    :=    S_OVER_TEMPERATURE_LOCK_MOTOR;
END_IF

S_OVER_TEMPERATURE_LOCK_MOTOR:
qMotor    :=    FALSE;
IF tonLockMotor.Q THEN
state_machine    :=    S_WAIT_NOMINAL_TEMPERATURE;
END_IF

S_WAIT_NOMINAL_TEMPERATURE:
IF dMActTemp < dMSetTemp THEN
state_machine    :=    S_CONTINIOUS_CONTROL_OF_MOTOR_TEMPERATURE;
END_IF

ELSE (*STATE ERROR CASE*)
qMotor    :=    FALSE;
state_machine    :=    S_WAIT_NOMINAL_TEMPERATURE;
END_CASE
 
Moderatör tarafında düzenlendi:
geçmişte bir projede kullandığım durum tanımlamasını aşağıya ekliyorum. Fikir verebilir.


Kod:
TYPE STATES_P12_OTOMATIK_MOD3 :
(
    SP12_BASLA:=0,
    SP12_CATAL_SENSOR_KONTROLU,
    SP12_SERVO_YATAGINDA_URUN_KONTROLU,
    SP12_YATAK_KONTROLU_JOGGING_SONLANDIRMA,
    SP12_YATAKTA_URUN_YOK_BASLANGIC_POZISYONUNA_GIT,
    SP12_YATAGA_URUN_BESLE,
    SP12_CATAL_SENSOR_GORENE_KADAR_URUNU_TASI,
    SP12_POZISYONLAMA_ONCESI_KLAPE_AC,
    SP12_ISTENEN_POZISYONA_GIT,
    SP12_DAYAMA_ASAGIYA,
    SP12_ISTENEN_POZISYONLAMA_YAVAS_SONLANDIR,
    SP12_OTOMATIK_DONGU_BASLANGIC_DURUMU,
    SP12_BASKI_CENESI_PRESS_YAP,
    SP12_ARABA_BEKLEME_POZ_YAP,
    SP12_DONME_ONCESI_DAYAMA_BEKLE,
    SP12_DONME_MOTORU_CALISTIR,
    SP12_DUZ_HIDROLIK_ILERI,
    SP12_DONME_HIDROLIK_ILERI_GERI,
    SP12_DUZ_HIDROLIK_GERI,
    SP12_GRIPPER_ILERI,
    SP12_NP_CATAL_SENSOR_KONTROL_ET,
    SP12_NP_CATAL_SENSOR_ONU_BOSALT,
    SP12_NP_BEKLEME_POZISYONUNA_GERI_DON,
    SP12_NP_YATAGA_URUN_BESLE,
    SP12_NP_CATAL_SENSOR_GORENE_KADAR_URUNU_TASI,
    SP12_NP_ISTENEN_POZISYONA_GIT,
    SP12_NP_ISTENEN_POZISYON_YAVAS_SONLANDIR,
    SP12_GRIPPER_GERI,
    SP12_CATAL_SENSORDEKI_URUNU_BOSALT,
    SP12_CATAL_SENSORDE_URUN_YOK,
);
END_TYPE
 
Moderatör tarafında düzenlendi:

Forum istatistikleri

Konular
127,966
Mesajlar
913,966
Kullanıcılar
449,612
Son üye
esperran

Yeni konular

Geri
Üst