INTERFACE
USES dDryer, dDW, dEKSGlobal, dEKSHmi;
PROGRAM Trockner;
END_INTERFACE
IMPLEMENTATION
PROGRAM Trockner
VAR
i : INT := 0;
flagDryerOPStarted : ARRAY [1..NUMBER_OF_DRYERS] OF BOOL;
PID_Regler : ARRAY [1..NUMBER_OF_DRYERS] OF _CTRL_pid;
PID_Parameter : ARRAY [1..NUMBER_OF_DRYERS] OF Struct_CTRL_dataPid;
PID_Regler_Act : ARRAY [1..NUMBER_OF_DRYERS] OF BOOL;
FB_S_Trockner_Ein : ARRAY [1..NUMBER_OF_DRYERS] OF R_TRIG;
FB_S_Trockner_Aus : ARRAY [1..NUMBER_OF_DRYERS] OF R_TRIG;
tempTime1 : ARRAY [1..NUMBER_OF_DRYERS] OF UDINT;
tempTime2 : ARRAY [1..NUMBER_OF_DRYERS] OF UDINT;
difTime : ARRAY [1..NUMBER_OF_DRYERS] OF UDINT;
myRetDINT1 : DINT;
myRetDINT2 : DINT;
myRetDINT3 : DINT;
myRetDINT4 : DINT;
var_FanCircSetSpeed : LREAL;
var_FanCircSetSpeed_old : LREAL;
END_VAR
FOR i := 1 TO NUMBER_OF_DRYERS BY 1 DO
FB_S_Trockner_Ein[i](var_S_Trockner_Ein[i]);
FB_S_Trockner_Aus[i](var_S_Trockner_Aus[i]);
//Fan-Spped adaptation
//FAN CIRCULATION 0-50Hz => 0 - 2950/min => 0 - xxxxx
//FAN EXHAUST 0-50Hz => 0 - 2920/min => 0 - xxxxx
//Dryer Start
IF FB_S_Trockner_Ein[i].q
THEN
DryerState[i] := 100;
END_IF;
//Dryer Stop
IF FB_S_Trockner_Aus[i].q THEN
DryerState[i] := 500;
END_IF;
//Check if the Dryer and the Fan are in proper state
IF (*var_sicherheit_trockner = TRUE
AND*) fehler_steuerspannung = FALSE
AND fehler_notaus = FALSE
THEN
;
ELSE
//Dryer / Fan has errors
DryerState[i] := 0;
END_IF;
PID_Regler[i](enable :=PID_Regler_Act[i],dataPid :=PID_Parameter[i]);
//Regler Sollwert
IF DryerSollTemp[i] >=0
AND DryerSollTemp[i] <=120
THEN
PID_Parameter[i].setpointValue := DryerSollTemp[i]*10.0;
END_IF;
//Regler Ist_Wert
PID_Parameter[i].numericActValue := LREAL_TO_REAL(DryerTempSensor[i]*10.0);
//Regler Parameter Anpassung
PID_Parameter[i].propGain := var_Regler_P[i]; //
PID_Parameter[i].integTime := var_Regler_I[i]; //
PID_Parameter[i].derivativeTime := var_Regler_D[i]; //
//Aktuelle Leisung ausrechnen und am Display anzeigen
DryerPIDoutPower[i] := (DryerPIDoutValue[i] / 4096.0) * 100.0;
CASE DryerState[i] OF
//Dryer Stop
0:
//PID deactivate
PID_Regler_Act[i] := FALSE;
PID_Parameter[i].reset := TRUE;
//DryerFanSetSpeed[i] := 0;
DryerPIDoutValue[i] := 0;
IF DryerFanActSpeed[i] <10 THEN
DryerFanOn[i] := FALSE;
DryerFanInOperation[i] := FALSE;
END_IF;
//Dryer&Fan Start
100:
DryerPIDoutValue[i] :=0;
//DryerFanSetSpeed[i] := 0;
DryerState[i] := 101;
101:
flagDryerOPStarted[i] := TRUE;
//Init PID
PID_Parameter[i].reset := TRUE;
PID_Parameter[i].manualMode := FALSE;
PID_Parameter[i].setPController := TRUE; //+ P-Anteil ein
PID_Parameter[i].setIController := TRUE; //+ I-Anteil ein
PID_Parameter[i].holdIValue := FALSE;
PID_Parameter[i].setIValue := FALSE;
PID_Parameter[i].setDController := FALSE; //+ D-Anteil einschalten
//PID_Parameter[i].setpointValue := 60.0; // Sollwert, Bediener
PID_Parameter[i].propGain := var_Regler_P[i]; //
PID_Parameter[i].integTime := var_Regler_I[i]; //
PID_Parameter[i].derivativeTime := var_Regler_D[i]; //
//
PID_Parameter[i].upperLimit := 4096;
PID_Parameter[i].lowerLimit := 0;
DryerFanCTL_PLC[i] := FALSE;
DryerFanStopC[i] := FALSE;
DryerFanStopQ[i] := FALSE;
DryerFanEnableOperation[i] := FALSE;
DryerFanEnableRampGenerator[i] := FALSE;
DryerFanUnfreezaRamp[i] := FALSE;
DryerFanEnableSetpoint[i] := FALSE;
DryerFanOn[i] := FALSE;
//Check Dryer for Errors
IF //FAN_CIRCULATION.error = no
FAN_CIRCULATION.actorMonitoring.driveError = no
AND FAN_CIRCULATION.actorMonitoring.cyclicInterface = active
AND FAN_CIRCULATION.sensorMonitoring.cyclicInterface = active
//AND FAN_CIRCULATION.sensordata[1].state = valid
THEN
DryerState[i] := 110;
END_IF;
110:
//Init & Release FAN
tempTime1[i] := _getinternaltimestamp();
DryerState[i] := 120;
120:
tempTime2[i] := _getinternaltimestamp();
difTime[i] :=_gettimedifferenceofinternaltimestamps(t1 := tempTime1[i] ,t2 := tempTime2[i] );
myRetDINT1 :=
_enableAxis(
axis := FAN_CIRCULATION
,enableMode := ALL
//,servoControlMode := ACTIVE
//,servoCommandToActualMode := INACTIVE
,nextCommand := IMMEDIATELY
,commandId := _getcommandid()
//,forceControlMode := INACTIVE
//,STWBitSet := 0
//,movingMode := SPEED_CONTROLLED
);
DryerState[i] := 130;
130:
tempTime2[i] := _getinternaltimestamp();
difTime[i] :=_gettimedifferenceofinternaltimestamps(t1 := tempTime1[i] ,t2 := tempTime2[i] );
IF difTime[i] >= 1*1*1000000 THEN //1sek. verweilen
tempTime1[i] := _getinternaltimestamp();
DryerState[i] := 140;
END_IF;
140:
tempTime2[i] := _getinternaltimestamp();
difTime[i] :=_gettimedifferenceofinternaltimestamps(t1 := tempTime1[i] ,t2 := tempTime2[i] );
IF difTime[i] >= 1*1*1000000 THEN //1sek. verweilen
tempTime1[i] := _getinternaltimestamp();
DryerState[i] := 150;
END_IF;
150:
tempTime2[i] := _getinternaltimestamp();
difTime[i] :=_gettimedifferenceofinternaltimestamps(t1 := tempTime1[i] ,t2 := tempTime2[i] );
IF difTime[i] >= 1*1*1000000 THEN //1sek. verweilen
tempTime1[i] := _getinternaltimestamp();
DryerState[i] := 160;
END_IF;
160:
tempTime2[i] := _getinternaltimestamp();
difTime[i] :=_gettimedifferenceofinternaltimestamps(t1 := tempTime1[i] ,t2 := tempTime2[i] );
IF difTime[i] >= 1*1*1000000 THEN //1sek. verweilen
tempTime1[i] := _getinternaltimestamp();
DryerState[i] := 170;
END_IF;
170:
tempTime2[i] := _getinternaltimestamp();
difTime[i] :=_gettimedifferenceofinternaltimestamps(t1 := tempTime1[i] ,t2 := tempTime2[i] );
IF difTime[i] >= 1*1*1000000 THEN //1sek. verweilen
tempTime1[i] := _getinternaltimestamp();
DryerState[i] := 180;
END_IF;
180:
tempTime2[i] := _getinternaltimestamp();
difTime[i] :=_gettimedifferenceofinternaltimestamps(t1 := tempTime1[i] ,t2 := tempTime2[i] );
IF difTime[i] >= 1*1*1000000 THEN //1sek. verweilen
tempTime1[i] := _getinternaltimestamp();
DryerState[i] := 190;
END_IF;
190:
tempTime2[i] := _getinternaltimestamp();
difTime[i] :=_gettimedifferenceofinternaltimestamps(t1 := tempTime1[i] ,t2 := tempTime2[i] );
IF difTime[i] >= 1*1*1000000 THEN //1sek. verweilen
tempTime1[i] := _getinternaltimestamp();
DryerState[i] := 200;
END_IF;
200:
DryerState[i] := 210;
210:
DryerState[i] := 220;
220:
DryerState[i] := 230;
230:
DryerState[i] := 240;
240:
//Dryer is in action
PID_Parameter[i].reset := FALSE;
PID_Regler_Act[i] := TRUE;
DryerPIDoutValue[i] := PID_Parameter[i].numericOutValue;
var_FanCircSetSpeed := (var_Soll_Geschw_FAN[1]*2950.0)/6000.0;
IF var_FanCircSetSpeed >= 49
THEN
var_FanCircSetSpeed := 49;
END_IF;
IF var_FanCircSetSpeed < 0
THEN
var_FanCircSetSpeed := 0;
END_IF;
//HIER DER MOVE BEFEHL
IF var_FanCircSetSpeed_old <> var_FanCircSetSpeed
THEN
myRetDINT2 := _move(axis := FAN_CIRCULATION,
velocity := var_FanCircSetSpeed
//velocityType := DIRECT
); //Werteingabe
var_FanCircSetSpeed_old := var_FanCircSetSpeed;
END_IF;
//Dryer Stop
500:
//Dryer Stop
//PID deactivate
PID_Regler_Act[i] := FALSE;
PID_Parameter[i].reset := TRUE;
DryerPIDoutValue[i] := 0;
myRetDINT3 :=
_move(
axis := FAN_CIRCULATION
// ,direction := USER_DEFAULT
// ,velocityType := USER_DEFAULT
,velocity := 0.0
);
(*
IF FAN_CIRCULATION.actorData.actualSpeed <=1
THEN
tempTime1[i] := _getinternaltimestamp();
DryerState[i] := 510;
END_IF;
*)
DryerState[i] := 510;
510:
tempTime2[i] := _getinternaltimestamp();
difTime[i] :=_gettimedifferenceofinternaltimestamps(t1 := tempTime1[i] ,t2 := tempTime2[i] );
myRetDINT4 :=
_disableAxis(
axis := FAN_CIRCULATION
,disableMode := ALL
// ,servoControlMode := INACTIVE
// ,servoCommandToActualMode := ACTIVE
// ,nextCommand := IMMEDIATELY
// ,commandId := (0,0)
// ,forceControlMode := INACTIVE
// ,STWBitSet := 0
);
DryerState[i] := 520;
520:
DryerState[i] := 530;
530:
;
ELSE
;
END_CASE;
END_FOR;
(*
// **********************
// Struct_CTRL_dataPid
// **********************
//myCTRL_dataPid : Struct_CTRL_dataPid;
myCTRL_dataPid.reset := FALSE; // [IN] complete restart
myCTRL_dataPid.manualMode := TRUE; // [IN] manual value on
myCTRL_dataPid.actValueType := FALSE; // [IN] process variable peripherie on
myCTRL_dataPid.setPController := TRUE; // [IN] proportional action on
myCTRL_dataPid.setIController := TRUE; // [IN] integral action on
myCTRL_dataPid.holdIValue := FALSE; // [IN] integral action hold
myCTRL_dataPid.setIValue := FALSE; // [IN] initialization of the integral action
myCTRL_dataPid.setDController := FALSE; // [IN] derivative action on
myCTRL_dataPid.cycleTime := 1000; // [IN] sample time in ms
myCTRL_dataPid.setpointValue := 0.0; // [IN] internal setpoint
myCTRL_dataPid.numericActValue := 0.0; // [IN] process variable in
myCTRL_dataPid.binActValue := 0; // [IN] process variable peripherie
myCTRL_dataPid.manualValue := 0.0; // [IN] manual value
myCTRL_dataPid.propGain := 2.0; // [IN] proportional gain
myCTRL_dataPid.integTime := 20000; // [IN] integration time in ms
myCTRL_dataPid.derivativeTime := 10000; // [IN] derivative time in ms
myCTRL_dataPid.delayTime := 2000; // [IN] time lag of the derivative action in ms
myCTRL_dataPid.deadBand := 0.0; // [IN] dead band width
myCTRL_dataPid.upperLimit := 100.0; // [IN] manipulated value high limit
myCTRL_dataPid.lowerLimit := 0.0; // [IN] manipulated value low limit
myCTRL_dataPid.actValueFactor := 1.0; // [IN] process variable factor
myCTRL_dataPid.actValueOffset := 0.0; // [IN] process variable offset
myCTRL_dataPid.outValueFactor := 1.0; // [IN] manipulated value factor
myCTRL_dataPid.outValueOffset := 0.0; // [IN] manipulated value offset
myCTRL_dataPid.initialIValue := 0.0; // [IN] initialization value of the integral action
myCTRL_dataPid.disturbValue := 0.0; // [IN] disturbance variable
*)
END_PROGRAM
END_IMPLEMENTATION