PLC Archives | DMC, Inc. https://www.dmcinfo.com/blog/category/manufacturing-automation-intelligence/plc/ Fri, 09 Jan 2026 15:24:00 +0000 en-US hourly 1 https://wordpress.org/?v=6.8.3 https://cdn.dmcinfo.com/wp-content/uploads/2025/04/17193803/site-icon-150x150.png PLC Archives | DMC, Inc. https://www.dmcinfo.com/blog/category/manufacturing-automation-intelligence/plc/ 32 32 Siemens S7-1200 Web Server https://www.dmcinfo.com/blog/40637/siemens-s7-1200-web-server/ Mon, 19 Jan 2026 15:22:54 +0000 https://www.dmcinfo.com/?p=40637 In the 13 years since Tim wrote his blog post on the Siemens embedded web server on S7-1200 and S7-1500 PLCs, a lot has changed regarding PLC security and access control. In this blog post, we will be walking through creating a user-defined web page using the latest security features in TIA Portal V20 and […]

The post Siemens S7-1200 Web Server appeared first on DMC, Inc..

]]>
In the 13 years since Tim wrote his blog post on the Siemens embedded web server on S7-1200 and S7-1500 PLCs, a lot has changed regarding PLC security and access control. In this blog post, we will be walking through creating a user-defined web page using the latest security features in TIA Portal V20 and firmware v4.7.

Project Setup

We will start by creating a new project in TIA Portal, navigating to the “Devices & Networks” page, and adding our chosen PLC from the catalog. For this example, we will be using a `6ES7 212-1BE40-0XB0` more commonly known as a 1212C AC/DC/RLY.

Once the PLC is added, a pop-up will appear asking you to configure PLC security settings for the project. If you clicked cancel or had previously checked the box to prevent this pop-up from being shown, you can access it by clicking on the PLC in the Devices & networks page (the actual PLC, not the gray box around it), selecting the Properties and General tabs, selecting the Protection & Security dropdown, and clicking the Start security wizard button.

PLC CPU

The first step is creating a password to protect the PLC project and data on the PLC. Both DMC and Siemens recommend setting this password to improve OT security, and since we will be enabling a web server on this device (while presumably connecting it to a larger IT network), it is a critical step towards protecting the PLC. It is important to note that once applied, this password cannot be removed – make sure it is documented in a secure place like a password manager available to everyone on your team. A Post-it on your monitor is not a great place to store this password.

PLC

The next security setting is the mode for PG/PC and HMI communication. Unless you know you will be communicating with a legacy device, you should leave this at the default option to only allow secure communication.

PLC HMI Communication

The next setting will be for setting up access control. This should be enabled to restrict who can perform actions on the PLC, such as changing the run mode or accessing our user pages.

The “access levels” option is a legacy option that was the only security option before V20. If setting up a new project, it is recommended to leave this unchecked and use the new User Management and Access Control (UMAC) feature.

PLC access protection

In the next step, we will create one or more administrator users. This user will be able to perform all actions on a PLC that may be restricted, such as changing the mode between run/stop, updating safety settings (if available on your selected PLC model), changing drive parameters, or downloading new programs. It is important to store the login information in a secure place, and having a backup administrator user is a good idea.

PLC Administrator Setup

The next security setting is selecting whether anonymous access should be enabled. This could be useful to provide read-only access to any user without logging in, but it does reduce security slightly. For this demo, we will leave it disabled.

PLC Anonymous Access

The next page will need no changes as we are not using access control levels, and the last page will provide an overview of the settings you have chosen.

PLC Overview

At this point, we can click Finish and get started changing PLC settings for the web server.

Getting Started

Back in Devices & Networks, open up the PLC properties. Each section below will guide you through the settings that need to be changed specifically for the web server.

General

  • Here we can set the PLC name, plant information, and other designators.

PROFINET Interface [X1]

  • Here, we will need to set an IP address and Subnet Mask.
  • If this device will be accessible from an IT network, make sure the router address is set so that the PLC can be accessed outside the immediate local network.
  • If the PLC will be performing any tasks where the time of day needs to be known, or if you would like logs to have accurate timestamps, enable the time-of-day synchronization and enter NTP addresses. For this example, we will use several NIST servers located in different geographic regions.
NIST time-of-day synchronization
  • At the bottom of this tab, make sure to enable the web server on this interface (we will enable the web server module later).
Web Server Access
  • Note: if your PLC has multiple interfaces, one may be set up for connecting to local devices such as drives, remote IO, or local HMIs, and the other may be configured for connection to a larger IT network. The router address, NTP server, and web server access would only be needed on the interface used for IT network access.

Web Server

  • Check the box to enable the web server on all modules of the device and to permit access with HTTPS only.
Web Server general
  • Certificate Type: Hardware-generated
    • For this blog post, we will skip the differences between the two.
  • Further updates will be made here once we create an actual web page.

Time of Day

  • Set the time zone and daylight savings settings according to your location.

Adding Users and Web Server User Roles

Before we download and test our setup so far, we will need to configure user roles to allow access to the web server and create some non-administrator users who can access it.

User Roles

In the project tree, open Security settings > Users and roles and then select the Roles tab.

We will create two new roles: the first is a Web Server Admin, who can perform all tasks through the web server. The existing administrator users will be added to this.

PLC security settings user-roles

The second role will be a Web Server User role with permission to open only the user-defined pages we create.

Web server user role

Users

At this point, we can go back to the Users tab. The administrator users created during the project security setup should be added to the Web Server Admin role. We will “forget” to add the second administrator user to demonstrate what the web server looks like if these permissions are not given to the administrator.

PLC users

Clicking <Add a new user> lets you create a new non-administrator user with only the “Web Server User” role assigned, which we created earlier.

Creating a new non administrator user

Testing our Setup So Far

To confirm that all our security settings are working, we can download the hardware and software to the PLC and try accessing its webpage.

By entering the previously set IP address of our PLC in a browser window, we should be greeted by a Siemens landing page, and we can press Enter to view our PLC’s webpage. Make sure to enter `https://` before the IP address, and click your browser’s “accept the risk and continue” button if you’re prompted with a certificate warning.

PLC web page

By logging in with our first administrator login (dmcAdmin1) we can see that we can access all pages as well as change the run mode of the PLC.

PLC administration login

Logging out and back in as our “incorrectly configured” admin account shows that the user can log in, but because none of the web server runtime rights were granted, we cannot perform any actions that an authenticated user can.

Siemens S7 1200

Finally, by logging in as the standard user with permissions to only access the User Pages, we can see that the user can access the user defined pages tab, but is unable to perform administrator actions such as switching the PLC operating mode, downloading or backing up the program, etc.

S7 1200 Station standard user

Optimization

We have now shown that the Siemens PLC web server is enabled and secured, but if you spend any time navigating even the existing pages, you may notice that the web pages feel sluggish and slow to respond. There are two options that can be changed to speed up the pages.

Communication Load

By default, the PLC is set to spend no more than 20% of its CPU cycles performing communications. For some use cases, you may not have a large or complicated PLC project and would prefer a more responsive web server, at the cost of a slower scan time. By navigating to the PLC properties and increasing the limit from 20% to 50%, the project will become noticeably faster. During testing with one of my customers’ projects, web page loading time was approximately halved, while scan times went from 3-5ms to 4-11ms.

PLC communication load

Enabling HTTP Communications

