Ein Beispielprogramm

Das Beispielprogramm soll zur Steuerung einer Mini-Ampelanlage mit zwei Autoampeln an einer Kreuzung dienen. Beide Ampeln werden sich in ihren rot/grün-Phasen abwechseln, und um Unfälle zu vermeiden, sollen zwischen den Phasen auch noch gelb bzw. gelb/rot-Umschaltphasen vorsehen werden. Letztere werden kürzer dauern als erstere. In diesem Beispiel werden Sie sehen, wie sich zeitabhängige Programme mit den Sprachmitteln der IEC61131-3 darstellen lassen, wie man mit Hilfe vom TwinCAT PLC Control die verschiedenen Sprachen der Norm editiert, und wie man sie problemlos verbinden kann.

Bausteine erzeugen

Starten Sie zunächst das TwinCAT PLC Control, und wählen Sie 'Datei' 'Neu'. Als Taskname wird Ihnen ‚Standard' vorgeschlagen. Den ersten Baustein sollten Sie PLC_PRG nennen. Für unseren Fall wählen wir als Sprache dieses Bausteins Ablaufsprache (AS). Erzeugen Sie nun zwei weitere Objekte mit dem Befehl 'Projekt' 'Objekt' 'einfügen' über die Menüleiste oder über das Kontextmenü (rechte Maustaste drücken im Object Organizer). Einen Funktionsblock in der Sprache Funktionsplan (FUP) namens AMPEL, sowie einen Baustein WARTEN, ebenfalls von dem Typ Funktionsblock, den wir als Anweisungsliste (AWL) programmieren wollen.
Im Baustein AMPEL werden wir die einzelnen Ampelphasen den Ampellichtern zuordnen, d.h. wir werden dafür sorgen, dass die rote Lampe bei der Phase rot und bei der Phase gelb/rot leuchtet, die gelbe Lampe bei der Phase gelb und gelb/rot, usw.
In WARTEN werden wir einen einfachen Timer programmieren, der als Eingabe die Dauer der Phase in Millisekunden bekommen wird, und der als Ausgabe TRUE liefert, sobald die Zeit abgelaufen ist.
PLC_PRG schließlich wird das alles miteinander verbinden, so dass das richtige Ampellicht zur richtigen Zeit, und mit der gewünschten Dauer leuchten wird.

Im Deklarationseditor deklarieren Sie als Eingabevariable (zwischen den Schlüsselwörtern VAR_INPUT und END_VAR) eine Variable namens STATUS vom Typ INT. STATUS wird fünf mögliche Zustände haben, nämlich jeweils einen für die Ampelphasen grün, gelb, gelb-rot, rot und aus. Ausgaben hat unsere Ampel dementsprechend vier, nämlich ROT, GELB, GRUEN (Umlaute werden für Variablen nicht akzeptiert) und AUS. Deklarieren Sie diese vier Variablen; dann sieht der Deklarationsteil des Funktionsblocks AMPEL folgendermaßen aus:

Ein Beispielprogramm 1:

Funktionsblock AMPEL, Deklarationsteil

Nun gilt es, aus der Eingabe STATUS des Bausteins die Werte der Ausgabevariablen zu ermitteln. Gehen Sie dazu in den Rumpf des Bausteins. Klicken Sie in das Feld links neben dem ersten Netzwerk (das graue Feld mit der Nummer 1). Sie haben jetzt das erste Netzwerk selektiert. Wählen Sie nun den Menüpunkt 'Einfügen' 'Operator'. Es wird im ersten Netzwerk eine Box mit dem Operator AND und zwei Eingängen eingefügt:

Ein Beispielprogramm 2:

Klicken Sie auf den Text AND mit dem Mauszeiger und ändern Sie den Text in EQ. Selektieren Sie die drei Fragezeichen vom oberen der beiden Eingänge und tragen Sie die Variable STATUS ein. Anschließend selektieren Sie die unteren drei Fragezeichen und überschreiben ihn mit einer 1. Sie erhalten folgendes Netzwerk:

Ein Beispielprogramm 3:

