297 lines
12 KiB
Plaintext
297 lines
12 KiB
Plaintext
FUNCTION_BLOCK "FB_StationUnloadPin"
|
|
{ S7_Optimized_Access := 'TRUE' }
|
|
VERSION : 0.1
|
|
VAR_INPUT
|
|
xInStartUnloading : Bool;
|
|
xInStopUnloading : Bool;
|
|
xInNextHanger : Bool;
|
|
xInBefore : Bool;
|
|
stInPartAfterSwitch : "UDT_Sensor";
|
|
nInBarcode : DInt;
|
|
sInBarcode : String;
|
|
xInReRouteAllowed : Bool := TRUE;
|
|
xInUnloadingCheckSensor : Bool;
|
|
xInMonitorUnloading : Bool;
|
|
xInQuitLocal : Bool;
|
|
xInBypass : Bool;
|
|
END_VAR
|
|
|
|
VAR_OUTPUT
|
|
xOutUnloadingDone : Bool;
|
|
nOutBarcode : DInt;
|
|
sOutBarcode : String;
|
|
xOutSwitch : Bool;
|
|
xOutLineOverloaded : Bool;
|
|
xOutLineOverloadAhead : Bool;
|
|
wOutErrorWord : Word;
|
|
xOutLineOverloadedHigh : Bool;
|
|
xOutLineOverloadedLow : Bool;
|
|
xOutUnloadingFail : Bool;
|
|
xOutUnloadingError : Bool;
|
|
END_VAR
|
|
|
|
VAR_IN_OUT
|
|
stInOutControlUnitCabinet : "UDT_MainState";
|
|
stInOutConveyorStations : "stConveyorStations";
|
|
arInOutCarrier : Array[*] of "stCarrier";
|
|
nNoReadCounter : UDInt;
|
|
stInOutHMI : "UDT_HMI_UnloadingStation";
|
|
END_VAR
|
|
|
|
VAR
|
|
nState : Int := -10;
|
|
TOnLineFullTimer {InstructionName := 'TON_TIME'; LibVersion := '1.0'} : TON_TIME;
|
|
tOnUnloadingCheck {InstructionName := 'TON_TIME'; LibVersion := '1.0'} : TON_TIME;
|
|
END_VAR
|
|
VAR RETAIN
|
|
CountSwitch {InstructionName := 'CTU_UDINT'; LibVersion := '1.0'} : CTU_UDINT;
|
|
nCount : UDInt;
|
|
END_VAR
|
|
VAR
|
|
rTrigSwitch {InstructionName := 'R_TRIG'; LibVersion := '1.0'} : R_TRIG;
|
|
rTrigUnload {InstructionName := 'R_TRIG'; LibVersion := '1.0'} : R_TRIG;
|
|
tUnloadingCheckTime : Time := T#5s;
|
|
xUnloadingCheck : Bool;
|
|
tLineFullTime : Time := T#3s;
|
|
tOnStateTimer {InstructionName := 'TON_TIME'; LibVersion := '1.0'} : TON_TIME;
|
|
xStateTimer : Bool;
|
|
tStateTimer : Time;
|
|
xFlgTrolleySensor : Bool;
|
|
xFlgStartUnloading : Bool;
|
|
fbMonitoringLineOverload : "FB_Monitoring";
|
|
fbMonitoringUnloadError : "FB_Monitoring";
|
|
xEdgeStoreLineOverload : Bool;
|
|
stHangerStatus { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : Struct
|
|
xOnline { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : Bool;
|
|
nTarget { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : Int;
|
|
xDoubleHangerOkay { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : Bool;
|
|
xTargetDoubleHanger { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : Bool;
|
|
xNoRead { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : Bool;
|
|
xPartMissing { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : Bool;
|
|
xTargetSetByMFS { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : Bool;
|
|
xReportedToMFS { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : Bool;
|
|
xReRouteOverflow { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : Bool;
|
|
xReRouteBalancing { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : Bool;
|
|
xReRouteUnavailable { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : Bool;
|
|
END_STRUCT;
|
|
END_VAR
|
|
|
|
VAR_TEMP
|
|
t_status : Bool;
|
|
tmpSuccess : Bool;
|
|
END_VAR
|
|
|
|
|
|
BEGIN
|
|
REGION xOutLineOverloaded Stau
|
|
IF #TOnLineFullTimer.Q THEN
|
|
//OR
|
|
//#tOnUnloadingCheck.Q THEN
|
|
#xFlgTrolleySensor := TRUE;
|
|
#xOutLineOverloaded := 1;
|
|
ELSE
|
|
#xFlgTrolleySensor := FALSE;
|
|
#xOutLineOverloaded := 0;
|
|
END_IF;
|
|
|
|
// Detect change of Line Overload
|
|
#xOutLineOverloadedHigh := #TOnLineFullTimer.Q AND NOT #xEdgeStoreLineOverload;
|
|
|
|
#xOutLineOverloadedLow := NOT #TOnLineFullTimer.Q AND #xEdgeStoreLineOverload;
|
|
|
|
#xEdgeStoreLineOverload := #TOnLineFullTimer.Q;
|
|
|
|
END_REGION
|
|
|
|
IF #xInStartUnloading AND #xFlgTrolleySensor AND #xInReRouteAllowed THEN
|
|
#xOutUnloadingFail := TRUE;
|
|
#nOutBarcode := #nInBarcode;
|
|
#sOutBarcode := #sInBarcode;
|
|
"FC_SHR_TargetSet_ReRoutePin"(nInBarcodeNo := #nInBarcode,
|
|
nInTarget := INT_TO_USINT(#stInOutConveyorStations.stData.nStations),
|
|
xOutSuccess => #tmpSuccess,
|
|
stInOutConveyorStations := #stInOutConveyorStations);
|
|
ELSE
|
|
#xOutUnloadingFail := FALSE;
|
|
END_IF;
|
|
|
|
#rTrigUnload(CLK:=#xInStartUnloading);
|
|
|
|
REGION Schrittkette
|
|
CASE #nState OF
|
|
-10: // Init
|
|
#xOutSwitch := 0;
|
|
#xStateTimer := 0;
|
|
#xOutUnloadingDone := 0;
|
|
#nState := 0;
|
|
|
|
0: // Standby
|
|
#xOutUnloadingDone := 0;
|
|
|
|
// IF #tOnStateTimer.Q (* #xFlgTrolleySensor *)THEN // Wenn Weiche voll //VON MYTHERESA -> STÖRT HIER, TEST
|
|
// #xUnloadingCheck := FALSE; // nicht möglich, da Flankenauswertung, bei dauerbelegtem Sensor sinnfrei
|
|
// #xOutSwitch := 0; // Switch schliessen
|
|
// END_IF;
|
|
|
|
IF #rTrigUnload.Q (* AND NOT #tOnStateTimer.Q *)THEN //VON MYTHERESA -> STÖRT HIER, TEST
|
|
#xOutSwitch := 1;
|
|
#nOutBarcode := #nInBarcode;
|
|
#sOutBarcode := #sInBarcode;
|
|
IF #xInMonitorUnloading THEN
|
|
#xUnloadingCheck := 1;
|
|
END_IF;
|
|
"FC_SHR_ExtractedHangerPin"(xInUnloadingDone := TRUE,
|
|
nInBarcode := #nOutBarcode,
|
|
xInBypass:= #xInBypass,
|
|
stInOutConveyorStations := #stInOutConveyorStations,
|
|
arInOutCarrier:= #arInOutCarrier);
|
|
#xOutUnloadingDone := 1;
|
|
ELSIF #xInStopUnloading THEN
|
|
#xOutSwitch := 0;
|
|
END_IF;
|
|
|
|
1100: // Warten bis fertig mit Switch offen lassen
|
|
#xOutSwitch := 1;
|
|
IF NOT #xInStartUnloading THEN
|
|
#nState := 1110; // Switch offen lassen
|
|
END_IF;
|
|
|
|
1110: // Switch offen lassen
|
|
#xOutSwitch := 1;
|
|
#xOutUnloadingDone := 1;
|
|
#nState := 0;
|
|
1200: // Warten bis fertig mit Switch offen lassen
|
|
#xOutSwitch := 1;
|
|
IF NOT #xInStartUnloading THEN
|
|
"FC_SHR_ExtractedHangerPin"(xInUnloadingDone := NOT #xInStartUnloading,
|
|
nInBarcode := #nOutBarcode,
|
|
xInBypass:=#xInBypass,
|
|
stInOutConveyorStations := #stInOutConveyorStations,
|
|
arInOutCarrier:= #arInOutCarrier);
|
|
#nState := 1210; // Switch offen lassen
|
|
END_IF;
|
|
1210: // Switch schließen
|
|
#xOutSwitch := 0;
|
|
#xOutUnloadingDone := 1;
|
|
#nState := 0;
|
|
1300: //Switch vorher öffnen
|
|
#xOutSwitch := 1;
|
|
#nState := 0;
|
|
END_CASE;
|
|
END_REGION
|
|
REGION Counter
|
|
#rTrigSwitch(CLK := #xOutSwitch);
|
|
#CountSwitch(CU := #rTrigSwitch.Q,
|
|
PV := 1,
|
|
CV => #nCount);
|
|
END_REGION ;
|
|
REGION Timer
|
|
#tOnStateTimer(IN := #xFlgTrolleySensor,//xStateTimer,
|
|
PT := T#800ms);//#tStateTimer);
|
|
|
|
#TOnLineFullTimer(IN := #stInPartAfterSwitch.xDbncdSensor,
|
|
PT := #tLineFullTime);
|
|
|
|
IF #xInUnloadingCheckSensor AND // Sensor nach Weiche
|
|
#xUnloadingCheck AND // Monitoring aktiviert
|
|
NOT #tOnUnloadingCheck.Q // Monitoring nicht bereits ausgeschlagen
|
|
THEN
|
|
#xUnloadingCheck := FALSE;
|
|
END_IF;
|
|
|
|
IF #tOnUnloadingCheck.Q AND // Monitoring ausgeschlagen?
|
|
(#stInOutControlUnitCabinet.xQuitError OR #xInQuitLocal) // dann am Schaltschrank zu quittieren
|
|
THEN
|
|
#xUnloadingCheck := FALSE; // Monitoring Ende
|
|
END_IF;
|
|
|
|
// Timer bis Teil am Sensor vorbei muss
|
|
#tOnUnloadingCheck(IN := #xUnloadingCheck AND #stInOutControlUnitCabinet.xRunning,
|
|
PT := #tUnloadingCheckTime);
|
|
|
|
#xOutUnloadingError := #tOnUnloadingCheck.Q;
|
|
|
|
END_REGION
|
|
|
|
REGION Flanken
|
|
|
|
#xFlgStartUnloading := #xInStartUnloading;
|
|
|
|
END_REGION
|
|
|
|
REGION Monitoring
|
|
|
|
#fbMonitoringLineOverload.stSettings.nErrorType := 1;
|
|
#fbMonitoringLineOverload.stSettings.xErrLedIfMachineIsOff := TRUE;
|
|
#fbMonitoringLineOverload.stSettings.xSelfQuit := TRUE;
|
|
#fbMonitoringLineOverload(sInFctnName := #stInOutHMI.sName,
|
|
wInTextListId_Function := 500,
|
|
wInTextListId_Message := 500,
|
|
sInSuffix := #stInPartAfterSwitch.sName,
|
|
InOutMachineState := #stInOutControlUnitCabinet,
|
|
xInQuitError := #stInOutControlUnitCabinet.xQuitError OR #xInQuitLocal,
|
|
xInSignal := NOT #TOnLineFullTimer.Q,
|
|
sInAlarmMessage := 'Die Linie ist voll');
|
|
|
|
#fbMonitoringUnloadError.stSettings.nErrorType := 1;
|
|
#fbMonitoringUnloadError.stSettings.xErrLedIfMachineIsOff := TRUE;
|
|
#fbMonitoringUnloadError.stSettings.xSelfQuit := TRUE;
|
|
#fbMonitoringUnloadError(sInFctnName := #stInOutHMI.sName,
|
|
wInTextListId_Function := 500,
|
|
wInTextListId_Message := 501,
|
|
sInSuffix := #stInPartAfterSwitch.sName,
|
|
InOutMachineState := #stInOutControlUnitCabinet,
|
|
xInQuitError := #stInOutControlUnitCabinet.xQuitError OR #xInQuitLocal,
|
|
xInSignal := NOT #xOutUnloadingError,
|
|
sInAlarmMessage := 'Laufzeitfehler bei Weiche/Abwurf');
|
|
|
|
END_REGION
|
|
|
|
REGION Visu
|
|
REGION Status
|
|
IF NOT #xOutUnloadingError AND (NOT #wOutErrorWord > 0) THEN
|
|
IF #stInOutHMI.xEnableControl THEN
|
|
#stInOutHMI.bStatus := 3;
|
|
ELSE
|
|
CASE #nState OF
|
|
-10:
|
|
#stInOutHMI.bStatus := 0; // NOT_AVAILABLE
|
|
0, 1100, 1110, 1200, 1210, 1300:
|
|
#stInOutHMI.bStatus := 1; // AVAILABLE
|
|
ELSE //Fallback
|
|
#stInOutHMI.bStatus := 0; // NOT AVAILABLE
|
|
END_CASE;
|
|
END_IF;
|
|
ELSE // Fehler
|
|
#stInOutHMI.bStatus := 2; // ERROR
|
|
END_IF;
|
|
END_REGION
|
|
|
|
REGION Modes
|
|
// Int16 Bit-codiert
|
|
#stInOutHMI.nMode.%X0 := (#nState = -10); // The device is turned off
|
|
#stInOutHMI.nMode.%X1 := (#nState = 0) OR (#nState = 1100) OR (#nState = 1110) OR (#nState = 1200) OR (#nState = 1210) OR (#nState = 1300); // The device is turned on
|
|
#stInOutHMI.nMode.%X2 := #stInOutHMI.xEnableControl; //Hand
|
|
#stInOutHMI.nMode.%X3 := FALSE; //NIU
|
|
#stInOutHMI.nMode.%X10 := #xOutUnloadingError; // Timeout Error
|
|
END_REGION
|
|
|
|
// Idee: Schrittkette setzt im Normalfall den Switch.
|
|
// Wenn EnableControl TRUE ist, dann wird der Ausgang hier einfach überschrieben mit dem HMI-Wert
|
|
REGION Handbetrieb
|
|
IF #stInOutHMI.xEnableControl THEN
|
|
#xOutSwitch := #stInOutHMI.xSetSwitch;
|
|
ELSE
|
|
#stInOutHMI.xSetSwitch := #xOutSwitch;
|
|
END_IF;
|
|
|
|
#stInOutHMI.xInHome := NOT #xOutSwitch;
|
|
#stInOutHMI.xInWork := #xOutSwitch;
|
|
|
|
END_REGION
|
|
|
|
#stInOutHMI.xLineFull := #TOnLineFullTimer.Q;
|
|
END_REGION
|
|
END_FUNCTION_BLOCK
|
|
|