During the web server setup process, we checked a box to enable only HTTPS (secured and encrypted) communications. Doing so requires the PLC to spend significantly more of the Communication Load time encrypting and decrypting web traffic and less time transferring web pages. Disabling this option will make the web pages load much faster. If your PLC is properly secured behind a VPN or is fully disconnected from the internet, then the decrease in security is not too severe, but keep in mind that anyone with access to the network could theoretically read the unencrypted HTTP information as it is transferred. This means that login information and everything displayed will be transferred in unsecured, plain text.

Enabling HTTP communications

Changing this setting had the most significant impact on page loading time, making the PLC-hosted web page feel almost as responsive as any site on the web, but comes with the cost of the greatest impact on security.

Next Steps

At this point, our PLC project and user permissions are correctly configured to enable user-defined pages. For more details on writing custom HTML pages that interface with the PLC program, check out Tim’s excellent write-up, which is mentioned at the start of this post.

Siemens S7 1200 Station

Ready to take your Automation project to the next level? Contact us today to learn more about our solutions and how we can help you achieve your goals.

The post Siemens S7-1200 Web Server appeared first on DMC, Inc..

]]>
Memory Manipulation Tips For Mitsubishi PLCs using GxWorks3  https://www.dmcinfo.com/blog/40570/memory-manipulation-tips-for-mitsubishi-plcs-using-gxworks3/ Thu, 15 Jan 2026 13:00:00 +0000 https://www.dmcinfo.com/?p=40570 After working with GxWorks3 on several projects, I learned a few things about managing memory that were very helpful. I hope my tips on the following topics will help others as well when working with GxWorks3. Retained Memory It is straightforward to set non-device assigned labels such as local labels within a program or a global label that doesn’t have a device assignment to retain memory. Locate the label and within […]

The post Memory Manipulation Tips For Mitsubishi PLCs using GxWorks3  appeared first on DMC, Inc..

]]>
After working with GxWorks3 on several projects, I learned a few things about managing memory that were very helpful. I hope my tips on the following topics will help others as well when working with GxWorks3.

  1. How to set up retained memory for local labels, global labels with no device assignment, and global labels with device assignment 
  1. Adjusting the allotted device memory if you run out of a certain type of device memory 
  1. Minimizing program memory 

Retained Memory

It is straightforward to set non-device assigned labels such as local labels within a program or a global label that doesn’t have a device assignment to retain memory. Locate the label and within the class drop down select ‘VAR_RETAIN’ or ‘VAR_GLOBAL_RETAIN’ as shown below for the two types of labels.  

GxWorks3 Local Program Label
Figure 1: Local Program Label
GxWorks3 Unassigned Global Label
Figure 2: Unassigned Global Label

It takes a couple of extra steps to set a device assigned global label to retain. After you have decided on which device you want to use to assign to your label, you can assign the device to the label as normal, then select ‘VAR_GLOBAL_RETAIN.’

In the example below, I have assigned a trend array to a device section starting at D12000 up to D12399.  

GxWorks3 Tag Device Assignments
Figure 3: Tag Device Assignments

Next, the D memory registers D12000-D12399 must be designated as retain memory in the ‘Device/Label Memory Area Detailed Setting’ area. To navigate here using the navigation tree, double-click on ‘Parameter’ -> ‘CPU Parameter’ -> ‘Memory/Device Setting’ -> ‘Device/Label Memory Area Setting’ -> ‘<Detailed Settings>.’ 

GxWorks3 Device/Label Memory Area Detailed Settings
Figure 4: Device/Label Memory Area Detailed Settings

This will display the window shown below.

GxWorks3 Setting Devices to Retain Memory
Figure 5: Setting Devices to Retain Memory

From here, double-click on any of the cells circled in the screenshot above. This will open the Latch Range Setting, where we will set what memory registers should be retained or latched.  

GxWorks3 Latch Range Setting Screen
Figure 6.1: Latch Range Setting Screen

Here, we can see that I have a couple of ranges set for both M and D registers including the range D12000-D12999 to include the trend array from our example. After you have set the ranges you need for your project, press ‘OK’ and then you are done.  

Note, if you assign global labels that are not set to retain registers you defined in the Latch Range Setting or vice versa, you will receive a compile error reminding you to correct this.

GxWorks3 Latch Range Setting Compile Error
Figure 6.2: Latch Range Setting Compile Error

Adjusting Device Memory Allotment Size

Depending on the size of your PLC memory and the size of your project, there are times when you might run out of a particular device type. In this situation, if you are unable to upgrade your PLC memory, you can attempt to reallocate your device types if there are some device memory types that you are not using.  

To do this, navigate to the Device/Label Memory Area Setting Detail Settings screen as mentioned in the section above. Starting in the navigation tree, double-click on ‘Parameter’ -> ‘CPU Parameter’ -> ‘Memory/Device Setting’ -> ‘Device/Label Memory Area Setting’ -> ‘<Detailed Settings>.’ 

GxWorks3 Reallocating Device Points
Figure 7: Reallocating Device Points

Under the Device/Points column is where you can see the amount of points allocated to a given device. For example, for the D device, there are 20k points allocated which means the range of usable D devices spans from D0 – D20000. You can modify these allocations as needed as long as the total adds up to the ‘Total Device’ at the bottom as that is the limit of the PLC. After you are done, click on the ‘Check’ button at the bottom to verify that your new allocations are ok.  

Minimizing Program Memory

GxWorks3 Almost Out of Program Memory
Figure 8: Almost Out of Program Memory

The screenshot above was from a previous Mitsubishi GxWorks3 PLC project where we almost ran out of program memory. Since upgrading the PLC memory was not an option, we had to consider other ways to save memory.  

For this project, we were programming from scratch and adhering to DMC’s best practices by using named Global Labels and UDTs for maximum code clarity and ease of maintenance. However, we discovered that moving data directly between UDTs using its symbolic name used a lot of program memory compared to directly manipulating the data using its device memory address. In the screenshots below you can see the massive difference in program steps used between using the symbolic name vs. the direct device address in rung 17.  

GxWorks3 Using symbolic name, 881 steps used
Figure 9: Using symbolic name, 881 steps used
GxWorks3 Using memory address, 79 steps used
Figure 10: Using memory address, 79 steps used

Due to the project hardware constraints, we had to sacrifice some code readability to fit the entire program within the allotted memory available. We used the instructions, BMOV (Transferring 16 – bit block data) and BLKMOV (Transferring n-bit data) on some of the bigger data transfers to help us achieve this. In the end, we were able to fit our program onto the PLC.  

I hope that you find these tips for setting up retained memory, adjusting the allotted device memory, and minimizing program memory helpful when working with GxWorks3. 

Contact us today to learn more about our Mitsubishi PLC expertise and how we can help your team achieve its goals.

The post Memory Manipulation Tips For Mitsubishi PLCs using GxWorks3  appeared first on DMC, Inc..

]]>
Getting Started with Opto 22 groov EPIC Part 3: CODESYS & Ignition Edge https://www.dmcinfo.com/blog/36928/getting-started-with-opto-22-groov-epic-part-3-codesys-ignition-edge/ Mon, 04 Aug 2025 13:00:00 +0000 https://www.dmcinfo.com/?p=36928 In this blog, we will explore the “PLC” functionality of the groov EPIC, completing our three-part series. Soon you will be ready to get started on your own groov EPIC Ignition Edge project!  For an overview of the groov EPIC and its features, check out the rest of this blog series. Setting Up the CODESYS Environment  The […]

