Users of this guide should be familiar with:
-
Creating C++ programs for PLCnext Control devices, and using those programs in PLCnext Engineer projects. There is extensive information on this topic in the PLCnext Technology Info Center.
-
Transferring files from a PC to the PLC using (for example)
scpor WinSCP. -
Using a Linux shell.
When using C++ programs in a PLCnext Control project, the typical development process includes the following steps:
- Package the C++ component(s) and program(s) into a PLCnext Engineer library.
- Add the library to a PLCnext Engineer project.
- In PLCnext Engineer's "Tasks and Events" window, create one or more C++ program instances in ESM tasks.
- In PLCnext Engineer's "Port List" window, connect GDS ports to/from the C++ program instances.
In cases where the project does not include any IEC 61131 programs, it is possible to eliminate steps 1 and 2 above, and to complete steps 3 and 4 without using PLCnext Engineer. This guide demonstrates how to do this, using a simple example.
| Description | Value |
|---|---|
| Created | 02.06.2021 |
| Last modified | 05.06.2025 |
| Controller | AXC F 2152 |
| FW | 2025.0 |
| SDK | 2025.0 |
| PLCnext Technology Toolchain | 2025.0 |
- PLCnext Runtime configuration files, in the PLCnext Technology Info Center.
In this example, a PLCnext Control device is configured as a Profinet device (slave). A real-time C++ program instance, running in an Execution and Synchronisation Manager (ESM) task, uses Global Data Space (GDS) variables to exchange data with the two Profinet Device (PND) system variables PND_S1_INPUTS and PND_S1_OUTPUTS. The GDS variables are also accessible through the OPC UA Server on the PLCnext Control device. The complete project is configured without the use of PLCnext Engineer.
-
Configure the PLC System Services
This application example uses a PLC that must have the IEC feature deactivated, the PROFINET DEVICE feature activated, and the OPC UA Server feature activated. Other applications that use the principles demonstrated in this example may not require these settings.
Using the PLCs Web Based Management interface, deactivate the IEC system feature, activate the OPC UA feature, and activate the PROFINET DEVICE feature. The PLC must be rebooted for changes to take effect.
-
Create the C++ program.
Using your C++ tool of choice (Eclipse, Visual Studio or the PLCnext Technology CLI), create a new PLCnext C++ project of type "Project". This type of project includes one PLM component and one C++ Program. Name the project “Pnd”, and leave the Component and Program names as the suggested defaults.
-
Create GDS port variables.
In the PndProgram.hpp file, create the following two port variables:
//#port //#attributes(Input|Opc) uint8 PND_S1_INPUTS[512] = {0}; //#port //#attributes(Output|Opc) uint8 PND_S1_OUTPUTS[512] = {0};
The
Opcattribute means that we can see the values of the port variables via the OPC UA Server. -
Build the C++ project.
-
Create the project directory structure on the PLC.
Create a new project directory named
Pndon the PLCnext Control device:mkdir /opt/plcnext/projects/PndCreate the following folder structure inside the Pnd directory:
|-Libs |-Plc | |-Esm | |-Gds | |-Plm |-Services | |-OpcUAYou can see that this is similar to the directory structure in the PCWE directory, which contains the PLCnext Engineer project that runs on the device by default.
-
Copy the C++ library to the PLC.
Copy the .so (shared object library) file from the C++ project's “Release/lib” directory to the following directory on the PLC:
/opt/plcnext/projects/Pnd/Libs -
Program Library Manager (PLM) configuration.
Copy the
pnd.plm.configfile from this repository to the following directory on the PLC:/opt/plcnext/projects/Pnd/Plc/PlmThis file will automatically be loaded by the PLM component of the PLCnext Runtime, and it contains instructions for loading your Pnd library and creating an instance of your PndComponent.
-
ESM configuration.
Copy the
pnd.esm.configfile from this repository to the following directory on the PLC:/opt/plcnext/projects/Pnd/Plc/EsmThis file will automatically be loaded by the ESM component of the PLCnext Runtime, and it contains instructions for creating an ESM task, assigning that task to ESM1, and creating an instance of your PndProgram in that task.
-
GDS configuration.
Copy the
pnd.gds.configfile from this repository to the following directory on the PLC:/opt/plcnext/projects/Pnd/Plc/GdsThis file will automatically be loaded by the GDS component of the PLCnext Runtime, and it contains the GDS port connection information between your program instance and the PND system variables in the PLC.
-
OPC UA Server configuration.
Copy the
PCWE.opcua.configfile from this repository to the following directory on the PLC:/opt/plcnext/projects/Pnd/Services/OpcUAThis file will automatically be loaded by the OPC UA Server component of the PLCnext Runtime. The configuration includes the option to make "Flagged" (or "Marked") GDS variables available through the OPC UA Server, which includes the two variables in our C++ program.
Note that the name of this file cannot be changed. Unlike other components, the OPC UA Server looks specifically for a "PCWE" configuration file, even in projects that are unrelated to PLCnext Engineer. This behaviour may change in future firmware versions.
-
Change the project that is automatically loaded when the PLCnext Runtime starts.
The PLCnext Runtime automatically loads the project that is referenced by the
currentsymbolic link in theprojectsdirectory. By default this is the PCWE (PLCnext Engineer) project, but this can be changed. For example, if a Solution App is installed on the device, then this is placed in a project directory alongside the PCWE directory, and thecurrentlink is automatically changed to point to the App directory.In this case, edit the
currentsymlink to point to the Pnd project:cd /opt/plcnext/projects ln -sfn Pnd current -
Activate the new configuration.
Restart the PLCnext Runtime.
sudo systemctl restart plcnextCheck the
Arp.logfile for any errors - there should be no errors!
The C++ program is now running and exchanging data with the system variables PND_S1_INPUTS and PND_S1_OUTPUTS.
-
Check the program GDS ports via the OPC UA Server.
Use an OPC UA Client like UaExpert to connect to the PLCnext Control device and view the two GDS port variables on the PndProgram instance.
Note that the value of the array elements in the IN port variable can be changed by the OPC UA client, but the values of the array in the OUT port variable cannot - those values need to be set by the C++ program.
The next steps are left up to the user:
-
Write non-zero data to
PND_S1_OUTPUTS.Change the code in the C++ program's
Executemethod, e.g. increment one or more elements of thePND_S1_OUTPUTSarray, and rebuild the C++ project. If there are no changes to the C++ GDS port definitions, you can simply replace the libPnd.so file on the PLC after every build and restart the PLCnext Runtime. -
Configure a Profinet controller.
Using another PLC as a Profinet controller, set up your device on the Profinet network. If required, the GSDML file for your device can be downloaded from the Phoenix Contact website.
The data written to
PND_S1_OUTPUTSon the device can now be observed in the Profinet controller. -
Extend the application.
For example - use the techniques demonstrated in the BusConductor example to enable your C++ component to dynamically configure connected Axioline I/O modules, without using PLCnext Engineer. Your C++ program(s) can then exchange I/O data via GDS port variables.

