SPS-Programmierung #09: ENUM (Aufzählungsdatentyp) — Transcript

Dieses Video erklärt die Verwendung von ENUMs in der SPS-Programmierung anhand eines Ampelfarben-Beispiels und zeigt Best Practices.

Key Takeaways

  • ENUMs erleichtern die Verwaltung von Zuständen in SPS-Programmen durch benannte Aufzählungen.
  • Die eindeutige ID jedes ENUM-Elements ermöglicht einfache Auswertung in Case-Statements.
  • Qualified_Only verhindert Namenskonflikte und sorgt für klaren Geltungsbereich bei ENUM-Elementen.
  • Manuelle Zuweisung von IDs ist möglich, aber meist nicht notwendig.
  • ENUM-Variablen sollten nicht wie normale Integer behandelt werden, um Fehler zu vermeiden.

Summary

  • ENUM ist ein benutzerdefinierter Aufzählungsdatentyp, der eine Liste von benannten Werten definiert.
  • Beispielhafte Verwendung eines ENUMs mit Ampelfarben: rot, rot-gelb, grün, gelb.
  • Jedes Element im ENUM hat eine eindeutige Integer-ID, die manuell oder automatisch vergeben werden kann.
  • ENUMs werden in SPS-Programmen genutzt, um Zustände einer Steuerung übersichtlich und sicher abzubilden.
  • Deklaration von ENUMs erfolgt im Ordner DUT (Data Unit Types) mit Type, Name, Elementen und End_Type.
  • ENUM-Elemente können in Case-Statements ausgewertet werden, da sie intern Integer-Werte sind.
  • Probleme können auftreten, wenn lokale Variablen dieselben Bezeichner wie ENUM-Elemente haben; Lösung ist die Verwendung des Geltungsbereichs (Qualified_Only).
  • Das Attribut Qualified_Only erzwingt die Verwendung des Geltungsbereichs bei ENUM-Elementen und verbessert die Lesbarkeit und Sicherheit.
  • ENUM-Variablen können intern wie Integer behandelt werden, was zu unerwarteten Werten führen kann, wenn Werte außerhalb der definierten ENUM-Elemente zugewiesen werden.
  • Das Video zeigt praxisnah, wie ENUMs sicher und effektiv in SPS-Steuerungen eingesetzt werden.

Full Transcript — Download SRT & Markdown