The post Getting Started with Opto 22 groov EPIC Part 3: CODESYS & Ignition Edge appeared first on DMC, Inc..

]]>
In this blog, we will explore the “PLC” functionality of the groov EPIC, completing our three-part series. Soon you will be ready to get started on your own groov EPIC Ignition Edge project! 

For an overview of the groov EPIC and its features, check out the rest of this blog series.

Setting Up the CODESYS Environment 

The groov EPIC supports a handful of programming environments, including PAC Control, Node-RED, and the CODESYS IDE. In this demo, we will use CODESYS to develop a simple program for the EPIC. CODESYS is an IEC 61131-3 compliant environment commonly used across many PLC manufacturers, with a user-friendly interface and support for multiple common IEC standard languages. 

To enable CODESYS on the EPIC, first open the groov manager web app and enable CODESYS (Controller > CODESYS Controller > Runtime Enable). Note that while the CODESYS application is running, we can no longer control the outputs from the screen made in blog 2, as the outputs are being controlled from the CODESYS program instead. To switch back to controlling IO from the previous screen, simply disable the CODESYS application from groov manager. This ability to easily switch back and forth between the two modes can be a huge help during I/O checkout and testing of a large, complex system. 

Next, open the CODESYS development environment on a PC that is on the same network as your EPIC and configure your device connection. Create a new project and add a new device connection to your groov EPIC by entering your device IP and scanning the network. Once connected, your device connection will look something like this. 

groov EPIC device connection screen

You can now click the “Login” button on the top toolbar to go online with your EPIC and monitor tag values directly. 

groov EPIC login screen

Configuring Controller Logic in CODESYS 

Our sample PLC program represents a machine that must not be left running unattended for longer than a set time interval (default of 10 seconds). PB_UPPER represents the “On” command to the machine, while PB_LOWER is an additional button that must be held down for the machine to continue running. This input could also be tied to a proximity sensor that determines whether an operator is present at the station. Our buzzer output alerts the operator if the machine has been running unattended for too long. 

Our simple application consists of two programs – the “main” program, PLC_PRG calls the subroutine “TurnOnBuzzer”. TurnOnBuzzer takes in both PB statuses, as well as the buzzer delay setpoint, and outputs the desired buzzer on/off state. These two programs illustrate how both text and ladder logic can be used to program your groov EPIC in CODESYS. 

Program your groov EPIC in CODESYS with text
Program your groov EPIC in CODESYS with ladder logic

To map your controller, I/O to tags within your programs, configure a mapping on the “State” tag of each I/O point, as shown below. Then, add a “Symbol Configuration” object to your application. This is where you control permissions for OPC UA read & write access of your PLC tags from Ignition or other applications. You can configure tags to be read-only or read/write based on the needs of your application. 

Screen to configure mapping on the State tag of each I/O point
Screen to configure mapping on the State tag of each I/O point
Screen to configure mapping on the State tag of each I/O point

Now that our CODESYS program is configured, click the “Login” button and download changes. Next, we’ll set up our Ignition Edge HMI to interact with the CODESYS program. 

Using Ignition Edge as an HMI for a CODESYS Program

Now that our CODESYS OPC server is configured, add a new OPC Connection to your Ignition gateway under Config > OPC Connections. Enter the discovery endpoint of the new CODESYS OPC UA server. If you are using defaults, this will be opc.tcp://localhost:4840. Once this is configured, you will see the new tags you added in CODESYS Symbol Configuration available in Ignition. 

Server discovery screen
connected devices screen

For this demo, we are building onto the Ignition HMI that was developed in part 2 of this blog series, with three new pages. The “Alarm Status” page provides an interface to monitor the status of the two push buttons, and contains an indicator of machine runtime, displaying as it counts towards our “buzzer on delay” value. 

Alarm condition monitor screens

The “Config” tab provides an input field that is linked to our “buzzer on delay” PLC parameter. Here the user can configure the limit for continuous machine runtime before the buzzer is triggered. This provides an example of a tag with read/write permissions between CODESYS and Ignition. 

Controller parameters scren

Finally, the “Trends” tab highlights the internal tag historian functionality of Ignition Edge. Without any extra database connections, tags from the groov EPIC (both PLC program tags or direct IO points) can be stored to the Edge historian and trended to monitor values over time. Here, we have configured the temperature reading from our Thermocouple and the voltage reading from our dial input as historical tags. With Ignition’s sleek and powerful trending tools, these trends can be configured and displayed in minutes. 

analog trends screen

Thanks for reading this Getting Started series for Opto 22 groov EPIC! Now you’re ready to begin programming your own groov EPIC using CODESYS and Ignition Edge.  

Learn more about DMC’s experience with Ignition HMI & SCADA programming and contact us today for your next project. 

The post Getting Started with Opto 22 groov EPIC Part 3: CODESYS & Ignition Edge appeared first on DMC, Inc..

]]>
Getting Started with Opto 22 groov EPIC Part 2: Ignition Edge https://www.dmcinfo.com/blog/36223/getting-started-with-opto-22-groov-epic-part-2-ignition-edge/ Mon, 21 Jul 2025 13:00:00 +0000 https://www.dmcinfo.com/?p=36223 This blog will provide an overview of configuring the Ignition Edge instance that ships with your groov EPIC. For an overview of the groov EPIC and its features, check out the rest of this blog series. Setting up Ignition Edge on groov EPIC  The groov EPIC GRV-EPIC-PR2 model ships with a license for onboard Ignition Edge version […]

The post Getting Started with Opto 22 groov EPIC Part 2: Ignition Edge appeared first on DMC, Inc..

]]>
This blog will provide an overview of configuring the Ignition Edge instance that ships with your groov EPIC.

For an overview of the groov EPIC and its features, check out the rest of this blog series.

Setting up Ignition Edge on groov EPIC 

The groov EPIC GRV-EPIC-PR2 model ships with a license for onboard Ignition Edge version 8. This can be enabled from the groov Manage web server under http://<EPIC address>/manage/local/ignition. Toggle on “Enable Ignition Edge” and click save. It will take a few minutes for the gateway to start.  

Ignition Edge setup screen

Once Ignition Edge has been enabled, simply click the “Open Ignition Edge” link and follow the prompts displayed to configure your Edge gateway. 

Once your gateway is configured, you can add its designer in the Ignition Designer Launcher application by manually entering the gateway URL. From here, you are ready to create your first groov EPIC Ignition Edge project.

Ignition Designer Launcher application

Configuring the groov EPIC OPC UA Server

Open the groov Manage webserver from a PC connected to the groov EPIC. From here, follow the instructions below to configure the OPC UA server.

1. Enable public access for all desired I/O.

a. Navigate to “I/O”, select an I/O point and click “Configure” in the top-right.

configure the OPC UA server I/O screen

b. Under “Public Access” turn on “State (Read)” and “Writable” then click “Save.”

OPC UA server I/O public access screen

c. Repeat the above steps for each desired I/O point. Alternatively, save time by configuring many I/O points at once under I/O > I/O Services > I/O Batch Operations. 

2. Configure data service

a. In groov Manage, navigate to “Data Service” and click “Configure” in the top right. 

b. Under “Scanned Devices”, click “Add Local PAC Controller.” 

c. Configure desired settings (ensure OPC UA Server is on) and save.

OPC UA server device configuration screen

d. Navigate back to the Data Service configuration page and add an OPC UA server. Set the following settings.

