Objektorientierte Programmierung in CoDeSys
Durch eine Erweiterung der IEC 61131-3 um neue Sprachmittel können Sie als Anwender Ihre CoDeSys- Applikation objektorientiert in den Sprachen der Norm programmieren. Dabei ist die objekt-orientierte Programmierung (OOP) eine Option, d.h. es wird Ihnen freigestellt, ob Sie objektorientiert oder wie bisher weiterhin funktional programmieren wollen. Sie können auch funktionale und objektorientierte Programmierung kombinieren.
Warum objektorientierte Programmierung in einem SPS-Programmiersystem?
Anwendungsbeispiel
Für die Realisierung einer Gebäudesteuerung möchten Sie den Code möglichst flexibel und modular
halten. Alle Räume im Gebäude haben zwei unterschiedliche Zustände: „OperationDaytime“ und
„OperationNighttime“, die zu einer festgelegten Zeit geschaltet werden. Diese Schaltung soll in
einem Manager-Baustein vorgenommen werden.
Die Räume selbst lassen sich in drei unterschiedlichen Typen
einteilen:
In allen Räumen muss mit dem Wechsel des Zustands das Licht ein- bzw. ausgeschaltet werden. Um diesen Schaltvorgang unabhängig vom Typ des Raums zu machen, verwenden wir die Objektorientierung und geben den Schaltvorgängen eine einheitliche Schnittstelle. Dazu bietet CoDeSys den Objekttyp „Interface“ als Schnittstellen-Definition mit Methoden, die dann in der eigentlichen Klasse ausprogrammiert wird.

D.h. im Funktionsbaustein RoomTyp 1, den wir anlegen und der damit zu einer Klasse wird, können wir jetzt die Interfaces für die Schaltvorgänge implementieren (Schlüsselwort IMPLEMENTS). Damit werden die im Interface angelegten Methoden sofort in die Klasse übernommen, wo wir sie klassen-spezifisch ausprogrammieren können. In diesem Beispiel schalten wir z.B. mit „OperationDaytime“ das Licht aus bzw. mit „OperationNighttime“ wieder an.

Um denselben Schaltvorgang für RoomTyp 2 vorzunehmen, der sich ja nur durch das zusätzliche Licht unterscheidet, können wir nun die Funktionalität von RoomTyp 1 erben, indem wir RoomTyp 2 um RoomTyp 1 erweitern. Dies geschieht mit dem Schlüsselwort „EXTENDS“. Durch die Vererbung ist die Funktionalität für „OperationDaytime“ und „OperationNighttime“ bereits vorhanden, d.h. wir müssen lediglich die Methode „SetLight“ überschreiben, und dann eben zwei statt nur einer Lampe schalten.
Und wieder vererben wir, wenn wir uns um RoomTyp 3 kümmern: Wir erweitern den Funktionsbaustein um RoomTyp 2 und haben damit sofort die überschriebene Funktion „SetLight“ zur Verfügung. Um noch die Temperatursteuerung einzubinden, implementieren wir in den Funktionsbaustein außerdem ein zusätzliches Interface „ITemp“. Damit bekommen wir sofort die erforderlichen Methoden in den Funktionsbaustein, die wir noch ausprogrammieren müssen. Nachdem „OperationDaytime“ und „OperationNighttime“ natürlich auch die Temperatursteuerung übernehmen sollen, müssen wir die geerbten Methoden in diesem Baustein überschreiben.

Damit haben wir die Steuerung der einzelnen Raumtypen fertig realisiert. Bei Steuerung des Gebäudes müssen wir jetzt nur noch festlegen, wie viele Räume das Gebäude hat und welcher Raum von welchem Typ ist. Das heißt, dass wir in einem Manager-Baustein ein Array über die Anzahl der Räume anlegen und pro Raum eine Instanz des entsprechenden RoomTyp hinterlegen:

Interessanterweise können wir jetzt das Array „Rooms“ mit einer Menge von Inhalten des Datentyps „IRoom“, also eines Interfaces, belegen. Im Array ist die Information darüber, welchen Typ jeder der einzelnen Räume hat, nicht mehr erforderlich, das wird erst zur Laufzeit je nach Instanziierung von r1 bis r8 entschieden. Aufgrund der Objektorientierung kann jetzt der Aufruf der Funktionen für die Tag- und Nachtsteuerung bequem in einer Schleife erfolgen.

Beim Aufruf werden jetzt lediglich die Methoden „OperationDaytime“ und „OperationNighttime“ aus dem Array aufgerufen, welches bei der Deklaration als Array eines Interfaces angelegt wurde. Um welchen Raumtyp es sich handelt, spielt hier keine Rolle mehr – die Information darüber wurde bei der Instanziierung der Basisklassen vorgenommen.
Im Online-Betrieb sehen wir die Variablenwerte im Deklarationsteil des Manager-Bausteins. Dabei haben natürlich die Instanzen r1..r8 eine andere Struktur, abhängig von der Instanziierung. Für den Aufruf von „OperationDaytime“ und „OperationNighttime“ spielt das aber keine Rolle.

Wenn wir jetzt die Anzahl der Räume oder deren Zuordnung ändern müssen, so ist das nur an einer zentralen Stelle, nämlich der Instanziierung, erforderlich. Der Manager-Baustein und die Schleife zur Abarbeitung werden überhaupt nicht mehr geändert. Sollten wir etwas bei der Implementierung der Schaltfunktionen in den Methoden der Funktionsbausteine RoomTyp 1, 2 oder 3 ändern müssen, so ist ebenfalls keine Anpassung des Manager-Bausteins erforderlich. Die Information über die Funktionen stecken in den einzelnen Objekten. Wenn wir das gesamte Projekt für ein anderes Gebäude wiederverwenden möchten, das zwar Räume mit identischer Funktionalität hat, aber ganz anders aufgebaut ist, müssen wir wiederum lediglich die Instanziierung und die Anzahl der Räume anpassen.
Definitionen von Begriffen, die wir in dem Beispiel bereits verwendet haben:
Ein Funktionsbaustein ist eine Klasse mit genau einer Methode. Mit der Erweiterung auf volle
Klassenfunktionalität können in einem Funktionsbaustein Methoden oder Interfaces mit deren Methoden
implementiert werden.
Methoden sind Routinen, die einem Funktionsbaustein bzw. einem
Interface fest zugeordnet sind. Sie arbeiten auf den Daten des Funktionsbausteins, können aber wie
IEC-Funktionen über Eingangs-, Ausgangs- und lokale Variablen verfügen.
Ein Interface
ist eine Schnittstellendefinition mit einem Satz an Methoden. Im Interface werden dabei
lediglich die erforderlichen Variablen der Methoden festgelegt. Der Rumpf der Methode wird erst in
der Klasse ausprogrammiert, in die das Interface implementiert wird.
Objekte sind
Instanzen von Funktionsbausteinen (Klassen).
Mit dem Schlüsselwort IMPLEMENTS
implementiert ein Funktionsbaustein ein Interface. Im Funktionsbaustein müssen somit alle
Methoden des Interfaces realisiert werden.
Ein Funktionsbaustein kann eine Klasse durch das
neue Schlüsselwort EXTENDS erweitern. Damit übernimmt (erbt) der Funktionsbaustein alle
Daten und Methoden der Klasse.
Beim Aufruf von Methoden über deren Interface wird erst zur
Laufzeit der Applikation entschieden, welche Implementierung der Methode tatsächlich ausgeführt
wird. Diese Funktionalität nennt sich Polymorphie.
Weitere Funktionen der OOP in CoDeSys:

Was suchen sie?
Produktübersicht