Klicken Sie nun an eine Stelle hinter der EQ Box. Es wird nun der Ausgang der EQ-Operation selektiert. Wählen Sie 'Einfügen' 'Zuweisung'. Die drei Fragezeichen ??? ändern Sie in GRUEN. Sie haben nun ein Netzwerk der folgenden Gestalt erstellt:

Ein Beispielprogramm 4:

STATUS wird mit 1 verglichen, das Ergebnis wird GRUEN zugewiesen. Dieses Netzwerk schaltet also auf GRUEN, wenn der vorgegebene Statuswert 1 ist. Für die anderen Ampelfarben bzw. für AUS benötigen wir drei weitere Netzwerke. Sie erzeugen diese durch den Befehl 'Einfügen' 'Netzwerk (danach)'. Diese Netzwerke sollten Sie wie im Beispiel einrichten. Daraus ergibt sich der fertige Baustein:

Ein Beispielprogramm 5:

Um vor einem Operator einen weiteren Operator einzufügen, müssen Sie die Stelle selektieren, wo der Eingang, an den Sie den Operator anhängen wollen, in die Box mündet. Anschließend führen Sie ein 'Einfügen' 'Operator' aus. Ansonsten können Sie beim Erstellen dieser Netzwerke ebenso vorgehen wie beim ersten Netzwerk. Nun ist unser erster Baustein bereits fertig. AMPEL steuert uns, je nach Eingabe des Wertes STATUS, die jeweils gewünschte Ampelfarbe.

Für den Timer im Baustein WARTEN benötigen wir einen Baustein aus der Standardbibliothek. Öffnen Sie also den Bibliotheksverwalter mit 'Fenster' 'Bibliotheksverwaltung'. Wählen Sie 'Einfügen' 'Weitere Bibliothek'. Der Dialog zum Öffnen von Dateien erscheint. Aus der Liste der Bibliotheken wählen Sie standard.lib.

Gehen wir nun zum Baustein WARTEN. Dieser soll ein Timer werden, mit dem wir die Länge jeder Ampelphase angeben können. Unser Baustein erhält als Eingabevariable eine Variable ZEIT vom Typ TIME, und als Ausgabe liefert er einen boolschen Wert, den wir OK nennen wollen, und der TRUE sein soll, wenn die gewünschte Zeit abgelaufen ist. Diesen Wert besetzen wir mit FALSE vor, indem wir an das Ende der Deklaration (aber vor dem Strichpunkt)" := FALSE " einfügen. Für unsere Zwecke benötigen wir den Baustein TP, einen Pulsgeber. Dieser hat zwei Eingänge (IN, PT) und zwei Ausgänge (Q, ET). TP macht nun folgendes: Solange IN FALSE ist, ist ET 0 und Q FALSE. Sobald IN den Wert TRUE liefert, wird im Ausgang ET die Zeit in Millisekunden hochgezählt. Wenn ET den Wert PT erreicht, wird ET nicht mehr weitergezählt. Q liefert unterdessen solange TRUE, solange ET kleiner als PT ist. Sobald der Wert PT erreicht ist, liefert Q wieder FALSE. Übrigens: eine Kurzbeschreibung aller Bausteine aus der Standardbibliothek finden Sie im Anhang. Um den Baustein TP im Baustein WARTEN verwenden zu können, müssen wir von TP eine lokale Instanz anlegen. Dazu deklarieren wir uns eine lokale Variable ZAB (für Zeit abgelaufen) vom Typ TP (zwischen den Schlüsselwörtern VAR, END_VAR). Der Deklarationsteil von WARTEN sieht somit wie folgt aus:

Ein Beispielprogramm 6:

Funktionsblock WARTEN, Deklarationsteil

Um den gewünschten Timer zu realisieren, muss der Rumpf des Bausteins wie folgt ausprogrammiert werden:

Ein Beispielprogramm 7:

Funktionsblock WARTEN, Anweisungsteil