Add OPC UA server screen

e. Return to the Data Service status page and enable Data Service Runtime. 

Connecting the groov EPIC OPC UA Server to Ignition

Now that we have an OPC UA server configured, we will next connect this to our local Ignition Edge gateway. 

1. In the Ignition Edge gateway, navigate to Config > OPC Connections. 

2. Click “Create new OPC connection.”

3. Copy the Discovery Endpoint from your previously configured OPC UA server into the “Endpoint URL” field. 

4. Follow the remaining configuration prompts to set up your connection. 

5. Give your connection a name and click “Save Changes.”

Once this connection is configured, you should be able to see your new OPC UA connection under Config>OPC Connections with a Status of “Connected.” You can now browse OPC UA tags from the Ignition designer and add your groov EPIC I/O tags to your Ignition project. 

OPC UA connection screen

From here, Ignition Edge screens can be easily developed to monitor and control the EPIC’s local I/O. In our demo setup, we monitor these I/O tags directly on the Main screen, as shown below.  

Ignition Edge main screen wiht a temperature and dial indicator

Ignition’s powerful scripting capabilities may be used to implement control logic directly, without a need for a PLC program. For the next part of this demo, however, the CODESYS controller onboard the EPIC was leveraged. In part 3, we will explore using CODESYS and Ignition Edge together on a groov EPIC. 

Ready to take your Automation project to the next level? Contact us today to learn more about our solutions and how we can help you achieve your goals. 

The post Getting Started with Opto 22 groov EPIC Part 2: Ignition Edge appeared first on DMC, Inc..

]]>
Controller Fault Handling in Rockwell PLCs https://www.dmcinfo.com/blog/36538/controller-fault-handling-in-rockwell-plcs/ Mon, 14 Jul 2025 14:22:31 +0000 https://www.dmcinfo.com/?p=36538 In industrial automation, even minor interruptions can result in substantial losses in productivity and revenue. To minimize downtime and enhance system reliability, Rockwell PLCs support a configurable fault handler program that enables the system to respond to faults in a controlled and effective manner. This article explores what controller faults are, why fault handling can […]

The post Controller Fault Handling in Rockwell PLCs appeared first on DMC, Inc..

]]>
In industrial automation, even minor interruptions can result in substantial losses in productivity and revenue. To minimize downtime and enhance system reliability, Rockwell PLCs support a configurable fault handler program that enables the system to respond to faults in a controlled and effective manner. This article explores what controller faults are, why fault handling can be useful, and how to implement a fault handler in your Rockwell PLC program.

Understanding Controller Faults

A fault disrupts normal PLC execution and can stem from logic errors, data issues, or hardware problems. Rockwell controllers classify faults as either minor or major. Minor faults are logged but do not stop the program. Major faults, however, halt execution and must be cleared or acknowledged.

Fault Type Comparison

FeatureMinor FaultMajor Fault
Program ExecutionContinuesHalts until fault is cleared or acknowledged
SeverityLowHigh
Example CausesOverflow, underflow warningsInvalid index, Negative timer preset
RecoveryYesIntervention required
VisibilityLogged in controllerData removed after clearing

By proactively handling recoverable major faults, users can reduce the impact of these interruptions. More importantly, controller fault data can be logged for the future and displayed on the HMI, so operators can see exactly what happened.

Creating the Fault Handler in Studio 5000

Setting up a fault handler in Rockwell’s Studio 5000 environment is a relatively simple process, but it’s important to follow the correct structure and understand what happens under the hood. The controller fault handler allows fault conditions to be handled programmatically, and in some cases, recovered from without halting the entire system.

Note: You cannot add a fault handler routine to a program while online. The project must be offline, and the program must be downloaded to the PLC for the fault handler to take effect.

Step 1: Create a Controller Fault Handler Program

Open your project in Studio 5000 Logix Designer. In the Controller Organizer, right-click the Controller Fault Handler folder and select New Program. Name the program according to your project standards (e.g., ControllerFaults) and ensure the Schedule In option is set to “Controller Fault Handler.

controller organizer

Step 2: Add a Routine to the Fault Handler Program

Once the program is created, right-click it and choose Add > New Routine. Assign a descriptive name such as “HandleMajorFaults”.

controller faults

Step 3: Define a UDT to Store Fault Information

To identify the fault and capture its data for logging or HMI display, create a user-defined data type (UDT). This structure should match Rockwell’s recommendation for storing a program’s MajorFaultRecord.

In the Controller Organizer, right-click Data Types > User-Defined and create a UDT (e.g., FAULTRECORD). The structure should include the following attributes:

Data Type: FAULTRECORD
Name FAULTRECORD
DescriptionStores the MajorFaultRecord attribute or MinorFaultRecord attribute of the Program object
Members
NameData TypeStyleDescription
Time_LowDINTDecimalLower 32 bits of the fault timestamp value
Time_HighDINTDecimalUpper 32 bits of the fault timestamp value
TypeINTDecimalFault type (program, I/O, and so forth)
CodeINTDecimalUnique code for the fault
InfoDINT[8]HexFault specific information
faultrecord

Note: The Type and Code fields are used to identify the fault and determine the appropriate response.

The Info attribute contains encoded data related to the fault, but its format is not human-readable.

Step 4: Write the Fault Handling Logic

In your routine, use the GSV (Set System Value) instruction to retrieve fault details from the MajorFaultRecord attribute. Store this data in a tag using the FAULTRECORD type.

Then, add logic to evaluate the fault’s type and code.

major fault record

If the fault is one that should be auto-recoverable (e.g., an invalid array index), use the SSV (Set System Value) instruction to clear it. A MOV instruction can be used to write the fault data to the HMI.

The two EQU instructions compare the fault type and code to identify the fault condition. Each recoverable fault you wish to handle requires a separate rung that checks for that fault’s unique type and code. Faults are categorized using numeric values; a complete list is available on the Rockwell Automation website here.

Note: When a controller faults, it provides the exact location of the fault. This location is not included if the fault is caught by the handler.

Important: Only clear faults that are known and safe to recover from. Avoid clearing all faults indiscriminately, as this could hide critical system issues.

Step 5: Testing and Validation

To verify your fault handler, induce a fault manually and confirm that the system logs and processes it correctly. A common test involves assigning a negative value to a timer preset, which triggers a major fault when executed. Be sure to have a rung in the fault handling routine that is specifically looking for the timer preset fault code and type.

TON testing and validation

You can test other faults as well, but be cautious. Only test conditions that you have configured the fault handler to manage, as unhandled faults will stop the PLC and may interrupt production.

Rockwell provides a tutorial on creating fault handlers, which includes additional examples and best practices, which can be found here.

Summary

Implementing a controller fault handler in your Rockwell PLC program provides a structured way to manage recoverable runtime faults. It helps reduce unplanned downtime, preserves fault data for diagnostics, and supports smoother system recovery.

If you’re working through a fault-handling strategy or looking for ways to improve system resilience, contact us today to learn more about our solutions and how we can help you implement smarter, more resilient PLC programs that keep your production line running efficiently.

Ready to take your Automation project to the next level? Contact us today to learn more about our solutions and how we can help you achieve your goals. 