00:00
Speaker A
Ein Enum ist ein Aufzählungsdatentyp, bei dem ihr selber festlegen könnt, was denn genau in diesem Datentypen aufgezählt werden soll.
00:11
Speaker A
Ihr könnt euch also ein Enum als eine Art Liste vorstellen.
00:15
Speaker A
Ein sehr einfaches Beispiel dafür ist eine Aufzählung von Ampelfarben, also rot, gelb und grün.
00:18
Speaker A
In der SPS-Programmierung werden Enums aber auch häufig eingesetzt für eine Auflistung von möglichen Zuständen, die eine Steuerung einnehmen kann, bei einer Ampelsteuerung würde also diese Aufzählung der Farben noch ergänzt werden um die Farbe rot-gelb.
00:33
Speaker A
So, ich werde euch gleich zeigen, dass die Deklaration und die Verwendung von Enums wirklich einfach ist.
00:40
Speaker A
Es gibt aber auch noch sozusagen Optionen bei Enums, die deren Verwendung sicherer machen, aber gleichzeitig eben auch etwas einschränken und wie das Ganze funktioniert, zeige ich euch ja auch.
00:52
Speaker A
Als erstes zeige ich euch jetzt, wie ihr einen Aufzählungsdatentypen anlegt.
00:56
Speaker A
Weil ein Enum ein benutzerdefinierter Datentyp ist, sollte der in diesem Ordner DUT, abgekürzt für Data Unit Types, erstellt werden.
01:06
Speaker A
Dazu klicke ich also mit Rechtsklick hier auf diesen Ordner.
01:10
Speaker A
Und wähle aus diesem Menü hinzufügen DUT.
01:14
Speaker A
In dem Menü, das sich jetzt hier öffnet, seht ihr schon, dass es verschiedene benutzerdefinierte Datentypen gibt.
01:21
Speaker A
Unter anderem eben auch eine Enumeration, also der Aufzählungsdatentyp, um den es jetzt hier geht.
01:26
Speaker A
Den wähle ich aus und nenne diesen Datentypen dann noch I_Farbe.
01:30
Speaker A
Weil ich für dieses Beispiel eine Aufzählung der Ampelfarben wähle.
01:34
Speaker A
So, hier gibt's noch die Option Textlistenunterstützung.
01:39
Speaker A
Womit ich die Möglichkeit schaffe, die Bezeichner meiner Aufzählungsliste später in einer Visualisierung verwenden zu können.
01:45
Speaker A
Das brauche ich jetzt hier aber nicht.
01:47
Speaker A
So, dann bestätige ich das Ganze mit Öffnen.
01:51
Speaker A
Und dann wird die Definition dieses Aufzählungsdatentypens hier erstellt.
01:55
Speaker A
Die Bedeutung dieser beiden Befehle hier oben in den geschweiften Klammern erkläre ich später.
02:00
Speaker A
Für den Moment kommentiere ich die also erstmal aus.
02:03
Speaker A
So, die Typendefinition wird also mit Type eingeleitet.
02:08
Speaker A
Danach kommt der Name des Aufzählungstypen mit einem Doppelpunkt.
02:12
Speaker A
Und in den runden Klammern stehen dann die Elemente meiner Aufzählungsliste.
02:16
Speaker A
Enum_Member ist hier nur ein Standardeintrag, den ich gleich ersetzen werde.
02:20
Speaker A
Und abgeschlossen wird die Definition mit End_Type.
02:24
Speaker A
So, in die runden Klammern schreibe ich jetzt also die Elemente meiner Aufzählung.
02:29
Speaker A
Und das sind die Farben rot, rot-gelb, grün und gelb.
02:32
Speaker A
Und die einzelnen Elemente trenne ich durch ein Komma.
02:36
Speaker A
Ihr fragt euch jetzt vielleicht noch, was diese Zuweisung mit dem Wert Null hier im ersten Element soll.
02:41
Speaker A
Die Erklärung dafür ist, dass alle Elemente in der Aufzählungsliste eine eindeutige ID haben.
02:47
Speaker A
Und das ist eine ganze Zahl.
02:49
Speaker A
Die ID von Element rot ist hier die Null.
02:52
Speaker A
Und die IDs der nächsten Elemente werden dann immer um eins erhöht.
02:57
Speaker A
Rot-gelb hat also den Wert eins, grün den Wert zwei und gelb den Wert drei.
03:01
Speaker A
Der Wert des ersten Elements muss nicht immer Null sein.
03:05
Speaker A
Das könnte auch eine andere ganze Zahl sein.
03:08
Speaker A
Sogar auch eine negative Zahl.
03:10
Speaker A
Grundsätzlich sind für die IDs der Listenelemente hier Werte aus dem Wertebereich eines Integers erlaubt.
03:16
Speaker A
Wenn ihr also hinter den Bezeichner keine andere Angabe macht, wird die ID immer um eins inkrementiert.
03:21
Speaker A
Wenn ihr es braucht, könnt ihr auch jedem Bezeichner sozusagen händisch eine ID zuweisen.
03:26
Speaker A
Wichtig ist nur, dass ihr dabei keinen Wert doppelt vergebt.
03:30
Speaker A
Und das Ganze könntet ihr auch nur bei einzelnen Elementen machen.
03:34
Speaker A
Also z.B. sowas hier.
03:36
Speaker A
Hier hat rot den Wert Null.
03:40
Speaker A
Rot-gelb wird dann der Wert eins zugewiesen.
03:43
Speaker A
Grün wird dann von uns auf den Wert vier gesetzt.
03:47
Speaker A
Und gelb bekommt dann wieder den Wert fünf.
03:49
Speaker A
In den meisten Fällen braucht man aber diese Möglichkeit, die Werte selber vorzugeben, gar nicht.
03:54
Speaker A
So, was könnt ihr jetzt mit einem solchen Enum-Datentypen anfangen?
03:58
Speaker A
Zu Beginn hatte ich ja schon erwähnt, dass ihr damit Zustände einer Steuerung angeben könnt.
04:04
Speaker A
Und das demonstriere ich jetzt einmal an einem kleinen Beispiel.
04:09
Speaker A
Im Main-Programm deklariere ich zunächst eine Variable vom Typ I_Farbe.
04:14
Speaker A
Und initialisiere die mit dem Wert rot.
04:17
Speaker A
Der Initialisierungswert muss hier natürlich ein Bezeichner aus dem Aufzählungsdatentypen sein.
04:21
Speaker A
Und dann brauche ich gleich noch eine Textvariable, also ein String, in die ich den Zustand der Steuerung schreibe.
04:27
Speaker A
Und eine Bool-Variable, um die Zustände weiter zu schalten.
04:31
Speaker A
So, weil ja die Werte eines Enums intern Integer-Variablen sind.
04:37
Speaker A
Kann ich die auch in einem Case-Statement auswerten.
04:40
Speaker A
Die einzelnen Fälle sind dann eben die Farben aus meinem Aufzählungsdatentypen.
04:44
Speaker A
Und da gebe ich einfach immer nur die Farbe aus und warte darauf, dass B_Switch wieder auf True gesetzt wird.
04:51
Speaker A
Dann wechsle ich den Wert von I_Farbe auf den jeweils nächsten Zustand.
04:55
Speaker A
Und ganz am Ende nach dem Case setze ich dann noch B_Switch wieder zurück.
05:00
Speaker A
So, das Programm kann ich nun laufen lassen.
05:02
Speaker A
Und dann seht ihr, dass hier die einzelnen Phasen einer Ampel zyklisch durchlaufen werden.
05:08
Speaker A
Der Zustand der Ampel wechselt also immer, wenn ich B_Switch auf True setze.
05:13
Speaker A
Bis hierhin habe ich euch also gezeigt, dass die Deklaration und die Verwendung eines Enums wirklich simpel ist.
05:19
Speaker A
So einfach ein Enum ist, so nützlich ist dieser Datentyp aber auch für den Aufbau von sogenannten Schrittketten, also Steuerungen, die eben verschiedene Zustände haben.
05:29
Speaker A
Und die in Abhängigkeit von bestimmten Ereignissen zwischen diesen Zuständen wechseln.
05:33
Speaker A
Bei einem Enum, wie ich den jetzt hier implementiert und genutzt habe, gibt es aber auch ein paar Sachen zu beachten.
05:40
Speaker A
Und die zeige ich euch jetzt.
05:42
Speaker A
Das erste ist, dass ich in meinem Programm hier die Bezeichner aus dem Enum, also rot, grün und so weiter.
05:50
Speaker A
Wie konstante Variablen verwendet habe.
05:53
Speaker A
Ohne dass dabei aber der Bezug zum Aufzählungsdatentypen tatsächlich ersichtlich ist.
05:58
Speaker A
Das heißt, diese Enum-Elemente hier werden losgelöst von ihrem Geltungsbereich verwendet.
06:03
Speaker A
Zu einem Problem kann das werden, wenn ich in meinem Programm Variablen habe.
06:08
Speaker A
Die denselben Bezeichner haben, also z.B. sowas hier.
06:12
Speaker A
Grün ist jetzt also eine lokale Variable in dem Programm.
06:18
Speaker A
Die das Enum-Element grün sozusagen überdeckt.
06:22
Speaker A
Das seht ihr insbesondere an diesem Fehler hier.
06:26
Speaker A
Das nämlich eine veränderliche Variable nicht in dem Case-Statement ausgewertet werden kann.
06:31
Speaker A
So, durch die Deklaration der Variablen grün vom Typ Integer hier oben kann ich also schon mal das Programm nicht mehr kompilieren.
06:37
Speaker A
Wenn ich jetzt die Variable grün hier zu einer Konstanten mache.
06:41
Speaker A
Dann gibt es zumindest keinen Fehler mehr, aber die lokale Variable grün überdeckt immer noch das Enum-Element.
06:50
Speaker A
Um dieses Problem zu lösen, gibt es eine einfache Möglichkeit.
06:55
Speaker A
Nämlich den Bezeichner grün hier seinen Geltungsbereich voranzustellen.
07:00
Speaker A
Also I_Farbe.
07:02
Speaker A
So, auch wenn die lokale Variable grün und der Enum-Bezeichner jetzt also gleich heißen, kann ich jetzt aber durch die Angabe des Geltungsbereichs sauber zwischen beiden trennen.
07:10
Speaker A
Das ist also guter Programmierstil bei der Verwendung eines Enums.
07:16
Speaker A
Diesen Bereich immer mit anzugeben.
07:19
Speaker A
Und damit ihr euch immer an diesen Stil haltet, könnt ihr euch auch selber dazu zwingen.
07:25
Speaker A
Indem ihr nämlich bei der Enum-Deklaration dieses Attribut Qualified_Only angebt.
07:32
Speaker A
So, jetzt seht ihr also in der Main, dass die Bezeichner rot, rot-gelb und gelb alle rot unterkringelt sind.
07:40
Speaker A
Diese Bezeichner sind jetzt also nur gültig zusammen mit dem Geltungsbereich.
07:46
Speaker A
Ein zweites Problem beim Enum kann sein.
07:50
Speaker A
Dass ihr eine Enum-Variable noch wie eine ganz normale Integer-Variable verwenden könnt.
07:55
Speaker A
Das heißt, ich könnte der Variablen I_Ampel hier irgendeinen Integer-Wert zuweisen.
07:59
Speaker A
Also z.B. den Wert sechs.
08:02
Speaker A
Das Problem ist jetzt, dass ich gar keinen Bezeichner definiert habe, der den Wert sechs hat.
08:08
Speaker A
In dem Case-Statement wird hier der Fall, dass I_Ampel gleich sechs ist, also gar nicht behandelt.
08:14
Speaker A
Die Enum-Variable wird also wie eine ganz normale Integer-Variable behandelt, mit der ihr sogar rechnen könnt.
08:21
Speaker A
In der Regel sind solche Berechnungen aber ziemlich sinnlos.
08:25
Speaker A
Damit euch solche Rechnungen nicht aus Versehen passieren, gibt es eine Möglichkeit, wie ihr euch davor schützen könnt.
08:31
Speaker A
Nämlich, indem ihr bei der Deklaration des Enum das Attribut Strict angebt.
08:37
Speaker A
Jetzt seht ihr im Main-Programm, dass bei den Berechnungen mit dem Enum Fehler aufpoppen.
08:43
Speaker A
Sodass das Programm also auch wieder nicht kompiliert werden kann, wenn darin eben solche Berechnungen enthalten sind.
08:51
Speaker A
So, ich hoffe, dass ihr bis hierhin erkannt habt, dass die Attribute Qualified_Only und Strict ganz sinnvoll sind.
08:59
Speaker A
Und die deswegen auch standardmäßig bei der Erstellung eines Enum immer mit angegeben werden.
09:03
Speaker A
Neben diesen beiden Attributen gibt es für Enums noch ein weiteres Attribut, das manchmal ganz hilfreich sein kann.
09:08
Speaker A
Und das ist das Attribut To_String.
09:12
Speaker A
Um zu erklären, wofür das gut ist, kommentiere ich das zunächst noch einmal aus.
09:17
Speaker A
So, hier im Main-Programm nutze ich ja diese String-Variable S_Text.
09:23
Speaker A
Um den jeweils aktiven Zustand da rein zu schreiben.
09:27
Speaker A
Das mache ich hier also in jedem Fall dieser Case-Anweisung.
09:31
Speaker A
Komfortabler wäre es ja aber, wenn ich den Bezeichner meiner Enum-Elemente direkt in S_Text schreiben könnte.
09:39
Speaker A
Also z.B. in dieser Form.
09:42
Speaker A
Eine direkte Zuweisung von I_Ampel zu S_Text funktioniert nicht, weil das ja zwei völlig verschiedene Datentypen sind.
09:51
Speaker A
Und deswegen musste ich I_Ampel zunächst in einen String konvertieren.
09:56
Speaker A
Mit der Funktion To_String.
09:59
Speaker A
Die Zuweisung in den Fallunterscheidungen brauche ich dann nicht mehr und deswegen kommentiere ich die dort mal aus.
10:06
Speaker A
Wenn ich jetzt das Programm laufen lasse, seht ihr, dass in dem String S_Text nicht die eigentlichen Bezeichner meiner Enum-Elemente stehen.
10:13
Speaker A
Sondern deren IDs.
10:15
Speaker A
Also die Werte Null bis drei.
10:18
Speaker A
Diese Werte sind aber nicht wirklich sprechend.
10:22
Speaker A
Eine Ausgabe von diesem String erfüllt also nicht wirklich den Zweck, Transparenz darüber zu schaffen, in welchem Zustand sich die Steuerung befindet.
10:30
Speaker A
Was man insbesondere bei der Entwicklung von Steuerungen häufiger mal braucht.
10:34
Speaker A
Wenn ich jetzt aber in der Enum-Deklaration das Attribut To_String hinzufüge.
10:40
Speaker A
Dann hat das die folgende Auswirkung.
10:45
Speaker A
Dann wird nämlich bei dieser Zuweisung hier in Zeile eins nicht die ID des Elements.
10:52
Speaker A
Sondern tatsächlich dessen Bezeichner übergeben.
10:55
Speaker A
Ich habe also jetzt nur das Attribut hinzugefügt, den restlichen Code aber gar nicht verändert.
11:01
Speaker A
Und dass das dann also tatsächlich so stimmt, wie ich behauptet habe.
11:05
Speaker A
Seht ihr jetzt hier im laufenden Programm.
11:07
Speaker A
In S_Text steht also nicht mehr die ID, sondern wirklich die Bezeichner der Enum-Elemente.
Topics:SPS-ProgrammierungENUMAufzählungsdatentypAmpelfarbenSteuerungData Unit TypesQualified_OnlyCase-StatementProgrammierungChristian Stöcker

Frequently Asked Questions

Was ist ein ENUM in der SPS-Programmierung?

Ein ENUM ist ein benutzerdefinierter Aufzählungsdatentyp, der eine Liste von benannten Werten definiert, um Zustände oder Optionen in SPS-Programmen übersichtlich abzubilden.

Wie kann man Namenskonflikte zwischen ENUM-Elementen und lokalen Variablen vermeiden?

Durch die Verwendung des Geltungsbereichs (z.B. I_Farbe.grün) oder das Attribut Qualified_Only, das erzwingt, dass ENUM-Elemente immer mit ihrem Typnamen verwendet werden.

Kann man ENUM-Elementen eigene Werte zuweisen?

Ja, jedem ENUM-Element kann man eine eindeutige Integer-ID manuell zuweisen, die nicht zwangsläufig bei Null beginnen muss und auch negative Werte erlaubt sind.

Get More with the Söz AI App

Transcribe recordings, audio files, and YouTube videos — with AI summaries, speaker detection, and unlimited transcriptions.

Or transcribe another YouTube video here →