Zunächst wird abgefragt, ob Q bereits auf TRUE gesetzt ist (ob also bereits gezählt wird), in diesem Fall ändern wir nichts an der Belegung von ZAB, sondern rufen den Funktionsblock ZAB ohne Eingabe auf (um zu prüfen, ob die Zeit bereits abgelaufen ist). Andernfalls setzen wir die Variable IN in ZAB auf FALSE, und damit gleichzeitig ET auf 0 und Q auf FALSE. So sind alle Variablen auf den gewünschten Anfangszustand gesetzt. Nun speichern wir die benötigte Zeit aus der Variablen ZEIT in der Variablen PT, und rufen ZAB mit IN:=TRUE auf. Im Funktionsblock ZAB wird nun die Variable ET hochgezählt bis sie den Wert ZEIT erreicht, dann wird Q auf FALSE gesetzt. Der negierte Wert von Q wird nach jedem Durchlauf von WARTEN in OK gespeichert. Sobald Q FALSE ist, liefert also OK TRUE. Der Timer ist hiermit fertig.

Nun gilt es, unsere beiden Funktionsblöcke WARTEN und AMPEL im Hauptprogramm PLC_PRG zusammenzubringen. Zunächst deklarieren wir die Variablen, die wir brauchen. Das sind zwei Instanzen des Funktionsblocks AMPEL (AMPEL1, AMPEL2) und eine vom Typ WARTEN (VERZ wie Verzögerung). PLC_PRG sieht nun folgendermaßen aus:

Ein Beispielprogramm 8:

Programm PLC_PRG, erste Ausbaustufe, Deklarationsteil

Das Anfangsdiagramm eines Bausteins in AS besteht stets aus einer Aktion "Init" einer nachfolgenden Transition "Trans0" und einem Sprung zurück zu Init. Wir sollten das etwas erweitern. Legen wir zunächst die Struktur des Diagramms fest, bevor wir die einzelnen Aktionen und Transitionen programmieren. Zuerst benötigen wir für jede Ampelphase einen Schritt. Fügen Sie diesen ein, indem Sie Trans0 markieren, und 'Einfügen' 'Schritt-Transition (danach)' wählen. Wiederholen Sie diesen Vorgang noch dreimal. Wenn Sie direkt auf den Namen einer Transition oder eines Schrittes klicken, dann wird dieser markiert, und Sie können ihn verändern. Nennen Sie die erste Transition nach Init "TRUE", alle anderen Transitionen "VERZ.OK". Die erste Transition schaltet also immer durch, alle anderen dann, wenn VERZ in OK TRUE ausgibt, also wenn die eingegebene Zeit abgelaufen ist. Die Schritte erhalten (von oben nach unten) die Namen Schalt1, Gruen2, Schalt2, Gruen1, wobei Init seinen Namen natürlich behält. "Schalt" soll jedes Mal eine Gelbphase bedeuten, bei Gruen1 wird AMPEL1 bei Gruen2 AMPEL2 grün sein. Ändern Sie zuletzt noch die Rücksprungadresse von Init nach Schalt1. Wenn Sie alles richtig gemacht haben, dann müsste das Diagramm nun folgendermaßen aussehen:

Ein Beispielprogramm 9:

Programm PLC_PRG, erste Ausbaustufe, Anweisungsteil

Nun müssen wir die einzelnen Schritte ausprogrammieren. Wenn Sie auf dem Feld eines Schrittes einen Doppelklick ausführen, öffnen Sie einen Dialog zum Öffnen einer neuen Aktion. In unserem Fall werden wir als Sprache jeweils AWL (Anweisungsliste) verwenden.

Aktionen und Transitionsbedingungen

In der Aktion zum Schritt Init werden die Variablen initialisiert, der STATUS von AMPEL1 soll 1 (grün) sein. Der Status von AMPEL2 soll 3 (rot) sein. Die Aktion Init sieht dann so aus:

Ein Beispielprogramm 10:

Aktion Init

Bei Schalt1 wechselt der STATUS von AMPEL1 auf 2 (gelb), der von AMPEL2 auf 4 (gelb-rot). Außerdem wird nun eine Verzögerungszeit von 2000 Millisekunden festgelegt. Die Aktion sieht nun wie folgt aus:

Ein Beispielprogramm 11:

Aktion Schalt1