The post Controller Fault Handling in Rockwell PLCs appeared first on DMC, Inc..

]]>
Getting Started with Opto 22 groov EPIC Part 1: groov EPIC Introduction https://www.dmcinfo.com/blog/36186/getting-started-with-opto-22-groov-epic-part-1-groov-epic-introduction/ Wed, 02 Jul 2025 08:00:00 +0000 https://www.dmcinfo.com/?p=36186 Opto 22’s groov EPIC (Edge Programmable Industrial Controller) is more than just a modern PLC. With an embedded Linux operating system, the groov EPIC processor supports a wide array of platforms for programming, visualization, and more at the network’s edge.  For an overview of the groov EPIC and its features, check out the rest of this blog […]

The post Getting Started with Opto 22 groov EPIC Part 1: groov EPIC Introduction appeared first on DMC, Inc..

]]>
Opto 22’s groov EPIC (Edge Programmable Industrial Controller) is more than just a modern PLC. With an embedded Linux operating system, the groov EPIC processor supports a wide array of platforms for programming, visualization, and more at the network’s edge. 

For an overview of the groov EPIC and its features, check out the rest of this blog series.

Here are just a few ways developers can interact with the groov EPIC processor: 

  • CODESYS (Runtime Engine license included) and PAC Control programming environments
  • Custom programming in C, C++, Python, Java, etc. by leveraging the EPIC’s Linux operating system
  • Local Ignition Edge instance (license included) for visualization & data acquisition across the network
  • Optional full Ignition gateway with additional license cost
  • Node-RED flow configuration
  • Built-in groov Manage & groov View webpages for quick & intuitive configuration & data visualization

With this impressive list of tools and features that ship with the groov EPIC processor, the task of selecting which to use for a given project can feel daunting. In this blog series, we will dive into a few of these options and have you ready to set up your first groov EPIC in no time! 

tools and features that ship with the groov EPIC processor
Credit: Opto 22

Our Hardware Setup

For this demo, we will be using the following groov EPIC processor and IO modules. 

groov EPIC processor on a wood table

GRV-EPIC-PR2 Processor

The GRV-EPIC-PR2 is Opto 22’s second generation groov EPIC processor, complete with onboard Ignition Edge 8, Linux operating system, and CODESYS runtime engine. The processor comes with a built-in high resolution touch screen and HDMI port for easy connection to an external monitor. 

IO Modules

  • IACDCTTL-24 Digital Input module, connected to the two push buttons shown in the above image 
  • ODCI-12 Digital Output module, connected to a buzzer 
  • IICTD-12 Temperature Probe Analog Input module, connected to the thermocouple shown above.
  • IV-24 Voltage Analog Input module, connected to the analog potentiometer dial shown above 

OPC UA Server Options on groov EPIC

With all the various features and programming environments available on the groov EPIC, determining the correct option for interacting with local I/O as well as distributed devices can be overwhelming. In this blog series, we’ll focus on a few different OPC UA servers that can be hosted locally on the EPIC to interact with local I/O and PLC program tags. Before we jump into our setup, here is a quick breakdown of some of the OPC UA server options on the groov EPIC and the appropriate use-case for each. 

Ignition OPC UA Server 

The Ignition OPC UA server comes with the included Ignition Edge module and is enabled by default once Ignition Edge is enabled on the EPIC. This server can be configured from the Ignition Edge gateway and is useful when communicating with network devices, such as other PLCs, from the groov’s Ignition Edge application. This OPC UA server was not used in this demo, as we did not connect to any external network devices from the groov EPIC. 

Groov EPIC OPC Server

The groov EPIC OPC server is the second OPC server that is hosted on the EPIC. This is configured from the groov Manage web server and allows clients to read and write to the EPIC’s local I/O directly. Part 2 of this blog series will focus on using this server to interact with the EPIC’s I/O from Ignition Edge. 

CODESYS OPC Server

In addition to Ignition Edge, the groov EPIC also comes with an onboard CODESYS controller that can be enabled from groov Manage. To use Ignition Edge as a front-end HMI for this CODESYS controller program, an OPC server must be configured on the CODESYS controller. This server then may be connected to the local Ignition Edge gateway, allowing PLC program tags to be read & written to from Ignition. This setup is detailed in part 3 of this blog series. 

Navigating the groov Manage Webserver

Out of the box, the groov EPIC comes with an impressive and sleek webserver that can be used to easily perform basic configuration and monitoring of the device and its I/O. This webpage can be accessed from a PC over the network as well as directly from the groov EPIC’s onboard touch screen, although some functionality is available only from a PC. 

groov EPIC processor on a wood table

IO Monitoring & Control from groov Manage 

The I/O section of the groov Manage webpage contains an intuitive interface to monitor, control, and configure I/O points. This useful tool can make commissioning and I/O checkout a breeze on any size system. Without any external software, users can quickly: 

  • Set a name & units for each I/O point 
  • Configure scaling, gain, and offset for analog values 
  • Monitor the state of inputs 
  • Modify output values 
  • Configure external access ability for each I/O point 
  • And more! 

The “batch operations” functionality even allows for some of these operations to be completed in bulk for many channels at once. 

groov Manage interface with many channels

System Configuration from groov Manage

The groov Manage webpage is a one-stop shop for configuring network settings, security, users, and more. The Data Service tab includes configuration for MQTT and OPC UA server. The Ignition, Node-RED, and groov View tabs allow you to quickly enable & launch each service on the groov EPIC processor. The Controller tab provides the ability to start, stop, and diagnose CODESYS and PAC applications running on the controller. Furthermore, the Info and Help tab contains links to a variety of useful support guides. 

Using groov View as an Onboard UI

Opto 22’s groov View is a no-code tool that can be used to quickly develop custom user interfaces to display on the groov EPIC’s onboard touchscreen, in addition to a network PC. Groov View can pull in tags from the groov EPIC’s own I/O or connect to several external data sources including OPC UA servers & Modbus devices. To get started, navigate to groov View from the groov Manage webserver and click the link to open groov View. This will open the home page of your groov View project. 

This HMI can be configured by switching to Build mode from the top-right corner Menu button. From Build mode, UI elements called “gadgets” can be dragged onto pages, linked to tags and organized with ease. 

Using groov View as an Onboard UI

Each page developed with groov View has both a Desktop/Tablet and Handheld size, to facilitate use from a PC/tablet or from the groov EPIC’s onboard touch screen. Navigation between pages is also built into groov View, making development a breeze. In minutes, you can have a custom application on the groov EPIC’s onboard screen that combines critical I/O points with external OPC UA or Modbus tags.

groov View custom application
Using groov View as an Onboard UI

Check out part 2 of the Opto 22 groov EPIC series to learn how to use CODESYS and Ignition Edge with groov EPIC.

Ready to take your Automation project to the next level? Contact us today to learn more about our solutions and how we can help you achieve your goals.

The post Getting Started with Opto 22 groov EPIC Part 1: groov EPIC Introduction appeared first on DMC, Inc..

]]>
Beckhoff XTS Part 7: Customizing Logic https://www.dmcinfo.com/blog/15346/beckhoff-xts-part-7-customizing-logic/ Thu, 12 Jun 2025 14:55:56 +0000 https://www.dmcinfo.com/blog/15346/beckhoff-xts-part-7-customizing-logic/ In previous entries of this blog series, we went over the Mover, Station, and PositionTrigger function blocks. Now that we understand these function blocks better, let’s use them to write our own Beckhoff XTS custom logic. This blog will continue to use the Beckhoff XTS_Base GitHub and the large XTS starter kit.  Beckhoff XTS Series […]

