Accessing, creating and handling PLC POUs

This chapter explains in-depth how to access PLC objects, for example POUs, Methods, Transitions, Properties, and how to access their corresponding implementation and declaration areas to handle PLC code. It also covers how to import/export PLC objects in PLCopen XML. The following list shows all chapters in this article:

General information about PLC objects

Although every tree item is considered to be of type ITcSmTreeItem, some items need to be casted to a more special interface to gain access to all of their methods and properties, for example POUs which need to be casted to the interface ITcPlcPou to get access to their unique methods and properties.

Code snippet (C#):

ITcSmTreeItem plcPousItem = systemManager.LookupTreeItem("TIPC^PlcGenerated^PlcGenerated Project^POUs");
ITcSmTreeItem newFb = plcPousItem.CreateChild("FB_TEST", 604, "", IECLANGUAGETYPES.IECLANGUAGE_ST);
ITcPlcPou fbPou = (ITcPlcPou)newFb;

Code snippet (Powershell):

$plcPousItem = $systemManager.LookupTreeItem("TIPC^PlcGenerated^PlcGenerated Project^POUs")
$newFb = $plcPousItem.CreateChild("FB_TEST", 604, "", 6)

In this example, the POU MAIN is being created in a PLC-Project. The object programPou references this POU and can now be used to access specific methods and properties of the POU by using the corresponding method/property of the ITcPlcPou interface.

Accessing the implementation / declaration area of a POU

You can also gain read/write access to either the implementation or declaration area of a POU, using the ITcPlcImplementation or ITcPlcDeclaration interfaces, as shown in the following example.

Code snippet (C#):

ITcPlcDeclaration fbPouDecl = (ITcPlcDeclaration) fbPou;
ITcPlcImplementation fbPouImpl = (ITcPlcImplementation) fbPou;
string decl = fbPouDecl.DeclarationText;
string impl = fbPouImpl.ImplementationText;
string implXml = fbPouImpl.ImplementationXml;

Code snippet (PowerShell):

$decl = $newFb.DeclarationText
$impl = $newFb.ImplementationText
$implXml = $newFb.ImplementationXml

When comparing the two interfaces, you will notice that the accessible properties differ in both interfaces. For example, the ITcPlcImplementation interface offers a "Language" property that ITcPlcDeclaration does not. The reason for this is that, according to IEC, the declaration area is not based on a real programming language (e.g. ST), so this property would not make sense if it were used in the declaration area.

Accessing Sub-POUs (Actions, Properties, ...)

POUs may have more sub-items like Methods, Transitions, Actions and Properties. It is important to understand that not every sub-item of a POU also has both an implementation and a declaration area. Actions and Transitions, for example, only have an implementation area. Therefore, casting to one of the interfaces mentioned above is only valid if the corresponding sub-object has this area. The following table gives an overview about which areas are available in the different types of POUs.

Tree Item

Type

Declaration Area

Implementation Area

Program

POU

Yes

Yes

Function

POU

Yes

Yes

Function Block

POU

Yes

Yes

Action

POU

No

Yes

Method

POU

Yes

Yes

Property (Get/Set)

POU

Yes

Yes

Transition

POU

No

Yes

Enum

DUT

Yes

No

Struct

DUT

Yes

No

Union

DUT

Yes

No

Alias

DUT

Yes

No

Interface

Interface

Yes

No

Property (Get/Set)

Interface

Yes

Yes

Global variables

GVL

Yes

No

Creating PLC objects

The creation of PLC objects is simple and can be carried out using the CreateChild() method of the ITcSmTreeItem interface. The parameters of this method must be interpreted differently depending on the POU type. In the following table you will find the information required to create different POU types. Please note that the vInfo parameter may be a string if more than one parameter is required. In [...] reference is made to each array position and whether it is optional or not.

Tree Item

Type

Parameter "nSubType"

Parameter "vInfo"

Program

POU

602

[0, optional]: IEC programming language, as defined by IECLANGUAGETYPES. ST (Structured Text) is used by default.
[1, optional]: Can be used for derivation (keywords "Extends" or "Implements"). If the keywords "Extends" AND "Implements" are to be used, the keyword "Extends" is specified in this field.
[2, optional]: Name of the interface or POU to be extended/implemented (mandatory if [1] is used). If the keywords "Extends" AND "Implements" are to be used, the library to be extended is specified in this field.
[3, optional]: If the keywords "Extends" AND "Implements" are to be used, the keyword "Implements" is specified in this field.
[4, optional]: If the keywords "Extends" AND "Implements" are to be used, the interface used for the derivation is specified in this field.

Function

POU

603

[0]: IEC programming language, as defined by IECLANGUAGETYPES.
[1]: Return type of the function. Can be a PLC data type, e.g. DINT, BOOL, …

Function block

POU

604

[0, optional]: IEC programming language, as defined by IECLANGUAGETYPES. ST (Structured Text) is used by default.
[1, optional]: Can be used for derivation (keywords "Extends" or "Implements"). If the keywords "Extends" AND "Implements" are to be used, the keyword "Extends" is specified in this field.
[2, optional]: Name of the interface or POU to be extended/implemented (mandatory if [1] is used). If the keywords "Extends" AND "Implements" are to be used, the library to be extended is specified in this field.
[3, optional]: If the keywords "Extends" AND "Implements" are to be used, the keyword "Implements" is specified in this field.
[4, optional]: If the keywords "Extends" AND "Implements" are to be used, the interface used for the derivation is specified in this field.

Action

POU

608

[0, optional]: IEC programming language, as defined by IECLANGUAGETYPES. ST (Structured Text) is used by default.
[1, optional]: Can contain PLCopen XML string with code for the action if necessary

Method

POU

609

[0, optional]: IEC programming language, as defined by IECLANGUAGETYPES. ST (Structured Text) is used by default.
[1, optional]: Return type
[2, optional]: Access specifier, e.g. PUBLIC. PUBLIC is used by default.
[3, optional]: May contain PLCopen XML string with code for the action if necessary

Property

POU

611

[0]: IEC programming language as defined by IECLANGUAGETYPES
[1]: Return type
[2, optional]: Access specifier, e.g. PUBLIC. PUBLIC is used by default.

Retrieve property

POU

613

[0, optional]: IEC programming language, as defined by IECLANGUAGETYPES. ST (Structured Text) is used by default.
[1, optional]: Access specifier, e.g. PUBLIC. PUBLIC is used by default.
[2, optional]: May contain PLCopen XML string with code for the action if necessary

Set property

POU

614

[0, optional]: IEC programming language, as defined by IECLANGUAGETYPES. ST (Structured Text) is used by default.
[1, optional]: Access specifier, e.g. PUBLIC. PUBLIC is used by default.
[2, optional]: May contain PLCopen XML string with code for the action if necessary

Transition

POU

616

[0, optional]: IEC programming language, as defined by IECLANGUAGETYPES. ST (Structured Text) is used by default.
[1, optional]: Can contain PLCopen XML string with code for the action if necessary

UML class diagram

POU

631

No vInfo parameter required, "Null" can be used.

Enum

DUT

605

[0, optional]: May contain declaration text if applicable

Struct

DUT

606

[0, optional]: May contain declaration text if applicable

Union

DUT

607

[0, optional]: May contain declaration text if applicable

Alias

DUT

623

[0, optional]: May contain declaration text if applicable

Interface

Interface

618

[0, optional]: Extend type

Property

Interface

612

[0]: Return type

Retrieve property

Interface

654

No vInfo parameter required, "Null" can be used.

Set property

Interface

655

No vInfo parameter required, "Null" can be used.

Method

Interface

610

[0]: Return type

Global variables

GVL

615

[0, optional]: May contain declaration text if applicable

PLC folder

Folder

601

No vInfo parameter required, "Null" can be used.

Parameter list

PL

629

[0, optional]: May contain declaration text if applicable

Visualization

Visualization

619

No vInfo parameter required, "Null" can be used.

Example: The following code snippet shows how the vInfo parameter can be used to create a function block "FB_Test", with the keywords "Extends" and/or "Implements", depending on the value of the Boolean variables bExtends and bImplements. The extended library is ADSRDSTATE and the implemented interface is ITcADI.

Code snippet (C#):

string[] vInfo;
bool bExtends = true;
bool bImplements = true;

if (bExtends && bImplements)
{
  vInfo= new string[5];
}
else
{
  if (bExtends || bImplements)
  {
    vInfo= new string[3];
  }
  else
  {
    vInfo= new string[1];
  }
}
vInfo[0] = language.AsString();
if (bExtends && bImplements)
{
  vInfo[1] = "Extends";
  vInfo[2] = "ADSRDSTATE";
  vInfo[3] = "Implements";
  vInfo[4] = "ITcADI";
}
else
{
  if (bExtends)
  {
    vInfo[1] = "Extends";
    vInfo[2] = "ADSRDSTATE";
  }
  else
  {
    if (bImplements)
    {
      vInfo[1] = "Implements";
      vInfo[2] = "ITcADI";
    }
  }
}

ITcSmTreeItem newPOU = parent.CreateChild("FB_Test", 604,
"", fbVInfo);
Accessing, creating and handling PLC POUs 1:

Please note

If the parameter vInfo only contains one value (marked with [0] in the table above), then you should not create an array of size 1, but simply a normal variable. Example: When using nSubType 618 (interface), you should use vInfo as follows.

Code snippet (C#):

ITcSmTreeItem interface1 = pou.CreateChild("NewInterface1", 618, "", null); // no expansion type
ITcSmTreeItem interface2 = pou.CreateChild("NewInterface2", 618, "", "ITcUnknown"); // expands ITcUnknown interface

PLC access modifier

The following access modifiers are valid and may be used as a vInfo parameter, as shown in the table above: PUBLIC, PRIVATE, PROTECTED, INTERNAL.

PLCopen XML import/export

You can also import/export PLC elements in PLCopen XML via the ITcPlcIECProject interface. Methods and properties of this interface can only be executed directly on a PLC project node, e.g.:

Code snippet (C#):

ITcSmTreeItem plcProject =
systemManager.LookupTreeItem("TIPC^PlcGenerated^PlcGenerated
Project");
ITcPlcIECProject importExport = (ITcPlcIECProject)
plcProject;
importexport.PlcOpenExport(plcOpenExportFile,
"MyPous.POUProgram;MyPous.POUFunctionBlock");
importExport.PlcOpenImport(plcOpenExportFile,
(int)PLCIMPORTOPTIONS.PLCIMPORTOPTIONS_NONE);

Code snippet (PowerShell):

$plcProject = $systemManager.LookupTreeItem("TIPC^PlcGenerated^PlcGenerated
Project")
$plcProject.PlcOpenExport(plcOpenExportFile, "MyPous.POUProgram;MyPous.POUFunctionBlock")
$plcProject.PlcOpenImport(plcOpenExportFile,0)

This code snippet assumes that a PLC project has already been added to the TwinCAT configuration, which is referenced via the plcProject object. This reference is converted into the object importexport of type ITcPlcIECProject, which is then used to export the POUs POUProgram and POUFunctionBlock (both are located in the PLC folder "MyPOUs") to an XML file and then import them again.

The available options for the import are: None (0), Rename (1), Replace (2), Skip (3)

Import existing POUs (templates)

PLC templates are available in two units: You can either use the complete PLC project as a whole or each POU individually as a template. The later is covered in this chapter. One of the reasons a developer may choose individual POUs as templates, is that it is easier to build a pool of existing functionalities and encapsulate them in separate POUs, e.g. different function blocks covering different sorting algorithms. Upon project creation, the developer simply chooses which functionality he needs in his TwinCAT project and accesses the template tool to retrieve the corresponding POU and import it to his PLC project.

Code snippet (C#):

ITcSmTreeItem plcProject = systemManager.LookupTreeItem("TIPC^PlcGenerated^PlcGenerated Project");
plcProject.CreateChild("NameOfImportedPOU", 58, null, pathToPouFile);
plcProject.CreateChild(null, 58, null, stringArrayWithPathsToPouFiles);

Code snippet (Powershell):

$plcProject = $systemManager.LookupTreeItem("TIPC^PlcGenerated^PlcGenerated Project")
$plcProject.CreateChild("NameOfImportedPOU", 58, $null, $pathToPouFile)
$plcProject.CreateChild($null, 58, $null, $stringArrayWithPathsToPouFiles)

Please note: A POU template file may not only be a .TcPou file but also the corresponding files for DUTs and/or GVLs. The example above demonstrates two common ways to import POU template files. The first is to import a single file, the second to import multiple files at once by storing the file paths to a string array and using this string array as the vInfo parameter of CreateChild().