Bei Gruen2 ist AMPEL1 rot (STATUS:=3), AMPEL2 grün (STATUS:=1), und die Verzögerungszeit ist auf 5000 Millisekunden gesetzt.

Ein Beispielprogramm 12:

Aktion Gruen2

Bei Schalt2 wechselt der STATUS von AMPEL1 auf 4 (gelb-rot), der von AMPEL2 auf 2 (gelb). Es wird nun eine Verzögerungszeit von 2000 Millisekunden festgelegt.

Ein Beispielprogramm 13:

Aktion Schalt2

Bei Gruen1 ist AMPEL1 grün (STATUS:=1), AMPEL2 rot (STATUS:=3), und die Verzögerungszeit wird auf 5000 Millisekunden eingestellt.

Ein Beispielprogramm 14:

Aktion Gruen1

Damit ist die erste Ausbauphase unseres Programms beendet. Sie können es nun übersetzen und auch in der Simulation testen.

Damit sich in unserem Diagramm wenigstens eine Alternativverzweigung befindet, und damit wir unsere Ampelanlage nachts abstellen können, bauen wir in unser Programm nun einen Zähler ein, der nach einer bestimmten Zahl von Ampelzyklen die Anlage abstellt. Zunächst brauchen wir also eine neue Variable ZAEHLER vom Typ INT. Deklarieren Sie diese wie gehabt im Deklarationsteil von PLC_PRG, und initialisieren Sie sie in Init mit 0.

Ein Beispielprogramm 15:

Aktion Init, zweite Fassung

Markieren Sie nun die Transition nach Schalt1 und fügen Sie einen Schritt und eine Transition danach ein. Markieren Sie die neu entstandene Transition und fügen Sie eine Alternativverzweigung links davon ein. Fügen Sie nach der linken Transition einen Schritt und eine Transition ein. Fügen Sie nach der nun neu entstandenen Transition einen Sprung nach Schalt1 ein. Wählen Sie die Transition unterhalb des ersten neuen Schrittes aus. Öffnen Sie das Kontextmenü und wählen Sie "Zoom Aktion/Transition" aus. Als Sprache für die Transition wählen Sie bitte AWL. Benennen Sie die neu entstandenen Teile wie folgt: Der obere der beiden neuen Schritte soll "Zählen" heißen, der untere "Aus". Die Transitionen heißen (von oben nach unten und von links nach rechts) BEENDEN, TRUE und VERZ.OK. Der neu entstandene Teil sollte also so aussehen wie der hier schwarz umrandete Teil:

Ein Beispielprogramm 16:

Ampelanlage

Es gibt also zwei neue Aktionen und eine neue Transitionsbedingung zu implementieren. Beim Schritt Zaehlen geschieht nichts anderes, als dass ZAEHLER um eins erhöht wird:
Ein Beispielprogramm 17:

Die Transition BEENDEN überprüft, ob der Zähler größer als eine bestimmte Zahl ist, sagen wir mal 7:

Ein Beispielprogramm 18:

Bei Aus wird der Status beider Ampeln auf 5 (AUS) gesetzt, der ZAEHLER wird auf 0 zurückgesetzt, und eine Verzögerungszeit von 10 Sekunden festgelegt:

Ein Beispielprogramm 19:

In unserer Ampelstadt wird es also nach sieben Ampelzyklen Nacht, für zehn Sekunden schaltet die Ampel sich aus, dann wird es wieder Tag, die Ampelanlage schaltet sich wieder ein, und das ganze geht wieder von vorn los.

Testen Sie nun Ihr Programm. Dazu müssen Sie es übersetzen ('Projekt' 'Alles übersetzen') und laden ('Online' 'Einloggen' und dann 'Online' 'Laden'). Wenn Sie nun 'Online' 'Start' ausführen, können Sie die zeitliche Abfolge der einzelnen Schritte ihres Hauptprogramms verfolgen. Das Fenster des Bausteins PLC_PRG hat sich nunmehr zum Monitor Fenster gewandelt. Mit Doppelklick auf das Pluszeichen im Deklarationseditor klappt die Variablendarstellung auf und Sie können die Werte der einzelnen Variablen beobachten.