The post Beckhoff XTS Part 7: Customizing Logic appeared first on DMC, Inc..

]]>
In previous entries of this blog series, we went over the Mover, Station, and PositionTrigger function blocks. Now that we understand these function blocks better, let’s use them to write our own Beckhoff XTS custom logic.

This blog will continue to use the Beckhoff XTS_Base GitHub and the large XTS starter kit

Beckhoff XTS Series

Customizing the Logic

Let’s update this logic to customize our system a bit more. For my system, I’m going to have stations and position triggers at the following places:

customizing logic

Update the Station and Position Trigger Positions

Remove the existing station and position trigger definitions on lines 108-117 and replace it with the following:

// Initialize station positions
Station[0].Position := 5;
Station[1].Position := 3200;
Station[2].Position := 3300;
Station[3].Position := 3400;
Station[4].Position := 3500;

PositionTrigger[0].Position := 1500;
PositionTrigger[1].Position := 2000;

This will define the stations and position triggers as shown above.

Updating the Station and Position Trigger Logic

Next, we need to update the logic of these stations and position triggers to get them to behave as we want. For this application, let’s have the mover run at high velocity across the top rail, then go down to the low velocity around the bend. Once it clears the bend, it can go back up to the medium velocity until it reaches the next station. Once we have a mover in each of the four bottom left stations, send them all back to station 0. Replacing lines 210-265 with the following code will do that:

// Station 0 Logic
IF Station[0].MoverInPosition THEN
    StationTimer[0](IN := TRUE, PT := T#1000MS);
    IF StationTimer[0].Q THEN
        Station[0].CurrentMover.MoveVelocity(highVelocity);
    END_IF
ELSE
    StationTimer[0](IN := FALSE);
END_IF
    // Position Trigger 0 Logic
IF PositionTrigger[0].MoverPassedPosition THEN
    PositionTrigger[0].CurrentMover.SetVelocity(lowVelocity);
    PositionTrigger[0].MuteCurrent();
END_IF
    // Position Trigger 1 Logic
IF PositionTrigger[1].MoverPassedPosition THEN
    PositionTrigger[1].CurrentMover.SetVelocity(mediumVelocity);
    PositionTrigger[1].CurrentMover.MoveToStation(Station[nextStation]);
    nextStation := nextStation – 1;
    IF nextStation = 0 THEN
        nextStation := 4;
    END_IF
    PositionTrigger[1].MuteCurrent();
END_IF

// Group of Stations 1, 2, 3, and 4 Logic
IF Station[1].MoverInPosition AND Station[2].MoverInPosition AND Station[3].MoverInPosition AND Station[4].MoverInPosition THEN
    StationTimer[1](IN := TRUE, PT := T#750MS);
    IF StationTimer[1].Q THEN
        StationTimer[1](IN := FALSE);
        Station[1].CurrentMover.MoveToStation(Station[0]);
        Station[2].CurrentMover.MoveToStation(Station[0]);
        Station[3].CurrentMover.MoveToStation(Station[0]);
        Station[4].CurrentMover.MoveToStation(Station[0]);
    END_IF
END_IF

Execute the New Code

Save the new code and activate the configuration. After logging in, you should be able to open the Controls visualization, press the Enable button, and then the Start button to start seeing the movers follow the new logic.

customizing logic executing the new code

This is just an example of the many customizations you can make to your XTS system. There’s even more functionality that comes with this starter project, though. In the next entry in this blog series, we will go over zones and add those to our custom logic.

If you’d like help with the next steps for your XTS system, DMC is proud to be a Beckhoff System Integrator and has worked on multiple XTS projects and applications. Learn more about our Beckhoff partnership and contact us for your next project.

Ready to take your Automation project to the next level? Contact us today to learn more about our solutions and how we can help you achieve your goals.

The post Beckhoff XTS Part 7: Customizing Logic appeared first on DMC, Inc..

]]>
Beckhoff XTS Part 6: Position Triggers https://www.dmcinfo.com/blog/15350/beckhoff-xts-part-6-position-triggers/ Mon, 02 Jun 2025 10:26:12 +0000 https://www.dmcinfo.com/blog/15350/beckhoff-xts-part-6-position-triggers/ The previous entry in this series went over the Station function block. Stations are excellent at holding movers while an operation is performed on their payload. Stations require a mover to stop at the station before continuing along, but what if we wanted to adjust our mover’s behavior while it’s still moving? That’s what position […]

The post Beckhoff XTS Part 6: Position Triggers appeared first on DMC, Inc..

]]>
The previous entry in this series went over the Station function block. Stations are excellent at holding movers while an operation is performed on their payload. Stations require a mover to stop at the station before continuing along, but what if we wanted to adjust our mover’s behavior while it’s still moving? That’s what position triggers are for. This blog will go over the PositionTrigger function block that comes with the base starter project. We will see how to configure Beckhoff XTS position triggers properly and what methods we have at our disposal to use with our system. 

This blog will continue to use the Beckhoff XTS_Base GitHub and the large XTS starter kit

Beckhoff XTS Series

Position Triggers

Position triggers are defined positions along the XTS track that know when movers pass by. This can allow for on-the-fly redirections or changes in velocity.

Declaring a Position Trigger

In MAIN, in the variable declaration we already have an array of position triggers defined with the line

Structured Text
PositionTrigger : ARRAY[0..2] OF PositionTrigger;

This defines 3 position triggers to use. If you want to use more, you can increase the array bounds. It’s also likely worth using a global constant similar to how the stations are defined.

Configuring Position Triggers

The existing starter project already has 3 position triggers configured, shown below.

configuring position triggers

Similarly to the stations, the position definition for these position triggers is in the MS_INTIIALIZING_OBJECTIVES section of the MAIN state machine, which is at line 115.

Structured Text
PositionTrigger[0].Position := 1500;
PositionTrigger[1].Position := 2000;
PositionTrigger[2].Position := 3500

We can see that the position triggers are given positions (in mm) around the track that line up with the picture above. Changing these positions will change where along the track the position triggers exist.

These position triggers also have CyclicLogic methods that must be called every scan and are already called for us at line 419.

Structured Text
PositionTrigger[0].Cyclic();
PositionTrigger[1].Cyclic();
PositionTrigger[2].Cyclic();

If you add more position triggers, make sure to call their CyclicLogic methods as well.

The stations also make sure to unregister movers on stopping or disabling. This happens on lines 332 and 367 by calling the UnregisterAll method for each position trigger.

Structured Text
FOR i := 0 TO SIZEOF(PositionTrigger) / SIZEOF(PositionTrigger[0]) - 1 DO
  PositionTrigger[i].UnregisterAll();
END_FOR

Position Trigger Logic

The existing starter project already has some position trigger logic. The logic for these position triggers is in the MS_RUN section of the MAIN state machine, which starts at line 250. There’s a few methods and properties about the position triggers that are useful to describe to interpret this code:

MoverPassedPosition

MoverPassedPosition is a property of the position trigger object. It goes TRUE when a mover passed the configured position trigger’s position. This will allow for logic based on the position trigger to affect the mover passing by.

MuteCurrent

MuteCurrent is a method of the position trigger object. It will set MoverPassedPosition to FALSE and clear out the mover being tracked by the position trigger. This can be used to indicate the position trigger logic is done and a new mover can be handled.

With these properties and methods, let’s see what the current position triggers are doing.

