Zugriff, Erstellung und Umgang mit SPS-POUs

In diesem Kapitel wird ausführlich beschrieben, wie auf SPS-Objekte, z.B. POUs, Methoden, Transitionen, Eigenschaften und auf deren entsprechenden Implementierungs- und Deklarationsbereiche für die Handhabung von SPS-Code zugegriffen werden kann. Auch der Import/Export von SPS-Objekten in PLCopen XML wird behandelt. Die folgende Liste enthält alle Kapitel dieses Artikels:

Allgemeine Informationen über SPS-Objekte

Auch wenn jedes Tree Item als vom Typ ITcSmTreeItem betrachtet wird, müssen bestimmte Elemente in eine speziellere Schnittstelle umgewandelt werden, damit der Zugriff auf alle ihre Methoden und Eigenschaften möglich wird, zum Beispiel POUs, die in die Schnittstelle ITcPlcPou umgewandelt werden müssen, um Zugang zu deren einmaligen Methoden und Eigenschaften zu erlangen.

Code-Ausschnitt (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-Ausschnitt (Powershell):

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

In diesem Beispiel wird die POU MAIN im SPS-Projekt erzeugt. Das Objekt programPou referenziert diese POU und kann nun dazu verwendet werden, um auf spezifische Methoden und Eigenschaften der POU mit Hilfe der entsprechenden Methode/Eigenschaft der ITcPlcPou-Schnittstelle zuzugreifen.

Zugriff auf Implementierungs- / Deklarationsbereich einer POU

Sie können auch Lese-/Schreibzugriff auf entweder den Implementierungs- oder den Deklarationsbereich einer POU erlangen, mit Hilfe der Schnittstellen ITcPlcImplementation oder ITcPlcDeclaration, wie im folgenden Beispiel gezeigt.

Code-Ausschnitt (C#):

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

Code-Ausschnitt (Powershell):

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

Beim Vergleichen der beiden Schnittstellen werden Sie feststellen, dass sich die zugänglichen Eigenschaften in beiden Schnittstellen voneinander unterscheiden. So bietet z.B. die ITcPlcImplementation-Schnittstelle eine Eigenschaft "Sprache", welche ITcPlcDeclaration nicht bietet. Der Grund hierfür ist, dass gemäß IEC der Deklarationsbereich nicht auf eine reale Programmiersprache basiert (z.B. ST), so dass diese Eigenschaft keinen Sinn ergäbe, wenn sie im Deklarationsbereich verwendet würde.

Auf Sub-POUs (Aktionen, Eigenschaften, ...) zugreifen

POUs können mehrere Unterelemente haben, wie Methoden, Transitionen, Aktionen und Eigenschaften. Es ist wichtig zu verstehen, dass nicht jedes Unterelement einer POU auch beides, einen Implementierungs- und einen Deklarationsbereich, aufweist. Aktionen und Transitionen z.B. haben nur einen Implementierungsbereich. Demzufolge ist die Umwandlung in eine dieser erwähnten Schnittstellen nur gültig, wenn das entsprechende Unterobjekt diesen Bereich aufweist. Die folgende Tabelle gibt einen Überblick darüber, welche Bereiche in den verschiedenen POU-Typen verfügbar sind.

Tree item

Typ

Deklarationsbereich

Implementierungsbereich

Programm

POU

Ja

Ja

Funktion

POU

Ja

Ja

Funktionsbaustein

POU

Ja

Ja

Aktion

POU

Nein

Ja

Methode

POU

Ja

Ja

Eigenschaft (Abrufen/Setzen)

POU

Ja

Ja

Transition

POU

Nein

Ja

Enum

DUT

Ja

Nein

Struct

DUT

Ja

Nein

Union

DUT

Ja

Nein

Alias

DUT

Ja

Nein

Schnittstelle

Schnittstelle

Ja

Nein

Eigenschaft (Abrufen/Setzen)

Schnittstelle

Ja

Ja

Globale Variablen

GVL

Ja

Nein

SPS-Objekte erstellen

Die Erstellung von SPS-Objekten ist einfach und kann mit der Methode CreateChild() der ITcSmTreeItem-Schnittstelle vorgenommen werden. Die Parameter dieser Methode müssen je nach POU-Typ unterschiedlich interpretiert werden. In der folgenden Tabelle finden Sie die notwendigen Informationen, um unterschiedliche POU-Typen zu erstellen. Achten Sie darauf, dass der vInfo-Parameter gegebenenfalls eine Zeichenkette ist, wenn mehr als ein Parameter benötigt wird. In [...] wird auf jede Arrayposition verwiesen, und darauf, ob sie optional ist oder nicht.

Tree Item

Typ

Parameter "nSubType"

Parameter "vInfo"

Programm

POU

602

[0, optional]: IEC-Programmiersprache, wie durch IECLANGUAGETYPES definiert. ST (Strukturierter Text) wird standardmäßig verwendet.
[1, optional]: Kann zur Ableitung verwendet werden (Schlüsselwörter “Extends" oder "Implements"). Wenn die Schlüsselwörter "Extends" UND "Implements" verwendet werden sollen, wird in diesem Feld das Schlüsselwort "Extends" spezifiziert.
[2, optional]: Name der Schnittstelle oder POU, die zu erweitern/implementieren ist (obligatorisch, wenn [1] verwendet wird). Wenn die Schlüsselwörter "Extends" UND "Implements" verwendet werden sollen, wird in diesem Feld die zu erweiternde Bibliothek spezifiziert.
[3, optional]: Wenn die Schlüsselwörter "Extends" UND "Implements" verwendet werden sollen, wird in diesem Feld das Schlüsselwort "Implements" spezifiziert.
[4, optional]: Wenn die Schlüsselwörter "Extends" UND "Implements" verwendet werden sollen, wird in diesem Feld die Schnittstelle spezifiziert, die für die Ableitung verwendet wird.

Funktion

POU

603

[0]: IEC-Programmiersprache, wie durch IECLANGUAGETYPES definiert.
[1]: Rückgabetyp der Funktion. Kann ein SPS-Datentyp sein, z.B. DINT, BOOL, ...

Funktionsbaustein

POU

604

[0, optional]: IEC-Programmiersprache, wie durch IECLANGUAGETYPES definiert. ST (Strukturierter Text) wird standardmäßig verwendet.
[1, optional]: Kann zur Ableitung verwendet werden (Schlüsselwörter “Extends" oder "Implements"). Wenn die Schlüsselwörter "Extends" UND "Implements" verwendet werden sollen, wird in diesem Feld das Schlüsselwort "Extends" spezifiziert.
[2, optional]: Name der Schnittstelle oder POU, die zu erweitern/implementieren ist (obligatorisch, wenn [1] verwendet wird). Wenn die Schlüsselwörter "Extends" UND "Implements" verwendet werden sollen, wird in diesem Feld die zu erweiternde Bibliothek spezifiziert.
[3, optional]: Wenn die Schlüsselwörter "Extends" UND "Implements" verwendet werden sollen, wird in diesem Feld das Schlüsselwort "Implements" spezifiziert.
[4, optional]: Wenn die Schlüsselwörter "Extends" UND "Implements" verwendet werden sollen, wird in diesem Feld die Schnittstelle spezifiziert, die für die Ableitung verwendet wird.

Aktion

POU

608

[0, optional]: IEC-Programmiersprache, wie durch IECLANGUAGETYPES definiert. ST (Strukturierter Text) wird standardmäßig verwendet.
[1, optional]: Kann gegebenenfalls PLCopen XML-Zeichenkette mit Code für die Aktion beinhalten

Methode

POU

609

[0, optional]: IEC-Programmiersprache, wie durch IECLANGUAGETYPES definiert. ST (Strukturierter Text) wird standardmäßig verwendet.
[1, optional]: Rückgabetyp
[2, optional]: Zugriffsbezeichner, z.B. PUBLIC. PUBLIC wird standardmäßig verwendet.
[3, optional]: Kann gegebenenfalls PLCopen XML-Zeichenkette mit Code für die Aktion beinhalten

Eigenschaft

POU

611

[0]: IEC-Programmiersprache, wie durch IECLANGUAGETYPES definiert
[1]: Rückgabetyp
[2, optional]: Zugriffsbezeichner, z.B. PUBLIC. PUBLIC wird standardmäßig verwendet.

Eigenschaft Abrufen

POU

613

[0, optional]: IEC-Programmiersprache, wie durch IECLANGUAGETYPES definiert. ST (Strukturierter Text) wird standardmäßig verwendet.
[1, optional]: Zugriffsbezeichner, z.B. PUBLIC. PUBLIC wird standardmäßig verwendet.
[2, optional]: Kann gegebenenfalls PLCopen XML-Zeichenkette mit Code für die Aktion beinhalten

Eigenschaft Setzen

POU

614

[0, optional]: IEC-Programmiersprache, wie durch IECLANGUAGETYPES definiert. ST (Strukturierter Text) wird standardmäßig verwendet.
[1, optional]: Zugriffsbezeichner, z.B. PUBLIC. PUBLIC wird standardmäßig verwendet.
[2, optional]: Kann gegebenenfalls PLCopen XML-Zeichenkette mit Code für die Aktion beinhalten

Transition

POU

616

[0, optional]: IEC-Programmiersprache, wie durch IECLANGUAGETYPES definiert. ST (Strukturierter Text) wird standardmäßig verwendet.
[1, optional]: Kann gegebenenfalls PLCopen XML-Zeichenkette mit Code für die Aktion beinhalten

Enum

DUT

605

[0, optional]: Kann gegebenenfalls Deklarationstext beinhalten

Struct

DUT

606

[0, optional]: Kann gegebenenfalls Deklarationstext beinhalten

Union

DUT

607

[0, optional]: Kann gegebenenfalls Deklarationstext beinhalten

Alias

DUT

623

[0, optional]: Kann gegebenenfalls Deklarationstext beinhalten

Schnittstelle

Schnittstelle

618

[0, optional]: Typ erweitern

Eigenschaft

Schnittstelle

612

[0]: Rückgabetyp

Eigenschaft Abrufen

Schnittstelle

654

Kein vInfo-Parameter erforderlich, "Null" kann verwendet werden.

Eigenschaft Setzen

Schnittstelle

655

Kein vInfo-Parameter erforderlich, "Null" kann verwendet werden.

Methode

Schnittstelle

610

[0]: Rückgabetyp

Globale Variablen

GVL

615

[0, optional]: Kann gegebenenfalls Deklarationstext beinhalten

SPS-Ordner

Ordner

601

Kein vInfo-Parameter erforderlich, "Null" kann verwendet werden.

Parameterliste

PL

629

[0, optional]: Kann gegebenenfalls Deklarationstext beinhalten

UML Klassendiagramm

POU

631

---

Beispiel: Der folgende Code-Ausschnitt zeigt, wie der vInfo-Parameter für die Erstellung eines Funktionsbausteins "FB_Test" verwendet werden kann, mit den Schlüsselwörtern “extends” und/oder “implements”, in Abhängigkeit des Werts der booleschen Variablen bExtends und bImplements. Die erweiterte Bibliothek ist ADSRDSTATE und die implementierte Schnittstelle ist ITcADI.

Code-Ausschnitt (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);
Zugriff, Erstellung und Umgang mit SPS-POUs 1:

Bitte beachten

Wenn der Parameter vInfo nur einen Wert beinhaltet (mit [0] in Tabelle oben gekennzeichnet), dann sollten Sie kein Array der Größe 1, sondern einfach eine normale Variable erstellen. Beispiel: Bei der Verwendung von nSubType 618 (Schnittstelle) sollten Sie vInfo folgendermaßen verwenden.

Code-Ausschnitt (C#):

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

SPS-Zugriffsbezeichner

Die folgenden Zugriffsbezeichner sind gültig und können als vInfo-Parameter verwendet werden, wie oben in der Tabelle gezeigt: PUBLIC, PRIVATE, PROTECTED, INTERNAL.

PLCopen XML Import/Export

Sie können auch SPS-Elemente in PLCopen XML über die ITcPlcIECProject-Schnittstelle importieren/exportieren. Methoden und Eigenschaften dieser Schnittstelle können nur direkt auf einen SPS-Projektknoten ausgeführt werden, z.B.:

Code-Ausschnitt (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-Ausschnitt (Powershell):

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

Dieser Code-Ausschnitt setzt voraus, dass bereits der TwinCAT-Konfiguration ein SPS-Projekt hinzugefügt wurde, das über das Objekt plcProject referenziert wird. Diese Referenz wird in das Objekt importexport vom Typ ITcPlcIECProject umgewandelt, welches dann für den Export der POUs POUProgram und POUFunctionBlock (beide befinden sich im SPS-Ordner "MyPOUs") in eine XML-Datei und deren anschließenden erneuten Import verwendet wird.

Die verfügbaren Optionen für den Import sind: Kein (0), Umbenennen (1), Ersetzen (2), Überspringen (3)

Bestehende POUs (Vorlagen) importieren

SPS-Vorlagen sind auf zwei Arten verfügbar: Sie können entweder das komplette SPS-Projekt als Ganzes verwenden oder jede POU einzeln als Vorlage. Das Letztere wird in diesem Kapitel behandelt. Einer der Gründe dafür, warum sich ein Entwickler für einzelne POUs als Vorlagen entscheiden kann, besteht darin, dass es einfacher ist, einen Pool von bestehenden Funktionalitäten aufzubauen und in separaten POUs zusammenzufassen, z. B. verschiedene Funktionsblöcke, die verschiedene Sortieralgorithmen abdecken. Bei der Projekterstellung wählt der Entwickler einfach die Funktionalität aus, die er in seinem TwinCAT-Projekt benötigt und greift auf das Vorlagetool zu, um die entsprechende POU abzurufen und diese in das SPS-Projekt zu importieren.

Code-Ausschnitt (C#):

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

Code-Ausschnitt (Powershell):

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

Bitte beachten: Die POU Vorlagedatei kann nicht nur eine .TcPou Datei sein, sondern auch die entsprechenden Dateien für DUTs und/oder GVLs. Das vorstehende Beispiel gibt zwei übliche Wege wieder, um POU Vorlagedateien zu importieren. Der erste besteht darin, eine einzige Datei zu importieren, der zweite, mehrere Dateien auf einmal zu importieren, indem die Dateipfade in einem String-Array gespeichert werden und dieses String-Array als vInfo Parameter von CreateChild() verwendet wird.