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 get read/write access to either the implementation or declaration area of a POU by using the interfaces ITcPlcImplementation or ITcPlcDeclaration, as the following example shows.

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 both interfaces, you will notice that the accessible properties in both interfaces differ from each other. For example the ITcPlcImplementation interface offers a property "Language" whereas ITcPlcDeclaration doesn't. This is because, according to IEC, the declaration area is not based on a real programming language (e.g. ST), therefore this property does not make sense when used on a 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 achieved via the CreateChild() method of the ITcSmTreeItem interface. Depending on the type of POU, the parameters of this method need to be interpreted differently. The following table gives the necessary information to be able to create different POU types. Please note that the vInfo parameter may be a string array, if more than one parameter is needed. Each array position and whether it is optional or not, is marked as [...] below.

Tree Item

Type

Parameter "nSubType"

Parameter "vInfo"

Program

POU

602

[0, optional]: IEC programming language, as definied by IECLANGUAGETYPES. By default, ST (Structured Text) is used.
[1, optional]: May be used for derivation (keywords "Extends" or "Implements"). If keywords "Extends" AND "Implements" should be used, this field specifies the keyword "Extends".
[2, optional]: Interface or POU name which should be extended/implemented (mandatory, if [1] is used). If keywords "Extends" AND "Implements" should be used, this field specifies the library to extend..
[3, optional]: If keywords "Extends" AND "Implements" should be used, this field specifies the keyword "Implements".
[4, optional]: If keywords "Extends" AND "Implements" should be used, this field specifies the interface used for derivation.

Function

POU

603

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

Function Block

POU

604

[0, optional]: IEC programming language, as definied by IECLANGUAGETYPES. By default, ST (Structured Text) is used.
[1, optional]: May be used for derivation (keywords "Extends" or "Implements"). If keywords "Extends" AND "Implements" should be used, this field specifies the keyword "Extends".
[2, optional]: Interface or POU name which should be extended/implemented (mandatory, if [1] is used). If keywords "Extends" AND "Implements" should be used, this field specifies the library to extend..
[3, optional]: If keywords "Extends" AND "Implements" should be used, this field specifies the keyword "Implements".
[4, optional]: If keywords "Extends" AND "Implements" should be used, this field specifies the interface used for derivation.

Action

POU

608

[0, optional]: IEC programming language, as definied by IECLANGUAGETYPES. By default, ST (Structured Text) is used.
[1, optional]: May contain PLCopen XML string with code for Action

Method

POU

609

[0, optional]: IEC programming language, as definied by IECLANGUAGETYPES. By default, ST (Structured Text) is used.
[1, optional]: Return data type
[2, optional]: Access modfier, e.g. PUBLIC. By default, PUBLIC is used.
[3, optional]: May contain PLCopen XML string with code for Action

Property

POU

611

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

Property Get

POU

613

[0, optional]: IEC programming language, as definied by IECLANGUAGETYPES. By default, ST (Structured Text) is used.
[1, optional]: Access modifier, e.g. PUBLIC. By default, PUBLIC is used.
[2, optional]: May contain PLCopen XML string with code for Action

Property Set

POU

614

[0, optional]: IEC programming language, as definied by IECLANGUAGETYPES. By default, ST (Structured Text) is used.
[1, optional]: Access modifier, e.g. PUBLIC. By default, PUBLIC is used.
[2, optional]: May contain PLCopen XML string with code for Action

Transition

POU

616

[0, optional]: IEC programming language, as definied by IECLANGUAGETYPES. By default, ST (Structured Text) is used.
[1, optional]: May contain PLCopen XML string with code for Action

Enum

DUT

605

[0, optional]: May contain declaration text

Struct

DUT

606

[0, optional]: May contain declaration text

Union

DUT

607

[0, optional]: May contain declaration text

Alias

DUT

623

[0, optional]: May contain declaration text

Interface

Interface

618

[0, optional]: Extending type

Property

Interface

612

[0]: Return data type

Property Get

Interface

654

No vInfo parameter is needed and "null" can be used.

Property Set

Interface

655

No vInfo parameter is needed and "null" can be used.

Method

Interface

610

[0]: Return data type

Global variables

GVL

615

[0, optional]: May contain declaration text

PLC Folder

Folder

601

No vInfo parameter is needed and "null" can be used.

Parameter List

PL

629

[0, optional]: May contain declaration text

UML Class Diagram

POU

631

---

Example: The following code snippet shows how to use the vInfo parameter to create a Functionblock "FB_Test" with the keywords extends and/or implements, depending on the value of the bool variables bExtends and bImplements. The extended library is ADSRDSTATE and the implemented interface 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 paramerter vInfo includes only one value (marked as [0] in the table above), you shouldn't create an array of size 1, instead just use a regular 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.

Importing / Exporting PLCopen XML

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

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 there is already a PLC project added to the TwinCAT configuration, which will be referenced via the object plcProject. This reference is casted to the object importexport of type ITcPlcIECProject, which is then used to export the POUs POUProgram and POUFunctionBlock (both reside in the PLC folder "MyPOUs") into an XML file and then import them again.

The available options for 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().