Structured Text
// Position Trigger 0 Logic
IF PositionTrigger[0].MoverPassedPosition THEN
  PositionTrigger[0].CurrentMover.SetVelocity(lowVelocity);
  PositionTrigger[0].MuteCurrent();
END_IF

// Position Trigger 1 Logic
IF PositionTrigger[1].MoverPassedPosition THEN
  PositionTrigger[1].CurrentMover.SetVelocity(highVelocity);
  PositionTrigger[1].MuteCurrent();
END_IF

// Position Trigger 2 Logic
IF PositionTrigger[2].MoverPassedPosition THEN
  PositionTrigger[2].CurrentMover.SetVelocity(lowVelocity);
  PositionTrigger[2].CurrentMover.MoveToStation(Station[0]);
  PositionTrigger[2].MuteCurrent();
END_IF

Position triggers 0 and 1 are doing similar things. They both wait for a mover to pass their position and then change the velocity of the mover. Position trigger 0 changes to low velocity and position trigger 1 changes to high velocity. They then both call the MuteCurrent methods to clear out the mover from the position trigger. Note that neither of these position triggers are sending a command to the mover, just changing its velocity. The mover is still obeying the MoveVelocity command from station 4.

Position trigger 2 waits for a mover to pass its position, sets the velocity low, and then commands the mover to move to station 0. This will override the move velocity command from station 4 and so the mover will next stop at station 0. The logic then calls MuteCurrent to signal the position trigger has processed the mover.

Now that we’ve reviewed movers, stations, and positions triggers we can not only understand the existing starter project logic but also write our own custom logic. In the next entry in this blog series, we will go over writing some custom logic for our XTS application.

If you’d like help with the next steps for your XTS system, DMC is proud to be a Beckhoff System Integrator and has worked on multiple XTS projects and applications. Learn more about our Beckhoff partnership and contact us for your next project.

Ready to take your Automation project to the next level? Contact us today to learn more about our solutions and how we can help you achieve your goals.

The post Beckhoff XTS Part 6: Position Triggers appeared first on DMC, Inc..

]]>
Beckhoff XTS Part 5: Stations https://www.dmcinfo.com/blog/15354/beckhoff-xts-part-5-stations/ Fri, 23 May 2025 13:30:41 +0000 https://www.dmcinfo.com/blog/15354/beckhoff-xts-part-5-stations/ The previous entry in this series went over the Mover function block. Movers already give us a lot of options for how to control our XTS system, but typically we don’t want to control movers based on which index in the array they are, we want to control them based on where they are along […]

The post Beckhoff XTS Part 5: Stations appeared first on DMC, Inc..

]]>
The previous entry in this series went over the Mover function block. Movers already give us a lot of options for how to control our XTS system, but typically we don’t want to control movers based on which index in the array they are, we want to control them based on where they are along the track. That’s what stations are for.

This blog will go over the Beckhoff XTS Station block that comes with the base starter project. We will see how to configure the stations properly and what methods we have at our disposal to use with our system. This blog will continue to use the Beckhoff XTS_Base GitHub and the large XTS starter kit.

Beckhoff XTS Series

Stations

Stations are defined positions along the XTS track where movers will stop until commanded to do something else. This allows for a mover to reach the station, have some actions performed on it while stationary, then to be sent elsewhere on the track.

Declaring Stations

In MAIN, in the variable declaration we already have an array of stations declared with the line

Structured Text
Station : ARRAY[0..GVL.NUM_STATIONS - 1] OF Station;

If you want to add more stations, you can change the value of NUM_STATIONS in the GVL file. There’s advantages and disadvantages to having your stations in an array. The advantages are that they’re all stored in one place, the name is consistent across various stations, and it’s easy to iterate through all the stations if needed. Additionally, adding stations between two existing stations is as easy as shifting the other stations in the array up an index. The disadvantage is that the station names are not going to be as descriptive as they could be if they were individually named. For this blog, we’re going to continue using the array of stations.

Configuring Stations

The existing starter project already has 5 stations configured, shown below:

configuring stations

The position definition for these stations is in the MS_INTIIALIZING_OBJECTIVES section of the MAIN state machine, which is at line 109.

Structured Text
Station[0].Position := 5;
Station[1].Position := 750;
Station[2].Position := 1200;
Station[3].Position := 1300;
Station[4].Position := 1400;

We can see that the stations are given positions (in mm) around the track that line up with the picture above. Changing these positions will change where along the track the stations exist.

We also need to make sure to call the CyclicLogic method of the station object. This is already done for us in line 414.

Structured Text
FOR i := 0 TO GVL.NUM_STATIONS - 1 DO
  Station[i].Cyclic();
END_FOR

One other thing these stations are already configured to do is to unregister movers on stopping or disabling. This will make sure that no movers are “trapped” at stations when the system starts back up. This is done in lines 327 and 362 by calling the UnregisterAll method for each station.

Structured Text
FOR i := 0 TO GVL.NUM_STATIONS - 1 DO
  Station[i].UnregisterAll();
END_FOR

Station Logic

The existing starter project already has some stations logic. The logic for these stations is in the MS_RUN section of the MAIN state machine, which starts at line 212. There’s a couple methods and properties about the station objects that are useful to describe to interpret this code.

MoverInPosition

MoverInPosition is a property of the station object. This property is true if a mover has arrived at the station. This is important to check before trying to do anything with a station’s mover because if there is no mover in the station, the code will try to command an invalid mover reference.

CurrentMover

CurrentMover is a property of the station object. This property is a reference to the mover that is currently at the station. This allows commands to the movers to go through the stations so logic can be configured on a station level rather than on a mover level.

With these methods and properties, we can better understand what the existing stations are doing.

Structured Text
// Station 0 Logic
IF Station[0].MoverInPosition THEN
  StationTimer[0](IN := TRUE, PT := T#1000MS);
  IF StationTimer[0].Q THEN
    Station[0].CurrentMover.SetVelocity(mediumVelocity);
    Station[0].CurrentMover.MoveToStation(Station[1]);
  END_IF
ELSE
  StationTimer[0](IN := FALSE);
END_IF

Station 0 is straightforward. Once a mover arrives, the logic waits for 1 second before setting the velocity to medium velocity and sending the mover to station 1.

Structured Text
// Station 1 Logic
IF Station[1].MoverInPosition THEN
  StationTimer[1](IN := TRUE, PT := T#250MS);
  IF StationTimer[1].Q THEN
    Station[1].CurrentMover.SetVelocity(mediumVelocity);
    Station[1].CurrentMover.MoveToStation(Station[nextStation]);
    nextStation := nextStation - 1;
    IF nextStation = 1 THEN
      nextStation := 4;
    END_IF
  END_IF
ELSE
  StationTimer[1](IN := FALSE);
END_IF

Station 1 has some similar logic. It only waits for 250 milliseconds and then rotates through sending to station 4, then station 3, then station 2, then back to station 4. This is a great example of how you can use the XTS system to multi-task with processes that have higher cycle times.

Structured Text
// Group of Stations 2, 3, and 4 Logic
IF Station[2].MoverInPosition AND Station[3].MoverInPosition AND Station[4].MoverInPosition THEN
  StationTimer[2](IN := TRUE, PT := T#750MS);
  IF StationTimer[2].Q THEN
    StationTimer[2](IN := FALSE);

    Station[2].CurrentMover.MoveVelocity(500);
    Station[3].CurrentMover.MoveVelocity(500);
    Station[4].CurrentMover.MoveVelocity(500);
  END_IF
END_IF

Stations 2 through 4 have their logic combined since they’re intended to be parallel processes. Once a mover has arrived in each of the three stations, the logic waits for 750 milliseconds before commanding all three movers to move at 500mm/s.

If we’re commanding these movers to move at 500mm/s until they receive another command, how will they ever stop? The first answer is that they have collision avoidance, so the movers will stop if they would run into a mover ahead of them. The second answer is that we have position triggers further along the track to give them new commands. In the next blog in this series, we will go over position triggers.

If you’d like help with the next steps for your XTS system, DMC is proud to be a Beckhoff System Integrator and has worked on multiple XTS projects and applications. Learn more about our Beckhoff partnership and contact us for your next project.

Ready to take your Automation project to the next level? Contact us today to learn more about our solutions and how we can help you achieve your goals.

The post Beckhoff XTS Part 5: Stations appeared first on DMC, Inc..

]]>
Beckhoff XTS Part 4: Movers https://www.dmcinfo.com/blog/15357/beckhoff-xts-part-4-movers/ Thu, 17 Apr 2025 10:38:02 +0000 https://www.dmcinfo.com/blog/15357/beckhoff-xts-part-4-movers/ In previous entries of this blog series, we went over how to configure, activate, and run code on a Beckhoff XTS system. Running the starter project is great to ensure the system is wired and configured correctly, but to truly get the most out of our XTS system we need to understand how to control […]

The post Beckhoff XTS Part 4: Movers appeared first on DMC, Inc..

]]>
In previous entries of this blog series, we went over how to configure, activate, and run code on a Beckhoff XTS system. Running the starter project is great to ensure the system is wired and configured correctly, but to truly get the most out of our XTS system we need to understand how to control the movers for our specific application.

