diff --git a/PLC/GVLs/GVL_Product.TcGVL b/PLC/GVLs/GVL_Product.TcGVL new file mode 100644 index 0000000..77b1579 --- /dev/null +++ b/PLC/GVLs/GVL_Product.TcGVL @@ -0,0 +1,9 @@ + + + + + + \ No newline at end of file diff --git a/PLC/PLC.plcproj b/PLC/PLC.plcproj index f0b56a0..55505d5 100644 --- a/PLC/PLC.plcproj +++ b/PLC/PLC.plcproj @@ -18,22 +18,20 @@ {c5c6b994-f2a1-4a71-b657-f282007c0cd2} + + Code + true + Code Code - + Code - - Code - - - Code - - + Code @@ -43,7 +41,7 @@ Code true - + Code @@ -54,18 +52,27 @@ Code + false - + Code + false Code + false - + Code + false - + Code + false + + + Code + true Code @@ -82,16 +89,26 @@ Code + + Code + + + Code + - + + false + - + + false + @@ -118,8 +135,8 @@ - - + + "<ProjectRoot>" {192FAD59-8248-4824-A8DE-9177C94C195A} @@ -195,14 +212,14 @@ - - - System.Boolean - System.Collections.Hashtable - {54dd0eac-a6d8-46f2-8c27-2f43c7e49861} - System.String - - + + + System.Boolean + System.Collections.Hashtable + {54dd0eac-a6d8-46f2-8c27-2f43c7e49861} + System.String + + \ No newline at end of file diff --git a/PLC/PLC.tmc b/PLC/PLC.tmc index 1f4d9cb..6960092 100644 --- a/PLC/PLC.tmc +++ b/PLC/PLC.tmc @@ -1 +1,14 @@ -ST_LibVersion288iMajorUINT160iMinorUINT1616iBuildUINT1632iRevisionUINT1648nFlagsDWORD3264sVersionSTRING(23)19296I_Product64PVOID__getP_CurrNodeIDUINT16property__getP_ResultBOOL8property__setP_CurrNodeIDP_CurrNodeIDUINT16property__setP_ResultP_ResultBOOL8propertyTcPlcInterfaceTypeI_Station64PVOID__getP_AvailableBOOL8property__getP_BusyBOOL8property__getP_CapabilitiesDWORD32property__getP_HasErrorBOOL8property__getP_ResultUINT16propertyM_InsertProductBOOL8fbProductI_Product64M_RemoveProductI_Product64TcPlcInterfaceTypeFB_Scheduler768_aiStationsI_Station01064064_uiStationCountUINT167040M_RegisterfbStationI_Station64M_ClearStationsPouTypeFunctionBlockFB_StationBase320I_Station_xAvailableBOOL8128_xBusyBOOL8136_xDoneBOOL8144_xErrorBOOL8152_dwCapabilitiesDWORD32160_uiResultUINT16192_fbProductI_Product64256__getP_CapabilitiesDWORD32P_CapabilitiesDWORD32property__getP_ResultUINT16P_ResultUINT16property__getP_BusyBOOL8P_BusyBOOL8property__getP_HasErrorBOOL8P_HasErrorBOOL8propertyM_RemoveProductI_Product64M_InsertProductBOOL8fbProductI_Product64__getP_AvailableBOOL8P_AvailableBOOL8propertyPouTypeFunctionBlockFB_Input320FB_StationBasePouTypeFunctionBlockFB_Etcher320FB_StationBasePouTypeFunctionBlockFB_HVTest320FB_StationBasePouTypeFunctionBlockFB_Output320FB_StationBasePouTypeFunctionBlockE_TransitCond16INTALWAYS0RESULT_OK1RESULT_NIO2qualified_onlystrictto_stringgenerate_implicit_init_functionST_Transition32eConditionE_TransitCond160uiNextNodeIDUINT1616ST_RecipeNode416uiNodeIDUINT160dwReqCapDWORD3232uiTransCntUINT1664astTransitionsST_Transition01032080ST_Recipe4224uiRecipeIDUINT160uiStartNodeUINT16160uiNodeCntUINT16320astNodesST_RecipeNode010416064EPlcPersistentStatus8USINT012PlcAppSystemInfo2048ObjIdOTCID320TaskCntUDINT3232OnlineChangeCntUDINT3264FlagsDWORD3296AdsPortUINT16128BootDataLoadedBOOL8144OldBootDataBOOL8152AppTimestampDT32160KeepOutputsOnBPBOOL8192ShutdownInProgressBOOL8200LicensesPendingBOOL8208BSODOccuredBOOL8216LoggedInBOOL8224PersistentStatusEPlcPersistentStatus8232TComSrvPtrITComObjectServer32256TcComInterfaceAppNameSTRING(63)512512ProjectNameSTRING(63)5121024PlcTaskSystemInfo1024ObjIdOTCID320CycleTimeUDINT3232PriorityUINT1664AdsPortUINT1680CycleCountUDINT3296DcTaskTimeLINT64128LastExecTimeUDINT32192FirstCycleBOOL8224CycleTimeExceededBOOL8232InCallAfterOutputUpdateBOOL8240RTViolationBOOL8248TaskNameSTRING(63)512512_Implicit_KindOfTask16INT_implicit_cyclic0_implicit_event1_implicit_external2_implicit_freewheeling3signature_flag256hidegenerate_implicit_init_function_Implicit_Jitter_Distribution48wRangeMaxWORD160wCountJitterNegWORD1616wCountJitterPosWORD1632signature_flag256hide_Implicit_Task_Info896dwVersionDWORD320pszNameSTRING(80)6464nPriorityINT16128KindOf_Implicit_KindOfTask16144bWatchdogBOOL8160bProfilingTaskBOOL8168dwEventFunctionPointerBYTE64192pszExternalEventSTRING(80)64256dwTaskEntryFunctionPointerBYTE64320dwWatchdogSensitivityDWORD32384dwIntervalDWORD32416dwWatchdogTimeDWORD32448dwLastCycleTimeDWORD32480dwAverageCycleTimeDWORD32512dwMaxCycleTimeDWORD32544dwMinCycleTimeDWORD32576diJitterDINT32608diJitterMinDINT32640diJitterMaxDINT32672dwCycleCountDWORD32704wTaskStatusWORD16736wNumOfJitterDistributionsWORD16752pJitterDistribution_Implicit_Jitter_Distribution64768bWithinSPSTimeSlicingBOOL8832byDummyBYTE8840bShouldBlockBOOL8848bActiveBOOL8856dwIECCycleCountDWORD32864signature_flag256hideFB_NIO320FB_StationBasePouTypeFunctionBlockMAIN_fbSchedulerFB_Scheduler768_xInitDoneBOOL8_fbInputFB_Input320_fbEtcherFB_Etcher320_fbHVTestFB_HVTest320_fbOutputFB_Output320_stRecipeSimpleST_Recipe4224_fbNIOFB_NIO320A_InitTwinCAT_PreventOnlineChangeGvlWriteLineIDsBOOL8truePlcProfilerActiveBOOL8falsePlcProfilerConfigChecksumSTRING(64)520linkalwaysGVL_SchedulerMAX_RECIPE_TRANSITIONSUINT1610MAX_RECIPE_NODESUINT1610MAX_STATIONSUINT1610qualified_onlyPLC{08500001-0000-0000-F000-000000000064}0PlcTask#x02010030DeviceLog FilterUDINT#x08508045DeviceLog Filter000000003PlcTask Internal010616832Global_Version.stLibVersion_Tc2_Standard288ST_LibVersion.iMajor3.iMinor4.iBuild5.iRevision0.nFlags1.sVersion3.4.5.0const_non_replacedTcVarGlobal3072000Global_Version.stLibVersion_Tc2_System288ST_LibVersion.iMajor3.iMinor10.iBuild1.iRevision0.nFlags1.sVersion3.10.1.0const_non_replacedTcVarGlobal3072288Global_Version.stLibVersion_Tc3_Module288ST_LibVersion.iMajor3.iMinor4.iBuild5.iRevision0.nFlags1.sVersion3.4.5.0const_non_replacedTcVarGlobal3072576MAIN._fbScheduler768FB_Scheduler3101568MAIN._xInitDone8BOOL3102336TwinCAT_PreventOnlineChangeGvl.WriteLineIDs8BOOLtrueTcVarGlobal3102344TwinCAT_PreventOnlineChangeGvl.PlcProfilerActive8BOOLfalseTcVarGlobal3102352GVL_Scheduler.MAX_RECIPE_TRANSITIONS16UINT10TcVarGlobal3102384MAIN._fbInput320FB_Input3102400MAIN._fbEtcher320FB_Etcher3102720MAIN._fbHVTest320FB_HVTest3103040MAIN._fbOutput320FB_Output3103360MAIN._stRecipeSimple4224ST_Recipe3103680TwinCAT_PreventOnlineChangeGvl.PlcProfilerConfigChecksum520STRING(64)TcVarGlobal3108000GVL_Scheduler.MAX_RECIPE_NODES16UINT10TcVarGlobal3108528GVL_Scheduler.MAX_STATIONS16UINT10TcVarGlobal3108544TwinCAT_SystemInfoVarList._AppInfo2048PlcAppSystemInfono_initTcVarGlobal3108864TwinCAT_SystemInfoVarList._TaskInfo1024PlcTaskSystemInfo11no_initTcVarGlobal3110912TwinCAT_SystemInfoVarList._TaskPouOid_PlcTask32OTCIDno_initTcVarGlobal3111936TwinCAT_SystemInfoVarList._TaskOid_PlcTask32OTCIDno_initTcVarGlobal3111968TwinCAT_SystemInfoVarList.__PlcTask896_Implicit_Task_Info.dwVersion2TcContextNamePlcTaskTcVarGlobal3112000MAIN._fbNIO320FB_NIO3152832ApplicationNamePort_851ChangeDate2026-02-16T17:39:15DataID{14db9a6a-0000-0000-0000-000000000000}GeneratedCodeSize61440GlobalDataSize16384UTF8EncodedStringsfalse \ No newline at end of file +ST_LibVersion288iMajorUINT160iMinorUINT1616iBuildUINT1632iRevisionUINT1648nFlagsDWORD3264sVersionSTRING(23)19296I_Station64PVOID__getP_AvailableBOOL8property__getP_BusyBOOL8property__getP_CapabilitiesDWORD32property__getP_CurrFlowRecIdxINT16property__getP_HasErrorBOOL8property__getP_ProdAvailBOOL8property__getP_StationIDUINT16property__setP_StationIDP_StationIDUINT16propertyM_HasCapabiltyBOOL8dwReqCapDWORD32M_InsertProductBOOL8iFlowRecIdxINT16M_ReleaseBOOL8uiHandleUINT16M_RemoveProductINT16M_ReserveUINT16TcPlcInterfaceTypeI_Transport64PVOID__getP_AvailableBOOL8property__getP_HasErrorBOOL8propertyTcPlcInterfaceTypeST_FlowRecipeNode160uiPriorityUINT160100dwReqCapDWORD32320uiMaxRetriesUINT16640uiCurrRetriesUINT16800xSuccessBOOL896falseiNextNodeSuccessINT16112-1iNextNodeRetryINT16128-1iNextNodeFailINT16144-1ST_FlowRecipe1664iProdIdxINT160-1iCurrNodeINT16160iNextNodeINT16320uiNodeCntINT16480astNodesST_FlowRecipeNode010160064I_FlowRecHandler64PVOIDM_AddFlowRecINT16stFlowRecipeST_FlowRecipe1664M_GetFlowRecST_FlowRecipe64iIdxINT16M_GetNextProcReqBOOL8iIdxINT16dwProcReqDWORD32ItemTypeOutputM_RemFlowRecBOOL8iIdxINT16M_ReportResultBOOL8iIdxINT16xResultBOOL8TcPlcInterfaceTypeFB_FlowRecHandler168256I_FlowRecHandler_astFlowRecPoolST_FlowRecipe0100166400128_iFlowRecCntINT161665280_stDefaultRecipeST_FlowRecipe1664166560POOL_SIZEINT16168224100M_GetNextProcReqBOOL8iIdxINT16dwProcReqDWORD32ItemTypeOutput_iNextNodeIdxINT16M_AdvJobBOOL8iIdxINT16M_GetNextPrioUINT16iIdxINT16_iNextNodeIdxINT16M_RemFlowRecBOOL8iIdxINT16M_AddFlowRecINT16stFlowRecipeST_FlowRecipe1664iINT16M_CheckPoolBoundsBOOL8iIdxINT16M_CheckNextNodeIdxBOOL8iCurrNodeIdxINT16iNextNodeIdxINT16M_GetFlowRecST_FlowRecipe64iIdxINT16M_ReportResultBOOL8iIdxINT16xResultBOOL8_iCurrNodeIdxINT16_iNextNodeIdxINT16PouTypeFunctionBlockST_TransJob80uiFromStationUINT160uiToStationUINT1616uiFromStationHandleUINT1632uiToStationHandleUINT1648uiPrioUINT1664FB_JobQueue896xEnableAgingBOOL864falseItemTypeInput_astJobQueueST_TransJob01080080_uiJobCountUINT168800M_AddJobBOOL8stJobST_TransJob80M_GetHighestBOOL8stJobST_TransJob80ItemTypeOutput_uiIndexUINT16_rDynPrioREAL32_uiCntUINT16M_CalcAgingPrioiUINT16PouTypeFunctionBlockFB_Scheduler1152fbFlowRecHandlerFB_FlowRecHandler6464ItemTypeInOutfbJobQueueFB_JobQueue64128ItemTypeInOut_aiStationsI_Station110640192_uiStationCountUINT168320_fbTransportI_Transport64896_uiCntUINT16960_uiNextAvailStationUINT16976_iFlowRecIdxINT16992_dwNextProcReqDWORD321024_stTmpJobST_TransJob801056M_RegisterfbStationI_Station64M_FindNextAvailStationUINT16dwProcReqDWORD32_uiCntUINT16M_GetStationI_Station64iStationIdxINT16M_RegisterTransportfbTransportI_Transport64M_ClearStationsPouTypeFunctionBlockFB_BaseStation384I_StationfbFlowRecHandlerFB_FlowRecHandler64128ItemTypeInOut_iFlowRecIdxINT16192-1_xProdAvailBOOL8208_xEmptyBOOL8216_xBusyBOOL8224_xDoneBOOL8232_xErrorBOOL8240_uiStationIDUINT162560_dwCapabilitiesDWORD32288_xReservedBOOL8320_uiCurrHandleUINT16336_uiHandleCounterUINT163521M_RemoveProductINT16__getP_CapabilitiesDWORD32P_CapabilitiesDWORD32propertyM_HasCapabiltyBOOL8dwReqCapDWORD32M_InsertProductBOOL8iFlowRecIdxINT16M_ReleaseBOOL8uiHandleUINT16__getP_BusyBOOL8P_BusyBOOL8property__getP_CurrFlowRecIdxINT16P_CurrFlowRecIdxINT16property__getP_StationIDUINT16P_StationIDUINT16propertyM_ReserveUINT16__getP_HasProductBOOL8P_HasProductBOOL8property__getP_HasErrorBOOL8P_HasErrorBOOL8property__getP_ProdAvailBOOL8P_ProdAvailBOOL8property__getP_AvailableBOOL8P_AvailableBOOL8property__setP_StationIDP_StationIDUINT16propertyPouTypeFunctionBlockTON256INBOOL864ItemTypeInputPTTIME3296ItemTypeInputQBOOL8128ItemTypeOutputETTIME32160ItemTypeOutputMBOOL8192StartTimeTIME32224PouTypeFunctionBlockFB_Input2368FB_BaseStation_tonNewProductReadyTON256384_stFlowRecipeST_FlowRecipe1664640_xRecipeSetBOOL82304_xStartBOOL82312M_SetRecipestRecipeST_FlowRecipe1664PouTypeFunctionBlockFB_Etcher704FB_BaseStation_iStateINT16384_tonProcessDurationTON256448PouTypeFunctionBlockFB_HVTest704FB_BaseStation_iStateINT16384_tonProcessDurationTON256448PouTypeFunctionBlockFB_Output704FB_BaseStation_iStateINT16384_tonAutoRemoveTON256448PouTypeFunctionBlockFB_NIO704FB_BaseStation_iStateINT16384_tonAutoRemoveTON256448PouTypeFunctionBlockFB_BaseTransport320I_TransportfbJobQueueFB_JobQueue64128ItemTypeInOut_stTransJonST_TransJob80192_xAvailableBOOL8272true_xErrorBOOL8280__getP_AvailableBOOL8P_AvailableBOOL8property__getP_HasErrorBOOL8P_HasErrorBOOL8propertyPouTypeFunctionBlockFB_Robot896FB_BaseTransportfbSchedulerFB_Scheduler64320ItemTypeInOut_tonTransportDoneTON256384_timTransportTimeTIME32640T#5S_itfSourceStationI_Station64704_itfTargetStationI_Station64768_iFlowRecIdxINT16832_iStateINT16848PouTypeFunctionBlockEPlcPersistentStatus8USINT012PlcAppSystemInfo2048ObjIdOTCID320TaskCntUDINT3232OnlineChangeCntUDINT3264FlagsDWORD3296AdsPortUINT16128BootDataLoadedBOOL8144OldBootDataBOOL8152AppTimestampDT32160KeepOutputsOnBPBOOL8192ShutdownInProgressBOOL8200LicensesPendingBOOL8208BSODOccuredBOOL8216LoggedInBOOL8224PersistentStatusEPlcPersistentStatus8232TComSrvPtrITComObjectServer32256TcComInterfaceAppNameSTRING(63)512512ProjectNameSTRING(63)5121024PlcTaskSystemInfo1024ObjIdOTCID320CycleTimeUDINT3232PriorityUINT1664AdsPortUINT1680CycleCountUDINT3296DcTaskTimeLINT64128LastExecTimeUDINT32192FirstCycleBOOL8224CycleTimeExceededBOOL8232InCallAfterOutputUpdateBOOL8240RTViolationBOOL8248TaskNameSTRING(63)512512_Implicit_KindOfTask16INT_implicit_cyclic0_implicit_event1_implicit_external2_implicit_freewheeling3signature_flag256hidegenerate_implicit_init_function_Implicit_Jitter_Distribution48wRangeMaxWORD160wCountJitterNegWORD1616wCountJitterPosWORD1632signature_flag256hide_Implicit_Task_Info896dwVersionDWORD320pszNameSTRING(80)6464nPriorityINT16128KindOf_Implicit_KindOfTask16144bWatchdogBOOL8160bProfilingTaskBOOL8168dwEventFunctionPointerBYTE64192pszExternalEventSTRING(80)64256dwTaskEntryFunctionPointerBYTE64320dwWatchdogSensitivityDWORD32384dwIntervalDWORD32416dwWatchdogTimeDWORD32448dwLastCycleTimeDWORD32480dwAverageCycleTimeDWORD32512dwMaxCycleTimeDWORD32544dwMinCycleTimeDWORD32576diJitterDINT32608diJitterMinDINT32640diJitterMaxDINT32672dwCycleCountDWORD32704wTaskStatusWORD16736wNumOfJitterDistributionsWORD16752pJitterDistribution_Implicit_Jitter_Distribution64768bWithinSPSTimeSlicingBOOL8832byDummyBYTE8840bShouldBlockBOOL8848bActiveBOOL8856dwIECCycleCountDWORD32864signature_flag256hideMAIN_fbSchedulerFB_Scheduler1152_xInitDoneBOOL8_xStartBOOL8_fbInputFB_Input2368_fbEtcherFB_Etcher704_fbHVTestFB_HVTest704_fbOutputFB_Output704_fbNIOFB_NIO704_fbRobotFB_Robot896_fbJobQueueFB_JobQueue896_stRecipeSimpleST_FlowRecipe1664_fbFlowRecHandlerFB_FlowRecHandler168256A_InitTwinCAT_PreventOnlineChangeGvlWriteLineIDsBOOL8truePlcProfilerActiveBOOL8falsePlcProfilerConfigChecksumSTRING(64)520linkalwaysGVL_SchedulerMAX_RECIPE_TRANSITIONSUINT1610MAX_RECIPE_NODESUINT1610MAX_STATIONSUINT1610AGING_STEPUINT161MAX_PRIORITYUINT1665535MAX_JOBS_IN_QUEUEUINT1610qualified_onlyGVL_ProductaxProductInStationBOOL0540qualified_onlyPLC{08500001-0000-0000-F000-000000000064}0PlcTask#x02010030DeviceLog FilterUDINT#x08508045DeviceLog Filter000000003PlcTask Internal010616832Global_Version.stLibVersion_Tc2_Standard288ST_LibVersion.iMajor3.iMinor4.iBuild5.iRevision0.nFlags1.sVersion3.4.5.0const_non_replacedTcVarGlobal3072000Global_Version.stLibVersion_Tc2_System288ST_LibVersion.iMajor3.iMinor10.iBuild1.iRevision0.nFlags1.sVersion3.10.1.0const_non_replacedTcVarGlobal3072288Global_Version.stLibVersion_Tc3_Module288ST_LibVersion.iMajor3.iMinor4.iBuild5.iRevision0.nFlags1.sVersion3.4.5.0const_non_replacedTcVarGlobal3072576GVL_Product.axProductInStation40BOOL05TcVarGlobal3098368MAIN._fbScheduler1152FB_Scheduler3107648MAIN._xInitDone8BOOL3108800MAIN._xStart8BOOL3108808TwinCAT_PreventOnlineChangeGvl.WriteLineIDs8BOOLtrueTcVarGlobal3108816TwinCAT_PreventOnlineChangeGvl.PlcProfilerActive8BOOLfalseTcVarGlobal3108824GVL_Scheduler.MAX_RECIPE_TRANSITIONS16UINT10TcVarGlobal3108848MAIN._fbInput2368FB_Input3108864MAIN._fbEtcher704FB_Etcher3111232MAIN._fbHVTest704FB_HVTest3111936MAIN._fbOutput704FB_Output3112640MAIN._fbNIO704FB_NIO3113344MAIN._fbRobot896FB_Robot3114048MAIN._fbJobQueue896FB_JobQueue3114944MAIN._stRecipeSimple1664ST_FlowRecipe3115840MAIN._fbFlowRecHandler168256FB_FlowRecHandler3117504TwinCAT_PreventOnlineChangeGvl.PlcProfilerConfigChecksum520STRING(64)TcVarGlobal3285760GVL_Scheduler.MAX_RECIPE_NODES16UINT10TcVarGlobal3286288GVL_Scheduler.MAX_STATIONS16UINT10TcVarGlobal3286304GVL_Scheduler.AGING_STEP16UINT1TcVarGlobal3286320GVL_Scheduler.MAX_PRIORITY16UINT65535TcVarGlobal3286336GVL_Scheduler.MAX_JOBS_IN_QUEUE16UINT10TcVarGlobal3286352TwinCAT_SystemInfoVarList._TaskPouOid_PlcTask32OTCIDno_initTcVarGlobal3286688TwinCAT_SystemInfoVarList._AppInfo2048PlcAppSystemInfono_initTcVarGlobal3286720TwinCAT_SystemInfoVarList._TaskInfo1024PlcTaskSystemInfo11no_initTcVarGlobal3288768TwinCAT_SystemInfoVarList._TaskOid_PlcTask32OTCIDno_initTcVarGlobal3289792TwinCAT_SystemInfoVarList.__PlcTask896_Implicit_Task_Info.dwVersion2TcContextNamePlcTaskTcVarGlobal3289856ApplicationNamePort_851ChangeDate2026-02-19T15:37:52DataID{bc6b67c6-0000-0000-0000-000000000000}GeneratedCodeSize61440GlobalDataSize40960UTF8EncodedStringsfalse \ No newline at end of file diff --git a/PLC/POUs/MAIN.TcPOU b/PLC/POUs/MAIN.TcPOU index 1089768..a056b1f 100644 --- a/PLC/POUs/MAIN.TcPOU +++ b/PLC/POUs/MAIN.TcPOU @@ -14,8 +14,18 @@ VAR _fbOutput : FB_Output; _fbNIO : FB_NIO; + // Transport + _fbRobot : FB_Robot; + + // Job queue + _fbJobQueue : FB_JobQueue; + // Example recipe - _stRecipeSimple : ST_Recipe; + _stRecipeSimple : ST_FlowRecipe; + + _fbFlowRecHandler : FB_FlowRecHandler; + + _xStart : BOOL; END_VAR ]]> @@ -25,18 +35,31 @@ END_VAR END_IF // Call all stations -_fbInput(); -_fbEtcher(); -_fbHVTest(); -_fbOutput(); -_fbNIO(); +_fbInput(fbFlowRecHandler := _fbFlowRecHandler); +GVL_Product.axProductInStation[0] := _fbInput.P_HasProduct; + +_fbEtcher(fbFlowRecHandler := _fbFlowRecHandler); +GVL_Product.axProductInStation[1] := _fbEtcher.P_HasProduct; + +_fbHVTest(fbFlowRecHandler := _fbFlowRecHandler); +GVL_Product.axProductInStation[2] := _fbHVTest.P_HasProduct; + +_fbOutput(fbFlowRecHandler := _fbFlowRecHandler); +GVL_Product.axProductInStation[3] := _fbOutput.P_HasProduct; + +_fbNIO(fbFlowRecHandler := _fbFlowRecHandler); +GVL_Product.axProductInStation[4] := _fbNIO.P_HasProduct; + // Call scheduler -_fbScheduler();]]> +_fbScheduler(fbFlowRecHandler := _fbFlowRecHandler, fbJobQueue := _fbJobQueue); + +// Call robot transport +_fbRobot(fbJobQueue := _fbJobQueue, fbScheduler := _fbScheduler);]]> - +// Etching +_stRecipeSimple.astNodes[0].dwReqCap := 16#0001; +_stRecipeSimple.astNodes[0].iNextNodeSuccess := 1; +_stRecipeSimple.astNodes[0].iNextNodeFail := 3; + +// HV Testing +_stRecipeSimple.astNodes[1].dwReqCap := 16#0002; +_stRecipeSimple.astNodes[1].iNextNodeSuccess := 2; +_stRecipeSimple.astNodes[1].uiMaxRetries := 1; +_stRecipeSimple.astNodes[1].iNextNodeRetry := 0; +_stRecipeSimple.astNodes[1].iNextNodeFail := 3; + +// Output +_stRecipeSimple.astNodes[2].dwReqCap := 16#0004; + +// NIO +_stRecipeSimple.astNodes[3].dwReqCap := 16#0008; + +// Set flow recipe in input station +_fbInput.M_SetRecipe(_stRecipeSimple);]]> diff --git a/PLC/POUs/ST_RobotMoveData.TcDUT b/PLC/POUs/ST_RobotMoveData.TcDUT new file mode 100644 index 0000000..28dda0b --- /dev/null +++ b/PLC/POUs/ST_RobotMoveData.TcDUT @@ -0,0 +1,15 @@ + + + + + + \ No newline at end of file diff --git a/PLC/POUs/Scheduler/DUTs/E_TransitCond.TcDUT b/PLC/POUs/Scheduler/DUTs/E_TransitCond.TcDUT deleted file mode 100644 index 2decbda..0000000 --- a/PLC/POUs/Scheduler/DUTs/E_TransitCond.TcDUT +++ /dev/null @@ -1,16 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/PLC/POUs/Scheduler/DUTs/ST_FlowRecipe.TcDUT b/PLC/POUs/Scheduler/DUTs/ST_FlowRecipe.TcDUT new file mode 100644 index 0000000..7bd6660 --- /dev/null +++ b/PLC/POUs/Scheduler/DUTs/ST_FlowRecipe.TcDUT @@ -0,0 +1,31 @@ + + + + + + \ No newline at end of file diff --git a/PLC/POUs/Scheduler/DUTs/ST_FlowRecipeNode.TcDUT b/PLC/POUs/Scheduler/DUTs/ST_FlowRecipeNode.TcDUT new file mode 100644 index 0000000..fce120a --- /dev/null +++ b/PLC/POUs/Scheduler/DUTs/ST_FlowRecipeNode.TcDUT @@ -0,0 +1,34 @@ + + + + + + \ No newline at end of file diff --git a/PLC/POUs/Scheduler/DUTs/ST_Recipe.TcDUT b/PLC/POUs/Scheduler/DUTs/ST_Recipe.TcDUT deleted file mode 100644 index 9a34c6e..0000000 --- a/PLC/POUs/Scheduler/DUTs/ST_Recipe.TcDUT +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/PLC/POUs/Scheduler/DUTs/ST_RecipeNode.TcDUT b/PLC/POUs/Scheduler/DUTs/ST_RecipeNode.TcDUT deleted file mode 100644 index 44b241f..0000000 --- a/PLC/POUs/Scheduler/DUTs/ST_RecipeNode.TcDUT +++ /dev/null @@ -1,19 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/PLC/POUs/Scheduler/DUTs/ST_TransJob.TcDUT b/PLC/POUs/Scheduler/DUTs/ST_TransJob.TcDUT index 7db2753..12b111d 100644 --- a/PLC/POUs/Scheduler/DUTs/ST_TransJob.TcDUT +++ b/PLC/POUs/Scheduler/DUTs/ST_TransJob.TcDUT @@ -4,21 +4,19 @@ diff --git a/PLC/POUs/Scheduler/DUTs/ST_Transition.TcDUT b/PLC/POUs/Scheduler/DUTs/ST_Transition.TcDUT deleted file mode 100644 index 4df5db4..0000000 --- a/PLC/POUs/Scheduler/DUTs/ST_Transition.TcDUT +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/PLC/POUs/Scheduler/GVLs/GVL_Scheduler.TcGVL b/PLC/POUs/Scheduler/GVLs/GVL_Scheduler.TcGVL index 5db23dd..024aca0 100644 --- a/PLC/POUs/Scheduler/GVLs/GVL_Scheduler.TcGVL +++ b/PLC/POUs/Scheduler/GVLs/GVL_Scheduler.TcGVL @@ -10,8 +10,10 @@ VAR_GLOBAL CONSTANT // Scheduler constants MAX_STATIONS : UINT := 10; - // Factor to calc dynmaic priority from age of job in prio/s - AGE_FACTOR : REAL := 1.0; + // Factor to calc dynamic priority from age of job in prio/s + AGING_STEP : UINT := 1; + + MAX_PRIORITY : UINT := 65535; // Job queue constants MAX_JOBS_IN_QUEUE : UINT := 10; diff --git a/PLC/POUs/Scheduler/ITFs/I_FlowRecHandler.TcIO b/PLC/POUs/Scheduler/ITFs/I_FlowRecHandler.TcIO new file mode 100644 index 0000000..cd81103 --- /dev/null +++ b/PLC/POUs/Scheduler/ITFs/I_FlowRecHandler.TcIO @@ -0,0 +1,47 @@ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/PLC/POUs/Scheduler/ITFs/I_Product.TcIO b/PLC/POUs/Scheduler/ITFs/I_Product.TcIO deleted file mode 100644 index 277987e..0000000 --- a/PLC/POUs/Scheduler/ITFs/I_Product.TcIO +++ /dev/null @@ -1,30 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/PLC/POUs/Scheduler/ITFs/I_Station.TcIO b/PLC/POUs/Scheduler/ITFs/I_Station.TcIO index a472466..388c5f5 100644 --- a/PLC/POUs/Scheduler/ITFs/I_Station.TcIO +++ b/PLC/POUs/Scheduler/ITFs/I_Station.TcIO @@ -10,26 +10,26 @@ VAR_INPUT END_VAR ]]> - + - - @@ -50,6 +50,12 @@ END_VAR + + + + + + @@ -62,23 +68,16 @@ END_VAR - - - - - - - - - - - - + + + \ No newline at end of file diff --git a/PLC/POUs/Scheduler/POUs/FB_StationBase.TcPOU b/PLC/POUs/Scheduler/POUs/FB_BaseStation.TcPOU similarity index 61% rename from PLC/POUs/Scheduler/POUs/FB_StationBase.TcPOU rename to PLC/POUs/Scheduler/POUs/FB_BaseStation.TcPOU index 0df4cac..f8e4ad0 100644 --- a/PLC/POUs/Scheduler/POUs/FB_StationBase.TcPOU +++ b/PLC/POUs/Scheduler/POUs/FB_BaseStation.TcPOU @@ -1,31 +1,45 @@  - - + @@ -38,33 +52,47 @@ VAR_INPUT END_VAR ]]> - + - 0 AND _fbProduct = 0 THEN - _fbProduct := fbProduct; - M_InsertProduct := TRUE; -ELSE + -1) OR (iFlowRecIdx = -1) THEN M_InsertProduct := FALSE; -END_IF]]> +END_IF + +// Save product index +_iFlowRecIdx := iFlowRecIdx; + +// Advance one step in the node control flow +fbFlowRecHandler.M_AdvJob(iIdx := iFlowRecIdx); + + +// Report success +M_InsertProduct := TRUE;]]> - - - + - - @@ -112,7 +147,10 @@ END_IF]]> END_VAR ]]> - + @@ -140,6 +178,18 @@ END_VAR + + + + + + + + + @@ -152,6 +202,17 @@ END_VAR + + + + + + -1);]]> + + + @@ -164,30 +225,6 @@ END_VAR - - - - - - - - - - - - - - - - - - @@ -199,6 +236,14 @@ END_VAR + + + + + + \ No newline at end of file diff --git a/PLC/POUs/Scheduler/POUs/FB_TransportBase.TcPOU b/PLC/POUs/Scheduler/POUs/FB_BaseTransport.TcPOU similarity index 82% rename from PLC/POUs/Scheduler/POUs/FB_TransportBase.TcPOU rename to PLC/POUs/Scheduler/POUs/FB_BaseTransport.TcPOU index c95ec50..2563555 100644 --- a/PLC/POUs/Scheduler/POUs/FB_TransportBase.TcPOU +++ b/PLC/POUs/Scheduler/POUs/FB_BaseTransport.TcPOU @@ -1,13 +1,18 @@  - - + diff --git a/PLC/POUs/Scheduler/POUs/FB_FlowRecHandler.TcPOU b/PLC/POUs/Scheduler/POUs/FB_FlowRecHandler.TcPOU new file mode 100644 index 0000000..f869957 --- /dev/null +++ b/PLC/POUs/Scheduler/POUs/FB_FlowRecHandler.TcPOU @@ -0,0 +1,263 @@ + + + + + + + + + + + = POOL_SIZE THEN + M_AddFlowRec := -1; + RETURN; +END_IF + +// Find a free slot in the pool +FOR i := 0 TO (POOL_SIZE - 1) DO + // If slot is free, set the flow recipe data + IF (_astFlowRecPool[i].iProdIdx = -1) THEN + _astFlowRecPool[i] := stFlowRecipe; + _astFlowRecPool[i].iProdIdx := i; + // Increment number of recipes in the pool + _iFlowRecCnt := _iFlowRecCnt + 1; + // Return index of the added flow recipe + M_AddFlowRec := i; + RETURN; + END_IF +END_FOR]]> + + + + + + + + + + + + (_astFlowRecPool[iCurrNodeIdx].uiNodeCnt - 1)) THEN + M_CheckNextNodeIdx := FALSE; +ELSE + M_CheckNextNodeIdx := TRUE; +END_IF]]> + + + + + + (POOL_SIZE - 1)) THEN + M_CheckPoolBounds := FALSE; +ELSE + M_CheckPoolBounds := TRUE; +END_IF]]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + (_astFlowRecPool[iIdx].uiNodeCnt - 1)) THEN + // If there is no next node set to -1 + // to indicate, that this was the last node in the + // flow recipe + _astFlowRecPool[iIdx].iNextNode := -1; +ELSE + _astFlowRecPool[iIdx].iNextNode := _iNextNodeIdx; +END_IF + +// Return success +M_ReportResult := TRUE;]]> + + + + \ No newline at end of file diff --git a/PLC/POUs/Scheduler/POUs/FB_JobQueue.TcPOU b/PLC/POUs/Scheduler/POUs/FB_JobQueue.TcPOU index 0f1c725..879dceb 100644 --- a/PLC/POUs/Scheduler/POUs/FB_JobQueue.TcPOU +++ b/PLC/POUs/Scheduler/POUs/FB_JobQueue.TcPOU @@ -3,6 +3,7 @@ - + - @@ -50,22 +50,36 @@ IF _uiJobCount >= GVL_Scheduler.MAX_JOBS_IN_QUEUE THEN RETURN; END_IF -_uiJobCount := _uiJobCount + 1; _astJobQueue[_uiJobCount] := stJob; -_astJobQueue[_uiJobCount].xValid := TRUE; -_astJobQueue[_uiJobCount].uliTimeCreated := F_GetSystemTime(); +_uiJobCount := _uiJobCount + 1; M_AddJob := TRUE;]]> + + + + (GVL_Scheduler.MAX_PRIORITY - GVL_Scheduler.AGING_STEP) THEN + _astJobQueue[i].uiPrio := GVL_Scheduler.MAX_PRIORITY; + ELSE + _astJobQueue[i].uiPrio := _astJobQueue[i].uiPrio + GVL_Scheduler.AGING_STEP; + END_IF + END_IF +END_FOR]]> + + 32767.0 THEN - _rDynPrio := 32767.0; - END_IF - _astJobQueue[_uiCnt].iDynPrio := REAL_TO_INT(_rDynPrio); - +FOR _uiCnt := 0 TO (_uiJobCount-1) DO // Check for highest priority - IF (_astJobQueue[_uiCnt].iStatPrio + _astJobQueue[_uiCnt].iDynPrio) > _iMaxPrio THEN - _iMaxPrio := + IF _astJobQueue[_uiCnt].uiPrio > _astJobQueue[_uiIndex].uiPrio THEN + _uiIndex := _uiCnt; END_IF - END_IF - -END_FOR]]> +END_FOR + +// Output job +stJob := _astJobQueue[_uiIndex]; + +// Close gap with last element +_astJobQueue[_uiIndex] := _astJobQueue[_uiJobCount - 1]; + +// Adjust job number in queue +_uiJobCount := _uiJobCount - 1; + +// Repost success +M_GetHighest := TRUE;]]> diff --git a/PLC/POUs/Scheduler/POUs/FB_Product.TcPOU b/PLC/POUs/Scheduler/POUs/FB_Product.TcPOU deleted file mode 100644 index 8020b4f..0000000 --- a/PLC/POUs/Scheduler/POUs/FB_Product.TcPOU +++ /dev/null @@ -1,87 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/PLC/POUs/Scheduler/POUs/FB_Scheduler.TcPOU b/PLC/POUs/Scheduler/POUs/FB_Scheduler.TcPOU index a6a3ce9..a23a77d 100644 --- a/PLC/POUs/Scheduler/POUs/FB_Scheduler.TcPOU +++ b/PLC/POUs/Scheduler/POUs/FB_Scheduler.TcPOU @@ -6,35 +6,77 @@ VAR_INPUT END_VAR VAR_OUTPUT END_VAR +VAR_IN_OUT + fbFlowRecHandler : FB_FlowRecHandler; + fbJobQueue : FB_JobQueue; +END_VAR VAR + // Array needs to start at 1 so that 0 can be an invalid station + // Maybe later change this to int ant -1 _aiStations : ARRAY[1..(GVL_Scheduler.MAX_STATIONS)] OF I_Station; _uiStationCount : UINT := 0; - _fbTransport : I_Station; - _uiTransportCnt : UINT := 0; + _fbTransport : I_Transport; _uiCnt : UINT; _uiNextAvailStation : UINT; - _fbProduct : I_Product; + _iFlowRecIdx : INT; + _dwNextProcReq : DWORD; + + _stTmpJob : ST_TransJob; END_VAR]]> - _dwNextProcReq)) THEN + CONTINUE; + END_IF + // Find next available station according to recipe and available station - _uiNextAvailStation := M_FindNextAvailStation(_aiStations[_uiCnt].P_Product); + _uiNextAvailStation := M_FindNextAvailStation(_dwNextProcReq); // Check if there is a station available IF _uiNextAvailStation <> 0 THEN - // Skip reservation for now - // _aiStations[_uiNextAvailStation].M_Reserve(); - // Create transport job + // Reserve source station + _stTmpJob.uiFromStationHandle := _aiStations[_uiCnt].M_Reserve(); + + // Reserve target station + _stTmpJob.uiToStationHandle := _aiStations[_uiNextAvailStation].M_Reserve(); + + // Check if we could reserve the stations + IF (_stTmpJob.uiToStationHandle <> 0) AND (_stTmpJob.uiFromStationHandle <> 0) THEN + // Create transport job + _stTmpJob.uiFromStation := _uiCnt; + _stTmpJob.uiToStation := _uiNextAvailStation; + _stTmpJob.uiPrio := fbFlowRecHandler.M_GetNextPrio(iIdx := _iFlowRecIdx); + + // Add job to job queue + fbJobQueue.M_AddJob(stJob := _stTmpJob); + ELSE + // Remove registrations from stations + _aiStations[_uiCnt].M_Release(_stTmpJob.uiFromStationHandle); + _aiStations[_uiNextAvailStation].M_Release(_stTmpJob.uiToStationHandle); + END_IF END_IF END_IF END_FOR]]> @@ -55,22 +97,37 @@ _uiStationCount := 0;]]> + + + + (GVL_Scheduler.MAX_STATIONS - 1) THEN + M_GetStation := 0; + RETURN; +END_IF + +M_GetStation := _aiStations[iStationIdx];]]> + + @@ -102,11 +160,10 @@ IF fbTransport = 0 THEN RETURN; END_IF -// Check if we have free slots -IF _uiTransportCnt < GVL_Scheduler.MAX_STATIONS THEN - _aiStations[_uiTransportCnt] := fbTransport; - _uiTransportCnt := _uiTransportCnt + 1; -END_IF]]> +// Set transport interface +_fbTransport := fbTransport; + +]]> diff --git a/PLC/POUs/Scheduler/POUs/GVL_Test.TcGVL b/PLC/POUs/Scheduler/POUs/GVL_Test.TcGVL new file mode 100644 index 0000000..f86d05a --- /dev/null +++ b/PLC/POUs/Scheduler/POUs/GVL_Test.TcGVL @@ -0,0 +1,8 @@ + + + + + + \ No newline at end of file diff --git a/PLC/POUs/Stations/FB_Etcher.TcPOU b/PLC/POUs/Stations/FB_Etcher.TcPOU index d2a6512..1daef66 100644 --- a/PLC/POUs/Stations/FB_Etcher.TcPOU +++ b/PLC/POUs/Stations/FB_Etcher.TcPOU @@ -1,16 +1,61 @@  - - + -1 THEN + _xDone := FALSE; + _xBusy := TRUE; + _iState := 10; + END_IF + + // Simulate process + 10: + _tonProcessDuration(IN := TRUE, PT := T#10S); + IF _tonProcessDuration.Q THEN + _tonProcessDuration(IN := FALSE); + fbFlowRecHandler.M_ReportResult(iIdx := _iFlowRecIdx, xResult := TRUE); + _xProdAvail := TRUE; + _xBusy := FALSE; + _xDone := TRUE; + _iState := 20; + END_IF + + // Wait for station to be empty again + 20: + IF _iFlowRecIdx = -1 THEN + _iState := 0; + END_IF +END_CASE]]> + + + + + + \ No newline at end of file diff --git a/PLC/POUs/Stations/FB_HVTest.TcPOU b/PLC/POUs/Stations/FB_HVTest.TcPOU index ccbeb06..c4e780c 100644 --- a/PLC/POUs/Stations/FB_HVTest.TcPOU +++ b/PLC/POUs/Stations/FB_HVTest.TcPOU @@ -1,16 +1,60 @@  - - + -1 THEN + _xDone := FALSE; + _xBusy := TRUE; + _iState := 10; + END_IF + + // Simulate process + 10: + _tonProcessDuration(IN := TRUE, PT := T#10S); + IF _tonProcessDuration.Q THEN + _tonProcessDuration(IN := FALSE); + fbFlowRecHandler.M_ReportResult(iIdx := _iFlowRecIdx, xResult := TRUE); + _xProdAvail := TRUE; + _xBusy := FALSE; + _xDone := TRUE; + _iState := 20; + END_IF + + // Wait for station to be empty again + 20: + IF _iFlowRecIdx = -1 THEN + _iState := 0; + END_IF +END_CASE]]> + + + + + + \ No newline at end of file diff --git a/PLC/POUs/Stations/FB_Input.TcPOU b/PLC/POUs/Stations/FB_Input.TcPOU index d6026ce..136c196 100644 --- a/PLC/POUs/Stations/FB_Input.TcPOU +++ b/PLC/POUs/Stations/FB_Input.TcPOU @@ -1,16 +1,40 @@  - - + + + + + + + \ No newline at end of file diff --git a/PLC/POUs/Stations/FB_NIO.TcPOU b/PLC/POUs/Stations/FB_NIO.TcPOU index e98e907..16e4560 100644 --- a/PLC/POUs/Stations/FB_NIO.TcPOU +++ b/PLC/POUs/Stations/FB_NIO.TcPOU @@ -1,16 +1,51 @@  - - + -1 THEN + _iState := 10; + END_IF + + // Remove product from line + 10: + _tonAutoRemove(IN := TRUE, PT := T#5S); + IF _tonAutoRemove.Q THEN + _tonAutoRemove(IN := FALSE); + + fbFlowRecHandler.M_RemFlowRec(iIdx := _iFlowRecIdx); + _iFlowRecIdx := -1; + _iState := 0; + END_IF +END_CASE]]> + + + + + + \ No newline at end of file diff --git a/PLC/POUs/Stations/FB_Output.TcPOU b/PLC/POUs/Stations/FB_Output.TcPOU index c0231de..764abbb 100644 --- a/PLC/POUs/Stations/FB_Output.TcPOU +++ b/PLC/POUs/Stations/FB_Output.TcPOU @@ -1,16 +1,51 @@  - - + -1 THEN + _iState := 10; + END_IF + + // Remove product from line + 10: + _tonAutoRemove(IN := TRUE, PT := T#5S); + IF _tonAutoRemove.Q THEN + _tonAutoRemove(IN := FALSE); + + fbFlowRecHandler.M_RemFlowRec(iIdx := _iFlowRecIdx); + _iFlowRecIdx := -1; + _iState := 0; + END_IF +END_CASE]]> + + + + + + \ No newline at end of file diff --git a/PLC/POUs/Stations/FB_Robot.TcPOU b/PLC/POUs/Stations/FB_Robot.TcPOU new file mode 100644 index 0000000..87e8dc1 --- /dev/null +++ b/PLC/POUs/Stations/FB_Robot.TcPOU @@ -0,0 +1,71 @@ + + + + + + _stTransJon) THEN + _xAvailable := FALSE; + + // Get station interfaces + _itfSourceStation := fbScheduler.M_GetStation(_stTransJon.uiFromStation); + _itfTargetStation := fbScheduler.M_GetStation(_stTransJon.uiToStation); + + _iState := 10; + END_IF + + // Move to pickup station + 10: + _tonTransportDone(IN := TRUE, PT := _timTransportTime); + IF _tonTransportDone.Q THEN + _tonTransportDone(IN := FALSE); + + // Get product from station + _iFlowRecIdx := _itfSourceStation.M_RemoveProduct(); + + _iState := 20; + END_IF + + // Move to drop station + 20: + _tonTransportDone(IN := TRUE, PT := _timTransportTime); + IF _tonTransportDone.Q THEN + _tonTransportDone(IN := FALSE); + + // Put product into station + _itfTargetStation.M_InsertProduct(_iFlowRecIdx); + + _iState := 30; + END_IF + + // Release all station reservations + 30: + _itfSourceStation.M_Release(uiHandle := _stTransJon.uiFromStationHandle); + _itfTargetStation.M_Release(uiHandle := _stTransJon.uiToStationHandle); + _xAvailable := TRUE; + _iState := 0; +END_CASE]]> + + + \ No newline at end of file diff --git a/PLC/PlcTask.TcTTO b/PLC/PlcTask.TcTTO index e169d9b..cf45cfc 100644 --- a/PLC/PlcTask.TcTTO +++ b/PLC/PlcTask.TcTTO @@ -12,6 +12,5 @@ {baf80adf-b0f3-4c1e-958c-6b1cb1610e8e} {ff4c396c-9481-47ed-a237-b2f9054f4e68} {e06145cf-bc12-4403-9e2e-7beeb337c603} - \ No newline at end of file diff --git a/SchedulerTest.tsproj b/SchedulerTest.tsproj index c5ed8cd..5d39319 100644 --- a/SchedulerTest.tsproj +++ b/SchedulerTest.tsproj @@ -1,6 +1,6 @@ - + diff --git a/_Config/PLC/PLC Instance.xti b/_Config/PLC/PLC Instance.xti index 82f9731..09df090 100644 --- a/_Config/PLC/PLC Instance.xti +++ b/_Config/PLC/PLC Instance.xti @@ -1,6 +1,6 @@ - + __FILENAME__ {08500001-0000-0000-F000-000000000064}