From f4486c89eb2f7b5da2d965dce6ff04514b62ed9c Mon Sep 17 00:00:00 2001 From: Matt Walsh Date: Thu, 14 Aug 2025 09:59:30 -0500 Subject: [PATCH 1/3] Make separate FB_XTS object array sizes from Mediator object array sizes This makes it much simpler to define XTS objects in user-code and have the mediator be able to register them via Mediator.Add... methods. --- Base Project.sln | 10 +++++++ Base Project/Base Project.tsproj | 4 +-- Base Project/PLC1/GVLs/Param.TcGVL | 9 ++++-- .../Administrative/Mediator.TcPOU | 28 +++++++++++-------- .../XTS (Do Not Edit)/Objects/Mover.TcPOU | 20 ++++++++----- 5 files changed, 47 insertions(+), 24 deletions(-) diff --git a/Base Project.sln b/Base Project.sln index 1a2c1c2..88671c0 100644 --- a/Base Project.sln +++ b/Base Project.sln @@ -13,6 +13,7 @@ Global Debug|TwinCAT OS (ARMV7-M) = Debug|TwinCAT OS (ARMV7-M) Debug|TwinCAT OS (ARMV8-A) = Debug|TwinCAT OS (ARMV8-A) Debug|TwinCAT OS (x64) = Debug|TwinCAT OS (x64) + Debug|TwinCAT OS (x64-E) = Debug|TwinCAT OS (x64-E) Debug|TwinCAT RT (x64) = Debug|TwinCAT RT (x64) Debug|TwinCAT RT (x86) = Debug|TwinCAT RT (x86) Release|TwinCAT CE7 (ARMV7) = Release|TwinCAT CE7 (ARMV7) @@ -21,6 +22,7 @@ Global Release|TwinCAT OS (ARMV7-M) = Release|TwinCAT OS (ARMV7-M) Release|TwinCAT OS (ARMV8-A) = Release|TwinCAT OS (ARMV8-A) Release|TwinCAT OS (x64) = Release|TwinCAT OS (x64) + Release|TwinCAT OS (x64-E) = Release|TwinCAT OS (x64-E) Release|TwinCAT RT (x64) = Release|TwinCAT RT (x64) Release|TwinCAT RT (x86) = Release|TwinCAT RT (x86) EndGlobalSection @@ -37,6 +39,8 @@ Global {E3FDD453-7143-4CBE-AF2D-E7E762464CFC}.Debug|TwinCAT OS (ARMV8-A).Build.0 = Debug|TwinCAT OS (ARMV8-A) {E3FDD453-7143-4CBE-AF2D-E7E762464CFC}.Debug|TwinCAT OS (x64).ActiveCfg = Debug|TwinCAT OS (x64) {E3FDD453-7143-4CBE-AF2D-E7E762464CFC}.Debug|TwinCAT OS (x64).Build.0 = Debug|TwinCAT OS (x64) + {E3FDD453-7143-4CBE-AF2D-E7E762464CFC}.Debug|TwinCAT OS (x64-E).ActiveCfg = Debug|TwinCAT OS (x64-E) + {E3FDD453-7143-4CBE-AF2D-E7E762464CFC}.Debug|TwinCAT OS (x64-E).Build.0 = Debug|TwinCAT OS (x64-E) {E3FDD453-7143-4CBE-AF2D-E7E762464CFC}.Debug|TwinCAT RT (x64).ActiveCfg = Debug|TwinCAT RT (x64) {E3FDD453-7143-4CBE-AF2D-E7E762464CFC}.Debug|TwinCAT RT (x64).Build.0 = Debug|TwinCAT RT (x64) {E3FDD453-7143-4CBE-AF2D-E7E762464CFC}.Debug|TwinCAT RT (x86).ActiveCfg = Debug|TwinCAT RT (x86) @@ -53,6 +57,8 @@ Global {E3FDD453-7143-4CBE-AF2D-E7E762464CFC}.Release|TwinCAT OS (ARMV8-A).Build.0 = Release|TwinCAT OS (ARMV8-A) {E3FDD453-7143-4CBE-AF2D-E7E762464CFC}.Release|TwinCAT OS (x64).ActiveCfg = Release|TwinCAT OS (x64) {E3FDD453-7143-4CBE-AF2D-E7E762464CFC}.Release|TwinCAT OS (x64).Build.0 = Release|TwinCAT OS (x64) + {E3FDD453-7143-4CBE-AF2D-E7E762464CFC}.Release|TwinCAT OS (x64-E).ActiveCfg = Release|TwinCAT OS (x64-E) + {E3FDD453-7143-4CBE-AF2D-E7E762464CFC}.Release|TwinCAT OS (x64-E).Build.0 = Release|TwinCAT OS (x64-E) {E3FDD453-7143-4CBE-AF2D-E7E762464CFC}.Release|TwinCAT RT (x64).ActiveCfg = Release|TwinCAT RT (x64) {E3FDD453-7143-4CBE-AF2D-E7E762464CFC}.Release|TwinCAT RT (x64).Build.0 = Release|TwinCAT RT (x64) {E3FDD453-7143-4CBE-AF2D-E7E762464CFC}.Release|TwinCAT RT (x86).ActiveCfg = Release|TwinCAT RT (x86) @@ -69,6 +75,8 @@ Global {DD3A0B29-8E7C-4E32-989D-B0222C998777}.Debug|TwinCAT OS (ARMV8-A).Build.0 = Debug|TwinCAT OS (ARMV8-A) {DD3A0B29-8E7C-4E32-989D-B0222C998777}.Debug|TwinCAT OS (x64).ActiveCfg = Debug|TwinCAT OS (x64) {DD3A0B29-8E7C-4E32-989D-B0222C998777}.Debug|TwinCAT OS (x64).Build.0 = Debug|TwinCAT OS (x64) + {DD3A0B29-8E7C-4E32-989D-B0222C998777}.Debug|TwinCAT OS (x64-E).ActiveCfg = Debug|TwinCAT OS (x64-E) + {DD3A0B29-8E7C-4E32-989D-B0222C998777}.Debug|TwinCAT OS (x64-E).Build.0 = Debug|TwinCAT OS (x64-E) {DD3A0B29-8E7C-4E32-989D-B0222C998777}.Debug|TwinCAT RT (x64).ActiveCfg = Debug|TwinCAT RT (x64) {DD3A0B29-8E7C-4E32-989D-B0222C998777}.Debug|TwinCAT RT (x64).Build.0 = Debug|TwinCAT RT (x64) {DD3A0B29-8E7C-4E32-989D-B0222C998777}.Debug|TwinCAT RT (x86).ActiveCfg = Debug|TwinCAT RT (x86) @@ -85,6 +93,8 @@ Global {DD3A0B29-8E7C-4E32-989D-B0222C998777}.Release|TwinCAT OS (ARMV8-A).Build.0 = Release|TwinCAT OS (ARMV8-A) {DD3A0B29-8E7C-4E32-989D-B0222C998777}.Release|TwinCAT OS (x64).ActiveCfg = Release|TwinCAT OS (x64) {DD3A0B29-8E7C-4E32-989D-B0222C998777}.Release|TwinCAT OS (x64).Build.0 = Release|TwinCAT OS (x64) + {DD3A0B29-8E7C-4E32-989D-B0222C998777}.Release|TwinCAT OS (x64-E).ActiveCfg = Release|TwinCAT OS (x64-E) + {DD3A0B29-8E7C-4E32-989D-B0222C998777}.Release|TwinCAT OS (x64-E).Build.0 = Release|TwinCAT OS (x64-E) {DD3A0B29-8E7C-4E32-989D-B0222C998777}.Release|TwinCAT RT (x64).ActiveCfg = Release|TwinCAT RT (x64) {DD3A0B29-8E7C-4E32-989D-B0222C998777}.Release|TwinCAT RT (x64).Build.0 = Release|TwinCAT RT (x64) {DD3A0B29-8E7C-4E32-989D-B0222C998777}.Release|TwinCAT RT (x86).ActiveCfg = Release|TwinCAT RT (x86) diff --git a/Base Project/Base Project.tsproj b/Base Project/Base Project.tsproj index 1413441..d12fe94 100644 --- a/Base Project/Base Project.tsproj +++ b/Base Project/Base Project.tsproj @@ -35782,7 +35782,7 @@ External Setpoint Generation: - + NC SAF Inputs @@ -36083,7 +36083,7 @@ External Setpoint Generation: - + PLC1 Instance {08500001-0000-0000-F000-000000000064} diff --git a/Base Project/PLC1/GVLs/Param.TcGVL b/Base Project/PLC1/GVLs/Param.TcGVL index ba8a671..7efba96 100644 --- a/Base Project/PLC1/GVLs/Param.TcGVL +++ b/Base Project/PLC1/GVLs/Param.TcGVL @@ -3,11 +3,14 @@ 0 THEN StationArray[i]^.Cyclic(); END_IF END_FOR -FOR i := 0 TO Param.NUM_POSITIONTRIGGERS - 1 DO +FOR i := 0 TO Param.MAX_POSITIONTRIGGERS - 1 DO IF PositionTriggerArray[i] <> 0 THEN PositionTriggerArray[i]^.Cyclic(); END_IF @@ -855,16 +855,16 @@ IF THIS^.InfoServerIsReady AND internalEnabled AND Param.AUTO_POPULATE_STATIONS 40: // calculate minimum number of stations that can be set up - nUsableStations := MIN(nInfoServerStations, Param.NUM_STATIONS); + nUsableStations := MIN(nInfoServerStations, Param.MAX_STATIONS); workingStation := 0; FOR i := 1 TO nUsableStations DO workingStation := workingStation + 1; // in case a sparse Station array is used, only detect stations that have a position value <> 0 - WHILE (workingStation < Param.NUM_STATIONS AND_THEN (StationArray[workingStation] = 0 OR_ELSE StationArray[workingStation]^.Position = 0)) DO + WHILE (workingStation < Param.MAX_STATIONS AND_THEN (StationArray[workingStation] = 0 OR_ELSE StationArray[workingStation]^.Position = 0)) DO workingStation := workingStation + 1; END_WHILE // check for valid working station, and exit this for loop iteration if we're outside it - IF workingStation >= Param.NUM_STATIONS THEN + IF workingStation >= Param.MAX_STATIONS THEN EXIT; END_IF // get XTS_Base Station pointer @@ -1162,11 +1162,15 @@ END_VAR ]]> 0 THEN + PositionTriggerArray[i]^.ResetStatistics(); + END_IF END_FOR -FOR i := 0 TO Param.NUM_STATIONS-1 DO - StationArray[i]^.ResetStatistics(); +FOR i := 0 TO Param.MAX_STATIONS-1 DO + IF StationArray[i] <> 0 THEN + StationArray[i]^.ResetStatistics(); + END_IF END_FOR ]]> diff --git a/Base Project/PLC1/XTS (Do Not Edit)/Objects/Mover.TcPOU b/Base Project/PLC1/XTS (Do Not Edit)/Objects/Mover.TcPOU index 7192ff3..4ab9fdd 100644 --- a/Base Project/PLC1/XTS (Do Not Edit)/Objects/Mover.TcPOU +++ b/Base Project/PLC1/XTS (Do Not Edit)/Objects/Mover.TcPOU @@ -1,4 +1,4 @@ - + 0 THEN + Mediator.PositionTriggerArray[i]^.UnregisterMover( THIS^ ); + END_IF END_FOR -FOR i := 0 TO Param.NUM_STATIONS-1 DO - Mediator.StationArray[i]^.UnregisterMover( THIS^ ); +FOR i := 0 TO Param.MAX_STATIONS-1 DO + IF Mediator.StationArray[i] <> 0 THEN + Mediator.StationArray[i]^.UnregisterMover( THIS^ ); + END_IF; END_FOR -FOR i := 0 TO Param.NUM_ZONES-1 DO - Mediator.ZoneArray[i]^.UnregisterMover( THIS^ ); +FOR i := 0 TO Param.MAX_ZONES-1 DO + IF Mediator.ZoneArray[i] <> 0 THEN + Mediator.ZoneArray[i]^.UnregisterMover( THIS^ ); + END_IF END_FOR]]> From 42aad904032127134969f3ec6a39cd96139ce569 Mon Sep 17 00:00:00 2001 From: Matt Walsh Date: Thu, 14 Aug 2025 10:00:00 -0500 Subject: [PATCH 2/3] Document Params and add code example with custom XTS object outside FB_XTS --- .../docs/CodeReference/Parameters.md | 33 +++ Documentation/docs/Examples/CustomObjects.md | 222 ++++++++++++++++++ Documentation/mkdocs.yml | 2 + 3 files changed, 257 insertions(+) create mode 100644 Documentation/docs/CodeReference/Parameters.md create mode 100644 Documentation/docs/Examples/CustomObjects.md diff --git a/Documentation/docs/CodeReference/Parameters.md b/Documentation/docs/CodeReference/Parameters.md new file mode 100644 index 0000000..49524fb --- /dev/null +++ b/Documentation/docs/CodeReference/Parameters.md @@ -0,0 +1,33 @@ + +# Parameters + +Paramaters configure the overall size of the XTS application including the number of objects such as stations or zones needed. Parameters can be viewed and adjusted in `GVL\Param`. + +!!! Note + Mover appears in parameters but is not addressed in this section as it has additional needs when increasing or decreasing its count. Please see [Project Customization](../GettingStarted/2_FirstSteps.md#project-customization). + +## NUM_ Parameters + +The provided FB_XTS object includes a set of the objects listed already pre-configured and ready to use. + +- `XTS.Mover[]` +- `XTS.PositionTrigger[]` +- `XTS.Station[]` +- `XTS.Zone[]` + +The size of these arrays is configured with the corresponding `NUM_` parameter. + +In many XTS applications, especially ones that implement simple station-to-station motion, the provided objects are all that is needed for user code. An simple adjustment of the `NUM_` parameter to increase stations, zones or position triggers may be the only parameters that need to be adjusted to fit the application. + +## MAX_ Parameters + +The mediator can manage additional Position Triggers, Stations and Zones outside of those declared in FB_XTS if needed for an application. This can help with code modularity and allows you to create custom objects (as FBs) that contain their own stations, zones and position triggers as needed. + +The `MAX_` parameters define the absolute maximum number of any of these objects that can be declared. The value selected should be high enough to include the number of objects created by the `NUM_` parameter, and any additional objects you will create in user code. + +!!! Note + There is no performance penalty for having more MAX_ objects than you actually use. Any objects in the array that have not been configured do not cause additional code to execute. There is a small amount of memory required for extra, unused objects but this often is insignificant in the overall size of the program and memory available on IPCs capable of running XTS. + +## MAX_ Parameters Example + +An example of declaring additional objects that consume space under the `MAX_` parameter limits is available in [Custom Objects](../Examples/CustomObjects.md) \ No newline at end of file diff --git a/Documentation/docs/Examples/CustomObjects.md b/Documentation/docs/Examples/CustomObjects.md new file mode 100644 index 0000000..9b5a0dd --- /dev/null +++ b/Documentation/docs/Examples/CustomObjects.md @@ -0,0 +1,222 @@ +# Custom objects + +This example makes use of additional position trigger objects defined outside of `FB_XTS` in a reusable, object-oriented solution. Understanding the use of the [XTS Parameters](../CodeReference/Parameters.md) is necessary for understanding this example. + +## The Application + +A basic assembly and inspection station consists of the following processes in order: + +1. Load part A to mover +1. Inspect part A at a line scan camera +1. Load part B into part A on mover +1. Inspect part A and B at a line scan camera +1. Unload completed part + +Stations 1, 3 and 5 are basic stop-wait-release stations. The line scan cameras in steps 2 and 4 require the movers to move at a defined speed and trigger the camera at the appropriate point. This example will use custom position triggers defined inside a reusable line scan camera FB to create these stations. + +## Solution discussion + +While this application can be solved using only the built in `XTS.Station[]` and `XTS.PositionTrigger[]` objects, care will need to be taken to keep track of which station indexes and position trigger indexes are grouped together and in which order. In this very small example this is not difficult to manage, but in larger applications these types of mappings can become cumbersome. + +Here is one way this could be implemented using only `FB_XTS` objects + +- `XTS.Station[1]` feeds the line scan camera surrounded by `XTS.PositionTrigger[1]` and `XTS.PositionTrigger[2]` +- `XTS.PositionTrigger[2]` feeds `XTS.Station[2]` +- `XTS.Station[2]` feeds the line scan camera surrounded by `XTS.PositionTrigger[3]` and `XTS.PositionTrigger[4]` +- `XTS.PositionTrigger[4]` feeds `XTS.Station[3]` +- Movers return to station 1 + +From the above sequence you can see that it very quickly becomes difficult to trace the flow through these processes. + +By createing a new line scan camera object to contain the position triggers and skipping some unneeded station indices we can make this much more readable + +- XTS.Station[1] feeds LineScan2 +- LineScan2 feeds XTS.Station[3] +- XTS.Station[3] feeds LineScan4 +- LineScan4 feeds XTS.Station[5] + +## The line scan station + +Because of the need for speed changes two position triggers will be used before and after the line scan camera to adjust the mover's speed. The first position trigger will also start the camera's scanning. + +The FB `LineScanCamera` will be created to implement this solution. + +### Declarations + +We start by declaring two position triggers inside the `LineScanCamera`. + +```javascript + StartPositionTrigger : PositionTrigger; // slow down and trigger camera + EndPositionTrigger : PositionTrigger; // speed up and check camera results +``` + +We'll also need an interface to a camera and a few other intermediate variables + +```javascript +VAR INPUT + CameraSpeed : LREAL; // speed to slow to for camera + ExitSpeed : LREAL; // speed to next station + + StartPosition : LREAL; // slow down point + EndPosition : LREAL; // speed up point +END_VAR + +VAR_IN_OUT + Camera : CameraInterface; // a camera interface with trigger, pass and fail bits +END_VAR + +VAR + TargetMover : iMover; // a temporary variable attached to the mover at the position triggers + Initialized : bool; // first-run flag for initializing the position triggers +END_VAR +``` + +### Initialization + +Position triggers need to be registered with the XTS system. This accomplishes two things: + +- The PositionTrigger.Cyclic() routine is called automatically for us by the [Mediator](../CodeReference/Objects/Mediator.md) +- The position trigger will automatically be populated with all movers on the system. + +We also need to set the locations of the position triggers. + +```javascript +IF NOT Initalized THEN + // set the initialized flag (one-shot this if statement) + Initialized = true; + + // copy locations to position triggers + StartPositionTrigger.Position := StartPosition; + EndPositionTrigger.Position := EndPosition; + + // register the position triggers with the XTS system + MAIN.XTS.System.AddPositionTrigger(StartPosition); + MAIN.XTS.System.AddPositionTrigger(EndPosition); +END_IF +``` + +### Start position trigger + +The start position trigger slows down the mover and triggers the camera. + +[Position Trigger](../CodeReference/Objects/PositionTrigger.md) and the Mover's [Payload](../CodeReference/Objects/Mover.md#payload) are used by this code. Details of their use can be found in the links. + +```javascript +// check for the position trigger's flag +IF StartPositionTrigger.MoverPassedPosition THEN + // get the mover that most recently passed this location + TargetMover = StartPositionTrigger.CurrentMover; + + // there is no need to slow down or scan an empty mover + // check for valid data and or product on this mover via the Payload parameter + IF THEN + // slow down the mover + TargetMover.SetVelocity(CameraSpeed); + // trigger the camera + Camera.Trigger := TRUE; + END_If + + // clear the position trigger flag + StartPositionTrigger.MuteCurrent(); +END_IF; +``` + +### End Position Trigger + +The end position trigger checks the camera result and speeds up the mover. It does not directly send the mover to the next station, as the station destination was already set by the preceding load station. + +[Position Trigger](../CodeReference/Objects/PositionTrigger.md) and the Mover's [Payload](../CodeReference/Objects/Mover.md#payload) are used by this code. Details of their use can be found in the links. + +```javascript +// check for the position trigger's flag +IF EndPositionTrigger.MoverPassedPosition THEN + // get the mover that most recently passed this location + TargetMover = EndPositionTrigger.CurrentMover; + + // if the camera was triggered we're working on this mover and need to clean up + IF (Camera.Trigger) THEN + // reset the camera trigger + Camera.Trigger := FALSE; + + // assign the camera result to the mover's payload + // e.g. TargetMover.Payload.CameraResult = Camera.Result + + // speed up the mover + TargetMover.SetVelocity(ExitSpeed); + END_IF + + // clear the position trigger flag + EndPositionTrigger.MuteCurrent(); +END_IF +``` + +### MAIN Implementation + +First declarations on `MAIN` need to be added for the two position triggers + +```javscript + // line scan camera speed and trigger controls + LineScan2 : LineScanCamera; + LineScan4 : LineScanCamera; + + // for clarity the camera interfaces are declared here, but the actual camera communication interface is not part of the scope of this example + Camera2 : CameraInterface; + Camera4 : CameraInterface; +``` + +Then within the `MAIN.StationLogic` we'll add code to implement the load, scan, load, scan and unload sequence defined above. More complete examples and discussion of [Station-to-Station](./StationRouting.md) motion is available. + +Pay careful attention to the sequence of how movers are sent from one station to the next. + +- XTS.Station[1] sends its mover to XTS.Station[3] +- XTS.Station[3] sends its mover to XTS.Station[5] + +Since we do not stop at the line-scan camera, we can send the movers directly to the next stop position. The line scan code will adjust the mover's speed accordingly, but will not change the destination. + +```javascript + +// first station waits for part to be loaded +IF XTS.Station[1].MoverInPosition THEN + // trigger loading mechanism + // wait for load complete + // update mover payload + // release the mover to the next station + XTS.Station[1].CurrentMover.MoveToStation(XTS.Station[3]) +END_IF + +// Call the first camera station (station 2) with appropriate parameters +LineScan2( + CameraSpeed := 100.0, // mm/s in front of the camera + ExitSpeed := 1000.0, // ms/s when scanning is complete + StartPosition := 200.0, // mm + EndPosition := 300.0, // mm + Camera := Camera2, +) + +// third station waits for part to be loaded +IF XTS.Station[3].MoverInPosition THEN + // trigger loading mechanism + // wait for load complete + // update mover payload + // release the mover to the next station + XTS.Station[3].CurrentMover.MoveToStation(XTS.Station[5]) +END_IF + +// Call the second camera station (station 4) with appropriate parameters +LineScan4( + CameraSpeed := 50.0, // mm/s in front of the camera + ExitSpeed := 1000.0, // ms/s when scanning is complete + StartPosition := 600.0, // mm + EndPosition := 700.0, // mm + Camera := Camera4, +) + +// third station waits for part to be unloaded and sends the empty mover back to the start at station 1 +IF XTS.Station[5].MoverInPosition THEN + // trigger loading mechanism + // wait for load complete + // update mover payload + // release the mover to the next station + XTS.Station[5].CurrentMover.MoveToStation(XTS.Station[1]) +END_IF +``` \ No newline at end of file diff --git a/Documentation/mkdocs.yml b/Documentation/mkdocs.yml index 41adebc..3608c23 100644 --- a/Documentation/mkdocs.yml +++ b/Documentation/mkdocs.yml @@ -48,6 +48,7 @@ nav: - Track: CodeReference/Objects/Track.md - Zone: CodeReference/Objects/Zone.md - System: CodeReference/Objects/Mediator.md + - Parameters: CodeReference/Parameters.md - Diagnostics: - Basics: CodeReference/Diagnostics/Basics.md - ErrorMovers: CodeReference/Diagnostics/ErrorMovers.md @@ -57,3 +58,4 @@ nav: - Examples: - Application Mover: Examples/ApplicationMover.md - Station to Station: Examples/StationRouting.md + - Custom Objects: Examples/CustomObjects.md From e2f5c29e0eb43086fb6a6d9467584ea6146452c4 Mon Sep 17 00:00:00 2001 From: Matt Walsh Date: Thu, 14 Aug 2025 13:35:23 -0500 Subject: [PATCH 3/3] Add over-subscribed messages to Mediator arrays --- Base Project/Base Project.tsproj | 2 +- .../Administrative/Mediator.TcPOU | 60 ++++++++++++++----- Documentation/docs/Examples/CustomObjects.md | 4 +- 3 files changed, 48 insertions(+), 18 deletions(-) diff --git a/Base Project/Base Project.tsproj b/Base Project/Base Project.tsproj index d12fe94..5fd8f7b 100644 --- a/Base Project/Base Project.tsproj +++ b/Base Project/Base Project.tsproj @@ -36083,7 +36083,7 @@ External Setpoint Generation: - + PLC1 Instance {08500001-0000-0000-F000-000000000064} diff --git a/Base Project/PLC1/XTS (Do Not Edit)/Administrative/Mediator.TcPOU b/Base Project/PLC1/XTS (Do Not Edit)/Administrative/Mediator.TcPOU index 66c079e..0c37e62 100644 --- a/Base Project/PLC1/XTS (Do Not Edit)/Administrative/Mediator.TcPOU +++ b/Base Project/PLC1/XTS (Do Not Edit)/Administrative/Mediator.TcPOU @@ -79,8 +79,8 @@ END_VAR VAR duplicateFound : BOOL; - i : UDINT; - emptyIDX : UDINT; + i : DINT; + emptyIDX : DINT := -1;; END_VAR]]> @@ -162,12 +168,18 @@ IF __ISVALIDREF( MoverList ) THEN END_IF ELSE // track the first empty index - IF (emptyIDX = 0) THEN + IF (emptyIDX = -1) THEN emptyIDX := i; END_IF; END_IF END_FOR + // if no empty index is available set a message and return + IF emptyIDX = -1 THEN + ADSLOGSTR( ADSLOG_MSGTYPE_WARN, 'MoverList System Array is full. %s not added. Check Params.MAX_MOVERLISTS' , MoverList.InstancePath); + RETURN; + END_IF; + IF duplicateFound = FALSE THEN THIS^.MoverListArray[emptyIDX] := ADR( MoverList ); END_IF @@ -187,8 +199,8 @@ END_VAR VAR duplicateFound : BOOL; - i : UDINT; - emptyIDX : UDINT; + i : DINT; + emptyIDX : DINT := -1; END_VAR ]]> @@ -208,12 +220,18 @@ IF __ISVALIDREF( PositionTrigger ) THEN END_IF ELSE // track the first empty index - IF (emptyIDX = 0) THEN + IF (emptyIDX = -1) THEN emptyIDX := i; END_IF; END_IF END_FOR + // if no empty index is available set a message and return + IF emptyIDX = -1 THEN + ADSLOGSTR( ADSLOG_MSGTYPE_WARN, 'AddPositionTrigger System Array is full. %s not added. Check Params.MAX_POSITIONTRIGGERS' , PositionTrigger.InstancePath); + RETURN; + END_IF; + IF duplicateFound = FALSE THEN THIS^.PositionTriggerArray[emptyIDX] := ADR( PositionTrigger ); @@ -238,8 +256,8 @@ END_VAR VAR duplicateFound : BOOL; - i : UDINT; - emptyIDX : UDINT; + i : DINT; + emptyIDX : DINT := -1; END_VAR ]]> @@ -259,12 +277,18 @@ IF __ISVALIDREF( Station ) THEN END_IF ELSE // track the first empty index - IF (emptyIDX = 0) THEN + IF (emptyIDX = -1) THEN emptyIDX := i; END_IF; END_IF END_FOR + // if no empty index is available set a message and return + IF emptyIDX = -1 THEN + ADSLOGSTR( ADSLOG_MSGTYPE_WARN, 'AddStation System Array is full. %s not added. Check Params.MAX_STATIONS' , Station.InstancePath); + RETURN; + END_IF; + IF duplicateFound = FALSE THEN THIS^.StationArray[emptyIDX] := ADR( Station ); END_IF @@ -324,8 +348,8 @@ END_VAR VAR duplicateFound : BOOL; - i : UDINT; - emptyIDX : UDINT; + i : DINT; + emptyIDX : DINT := -1; END_VAR ]]> @@ -345,12 +369,18 @@ IF __ISVALIDREF( Zone ) THEN END_IF ELSE // track the first empty index - IF (emptyIDX = 0) THEN + IF (emptyIDX = -1) THEN emptyIDX := i; END_IF; END_IF END_FOR + // if no empty index is available set a message and return + IF emptyIDX = -1 THEN + ADSLOGSTR( ADSLOG_MSGTYPE_WARN, 'AddZone System Array is full. %s not added. Check Params.MAX_ZONES' , Zone.InstancePath); + RETURN; + END_IF; + IF duplicateFound = FALSE THEN THIS^.ZoneArray[emptyIDX] := ADR( Zone ); diff --git a/Documentation/docs/Examples/CustomObjects.md b/Documentation/docs/Examples/CustomObjects.md index 9b5a0dd..8de3c02 100644 --- a/Documentation/docs/Examples/CustomObjects.md +++ b/Documentation/docs/Examples/CustomObjects.md @@ -187,7 +187,7 @@ END_IF // Call the first camera station (station 2) with appropriate parameters LineScan2( CameraSpeed := 100.0, // mm/s in front of the camera - ExitSpeed := 1000.0, // ms/s when scanning is complete + ExitSpeed := 1000.0, // mm/s when scanning is complete StartPosition := 200.0, // mm EndPosition := 300.0, // mm Camera := Camera2, @@ -205,7 +205,7 @@ END_IF // Call the second camera station (station 4) with appropriate parameters LineScan4( CameraSpeed := 50.0, // mm/s in front of the camera - ExitSpeed := 1000.0, // ms/s when scanning is complete + ExitSpeed := 1000.0, // mm/s when scanning is complete StartPosition := 600.0, // mm EndPosition := 700.0, // mm Camera := Camera4,