This blog will go over the Beckhoff XTS mover blocks that comes with the base starter project. We will see how to configure the movers properly and what methods we have at our disposal to use with our system. This blog will continue to use the Beckhoff XTS_Base GitHub and the large XTS starter kit

Beckhoff XTS Series

Movers

Movers are the software representation of the physical XTS movers. The mover object built into the base project is a great starting point since it comes with a lot of useful methods for controlling the mover behavior. 

Declaring Movers

In the previous entry in this blog series, we made sure to update the number of movers to match the physical movers in our system. In the MAIN program, we can see that the movers are declared with the line.

Structured Text
Mover : ARRAY[0..GVL.NUM_MOVERS - 1] OF Mover;

As mentioned in the previous section, this NUM_MOVERS should be exactly equal to the number of physical movers in the XTS system. Additionally, the axis references of these mover objects should be linked to the motion axes. If you haven’t already done that see this section

Configuring Movers

Like most drives, the movers need to have a set of parameters and to go through an enable process before they can run. The base project already does both things for us. In the MAIN program the code starting at line 52 is where the parameter set is applied to all of the movers configured in our system. 

Structured Text
FOR i := 0 TO GVL.NUM_MOVERS - 1 DO
  Mover[i].MotionParameters := ParameterSet;
END_FOR

The lines starting at line 46 define the parameter set, which includes acceleration, deceleration, jerk, velocity, and direction. 

Structured Text
ParameterSet.Jerk     := 1E5; // mm/s3
ParameterSet.Acceleration := 1E4; // mm/s2
ParameterSet.Deceleration := 1E4; // mm/s2
ParameterSet.Velocity   := 1E3; // mm/s
ParameterSet.Direction   := mcDirectionPositive;

Line 72 is where the movers are enabled 

Structured Text
FOR i := 0 TO GVL.NUM_MOVERS - 1 DO
  Mover[i].Enable();
END_FOR

and a few lines down in line 87 is where their Ready property is checked to see if they got enabled properly. 

Structured Text
FOR i := 0 TO GVL.NUM_MOVERS - 1 DO
  IF Mover[i].Ready = FALSE THEN
    allMoversEnabled := FALSE;
  END_IF
END_FOR

Additionally, the movers must be assigned to a track. This happens starting at line 144 by calling ActivateTrack and passing in the track the mover is to be assigned to. 

Structured Text
FOR i := 0 TO GVL.NUM_MOVERS - 1 DO
  Mover[i].ActivateTrack(Track[1]);
END_FOR

For the basic starter project, all movers are assigned to track 1. If your application has multiple tracks, this is where you can specify which movers belong to which track. A few lines down at line 153 is where the logic checks the mover’s IsTrackReady property to make sure they’re properly assigned to their track. 

Structured Text
allMoverTracksEnabled := TRUE;
FOR i := 0 TO GVL.NUM_MOVERS - 1 DO
  IF (NOT Mover[i].IsTrackReady) THEN
    allMoverTracksEnabled := FALSE;
  END_IF;
END_FOR

To stop the movers, the logic will need to call the Halt method. This is already implemented in line 286 of the base starter project. 

Structured Text
FOR i := 0 TO GVL.NUM_MOVERS - 1 DO
  Mover[i].Halt();
END_FOR

Once the movers are stopped, they can be disabled using the Disable method. Again, this is already implemented in line 348. 

Structured Text
FOR i := 0 TO GVL.NUM_MOVERS DO
  Mover[i].Disable();
END_FOR

It’s worth noting that if you have a vertically mounted track, disabling the movers will often let them succumb to gravity. It could be worth implementing something that gets the movers off the curved sections before disabling them. 

Many of these XTS library objects have methods named Cyclic or CyclicLogic that need to be called every scan in order to function properly, so check those are getting called correctly if any issues come up. For our movers, this happens at line 408. 

Structured Text
FOR i := 0 TO GVL.NUM_MOVERS - 1 DO
  Mover[i].Cyclic(GroupRef);
  Mover[i].AxisReference.ReadStatus();
END_FOR;

The logic also calls the ReadStatus method of the mover’s internal axis reference to ensure the status values are up to date. 

Now we’ve gone over a lot of the configuration that these movers need. We can enable them, assign a parameter set to them, assign them to tracks, stop them and disable them. We’re also calling the Cyclic method that ensures our commands get processed properly. Now it’s time for the fun part, getting the movers to move around the track. 

Mover Logic

The mover objects come with four main methods that will help control their movement throughout the track. Here’s a quick description of each of the methods. 

SetVelocity

SetVelocity is a method of the mover object. It will immediately change the velocity of the mover to the commanded velocity (in mm/s).

MoveVelocity

MoveVelocity is a method of the mover object. It will command a mover to run at the commanded velocity (in mm/s) until it receives another command.

MoveToStation

MoveToStation is a method of the mover object. It will command a mover to go to the commanded station. Note that there’s no velocity input for this method, so the mover will go at its existing velocity, which was likely last given by SetVelocity or MoveVelocity. The mover will stop once it reaches the commanded station.

MoveToPosition

MoveToPosition is a method of the mover object. It will command a mover to go to the inputted position (in mm). Similar to MoveToStation, there is no velocity input so this will use the mover’s existing velocity.

The MoveToStation function is particularly useful, but first we have to understand what a station is. We will go over stations in the next entry in this blog series.

If you’d like help with the next steps for your XTS system, DMC is proud to be a Beckhoff System Integrator and has worked on multiple XTS projects and applications. Learn more about our Beckhoff partnership and contact us for your next project.

Ready to take your Automation project to the next level? Contact us today to learn more about our solutions and how we can help you achieve your goals.

The post Beckhoff XTS Part 4: Movers appeared first on DMC, Inc..

]]>