Post on 18-Dec-2021
Universität Stuttgart
Institut für Automatisierungstechnik und Softwaresysteme Prof. Dr.-Ing. M. Weyrich
Raum 2.146
Praktische Übungen im Labor
„Automatisierungstechnik“
Versuch Nr. 2
Echtzeitprogrammierung mit Ada
Versuchsanleitung
Echtzeitprogrammierung mit Ada 2
Inhaltsverzeichnis
INHALTSVERZEICHNIS ...................................................................................................... 2
1 EINLEITUNG .................................................................................................................. 4
1.1 MÖGLICHKEITEN ZUR PROZESSDATENVERARBEITUNG IN ECHTZEIT ....................................................... 4 1.2 INHALT UND ZIELSETZUNG DES VERSUCHS ............................................................................................. 4
2 DIE PROGRAMMIERSPRACHE ADA ....................................................................... 5
2.1 ENTSTEHUNG UND GESCHICHTLICHER ÜBERBLICK ................................................................................. 5 2.2 VORTEILE VON ADA ................................................................................................................................ 5 2.3 AUFBAU DER PROGRAMMIERSPRACHE ADA ............................................................................................ 6
2.3.1 Formeller Aufbau der Programme ....................................................................... 6
2.3.2 Typen .................................................................................................................... 7
2.3.3 Operatoren ............................................................................................................ 8
2.3.4 Befehle in Ada ...................................................................................................... 8
2.3.5 Programmeinheiten ............................................................................................ 11
3 AUFBAU DER MPS PA COMPACT- WORKSTATION ......................................... 14
4 AUFBAU DES VORHANDENEN ADA- PROCESS- CONTROLLER .................. 19
4.1 FIELD EBENE ......................................................................................................................................... 19 4.1.1 Communications Link Ebene ............................................................................. 20
4.1.2 Communication Command Ebene ..................................................................... 20
4.1.3 Communication Manager Ebene ........................................................................ 20
4.1.4 Module Interface Ebene ..................................................................................... 20
4.2 PROCESS VARIABLE EBENE ................................................................................................................... 20 4.2.1 Analoge Schnittstellen ........................................................................................ 21
4.2.2 Digitale Schnittstellen ........................................................................................ 23
4.3 PROCESS CONTROL EBENE .................................................................................................................... 23 4.4 GRAPHISCHE OBERFLÄCHE ................................................................................................................... 24 4.5 SZENARIO EXPERIMENT ........................................................................................................................ 24
4.5.1 Kommunikationssteuerung ................................................................................. 25
4.5.2 Analoge Eingangssignale ................................................................................... 25
4.5.3 Digitale Eingangssignale .................................................................................... 25
4.5.4 Analoge Ausgangssignale .................................................................................. 25
4.5.5 Digitale Ausgangssignale ................................................................................... 25
4.5.6 Versuchssteuerung ............................................................................................. 25
5 BENUTZUNGSANLEITUNG ...................................................................................... 26
5.1 MÖGLICHE PROBLEME BEIM PRAKTIKUMSVERSUCH ............................................................................. 27
6 BEISPIELPROJEKT „AUTOMATISIERUNG EINER ABFÜLLANLAGE“ ....... 27
6.1 EINFÜHRUNG ......................................................................................................................................... 27 6.2 AUFGABENSTELLUNG ............................................................................................................................ 27
7 AUFGABEN UND VERSUCHE................................................................................... 32
7.1 HINWEISE ZUR VERSUCHSDURCHFÜHRUNG .......................................................................................... 32 7.2 EINFÜHRUNGSAUFGABEN ...................................................................................................................... 32 7.3 IMPLEMENTIERUNG DER AUSGANGSLAGE UND NOTAUSSCHALTERFUNKTIONALITÄT ........................... 34
Echtzeitprogrammierung mit Ada 3
7.4 IMPLEMENTIERUNG DER TEMPERATURREGELUNG ................................................................................ 34
8 LITERATUR .................................................................................................................. 36
9 ANHANG ........................................................................................................................ 37
Echtzeitprogrammierung mit Ada 4
1 Einleitung
Dieser Fachpraktikumsversuch dient zur Einführung in die Programmiersprache Ada und die
Automatisierung einer Modellabfüllanlage.
1.1 Möglichkeiten zur Prozessdatenverarbeitung in Echtzeit
Die Überwachung und Führung von technischen Anlagen ist in der Industrie eines der
wichtigsten Themenfeldern und Hauptaufgabe der Automatisierungstechnik. Ohne die
Möglichkeit komplexe technische Prozesse zu steuern und zu automatisieren, wäre unser
heutiges güterkonsumierendes Leben nicht in diesem Ausmaß möglich. Was mit der
Erfindung der ersten industrietauglichen Dampfmaschine durch Thomas Newcomen im Jahre
1712 begann, wurde 1913 mit der Einführung des ersten motorisierten Fließbandes durch
Henry Ford fortgesetzt.
Heutzutage besteht eine Produktionsanlage freilich nicht nur aus einem Fließband, sondern
kann aus vielen Maschinen mit schnellen und präzisen Bewegungsabläufen bestehen, die
komplexe Steuerungsanforderungen erfordern. Damit eine solche Anlage gesteuert und
automatisiert werden kann, werden verschiedenste Rechnersysteme eingesetzt, die die
Prozessdaten häufig in Echtzeit verarbeiten müssen, damit die Anlage synchron läuft.
Um Prozessdaten in Echtzeit zu verarbeiten, kann man auf verschiedene Möglichkeiten
zurückgreifen. Der Einsatz von
Speicherprogrammierbaren Steuerungen (SPS)
Hardwarenahe Mikroprozessoren und -controller
Höhere Programmiersprachen in Verbindung mit einem Echtzeitbetriebssystem auf
einem PC
Programmierung mittels Echtzeitprogrammiersprache (z.B. Ada)
hat sich dabei bewährt.
Die Vorteile die Ada für einen Echtzeitbetrieb mit sich bringt sind beispielsweise die
Nebenläufigkeit von Tasks, zeitgesteuertes Verhalten und einen exklusiven Zugriff auf
Ressourcen. Dadurch ist es mit Ada möglich, eine Echtzeitprogrammierung direkt
durchzuführen, ohne von Schnittstellen des Echtzeitbetriebssystems abhängig zu sein.
1.2 Inhalt und Zielsetzung des Versuchs
Eine typische Aufgabenstellung eines Automatisierungsingenieurs besteht darin, ein
echtzeitfähiges System zu entwickeln. Dieser Versuch dient dazu, einen Einblick in die
Programmierung solcher Echtzeitsysteme mit Hilfe der Programmiersprache Ada zu
vermitteln. Hierzu soll zum Einen ein Beispielprogramm erweitert werden und zum Zweiten
eine Automatisierung für eine Abfüllanlage realisiert werden. Hierfür wird ein Modell einer
Industrieabfüllanlage von Festo Didactic, die MPS PA Compact- Workstation verwendet.
Um eine zügige und erfolgreiche Versuchsdurchführung zu gewährleisten, muss der Versuch
gründlich vorbereitet werden. Dazu muss die komplette Anleitung mitsamt dem Anhang
durchgelesen werden und die Vorbereitungsaufgaben in Kapitel 6 sind vor der Durchführung
des Versuchs schriftlich zu bearbeiten.
Echtzeitprogrammierung mit Ada 5
2 Die Programmiersprache Ada
2.1 Entstehung und geschichtlicher Überblick
Ada entstand in den 1970er Jahren. Zu diesem Zeitpunkt veranlasste das amerikanische
Verteidigungsministerium (US Departement of Defense, kurz DoD) eine interne
Untersuchung und musste feststellen, dass mehr als 450 verschiedene Programmiersprachen
in deren Projekten verwendet wurden. Um den gewaltigen Aufwand zu verringern, der nötig
war, um die verwendete Software zu warten, wurde daraufhin eine Arbeitsgruppe
eingerichtet. Ziel dieser Arbeitsgruppe war, die Anforderungen des
Verteidigungsministeriums zu standardisieren und aufzulisten. Trotz der vielen auf dem
Markt verfügbaren Programmiersprachen konnte keine die Anforderungen im Bereich der
Wartung, Ausbildung, Modularität und Wiederverwendung erfüllen. Nach einer weltweiten
Ausschreibung entschied man sich für den Entwurf von Jean Ichbiah (Sprachstandard
ANSI/MIL-STD-1815A 1983) und nannte die Sprache Ada831. Diese wurde in den folgenden
Jahren überarbeitet, erweitert und durch das ANSI (American National Standards Institute)
und die ISO (Internationale Organisation für Normung) normiert und standardisiert. Durch die
Erweiterung mit objektorientierten Funktionen wurde Ada95 (Sprachstandard
ANSI/ISO/IEC-8652:1995) somit die erste genormte objektorientierte Programmiersprache.
Um eine schnelle Verbreitung der Sprache zu forcieren, schrieb das amerikanische
Verteidigungsministerium bis 1997 vor, dass in allen Softwareprojekten des DoD mindestens
30% des Codes in Ada implementiert werden musste. Zusätzlich wurde der GNAT- Compiler
von der US Air Force finanziert und allen Nutzern kostenfrei zur Verfügung gestellt.
2.2 Vorteile von Ada
Ada ist heutzutage in Bereichen mit sicherheitskritischem Echtzeitbezug, beispielsweise beim
Militär weit verbreitet. Gründe hierfür sind reichlich vorhanden.
Zum Einen wurde Ada sehr streng standardisiert und der gesamte Standard ist seither im
sogenannten Ada Language Reference Manual kostenfrei verfügbar. Darüber hinaus muss
jeder Ada-Compiler, will er offiziell validiert werden, ausgiebige Tests durchlaufen und alle
korrekt bewältigen. Dadurch wird eine hohe Portierbarkeit auf andere Zielsysteme erreicht.
Bereits bei der Kompilierung wird der Code überprüft, um beispielsweise Flüchtigkeitsfehler
direkt zu erkennen und die formale Korrektheit zu gewährleisten. Dadurch verringert sich der
Aufwand der Qualitätssicherung ganz erheblich.
Zusätzlich wird auch eine Laufzeitüberprüfung durchgeführt, damit bei Verletzungen von
vordefinierten Regeln ein Fehler ausgelöst wird und ein weiteres Feature von Ada, die
sogenannte Ausnahmebehandlung (Exceptionhandling), Verwendung findet. Dies erlaubt
vorzuschreiben, wie das Programm in einem Fehlerfall reagieren soll, beispielsweise einen
speziellen Fehlercode auszugeben oder die Anlage in einen sicheren Zustand zu überführen.
Dadurch wird es auch erheblich leichter den Fehler zu lokalisieren. Da Ada für sehr große und
komplexe Systeme mit Millionen von Codezeilen entwickelt wurde, ist dieses Feature auch
ein Garant dafür, dass Ada in sicherheitskritischen Aufgabengebieten, wie zum Beispiel bei
der Flugsicherung, bei Waffensystemen oder bei der Raumfahrt so verbreitet ist.
Ein weiterer Vorteil von Ada ist die Möglichkeit ein Softwareprojekt in verschiedene Module
aufzuteilen. Dies ist ein Grund, dass sehr große und komplexe Softwareprojekte erst
umsetzbar sind. Zudem vereinfacht die Modularisierung das Programm zu verstehen und
minimiert den Aufwand das Programm zu erweitern. Durch die Verwendung von
Bibliotheken und somit die Verwendung von bereits bewährten Codezeilen wird die
Erweiterung von Programmen deutlich vereinfacht und beschleunigt.
1 nach der britischen Mathematikerin Ada Lovelace (1815-1852)
Echtzeitprogrammierung mit Ada 6
Die Möglichkeit gar einzelne Bits bei Ada zu manipulieren und auf Registerebene zu
programmieren, macht Ada auch für die maschinennahe Hardwareprogrammierung
interessant.
Weitere Vorteile sind [IAS07]:
Unterstützung von Methoden der Softwaretechnik
Unterstützung der Wiederverwendbarkeit
Ereignisgesteuerte und nebenläufige Programmierung
Verwendung einer Programmbibliothek
Schnittstelle zu peripheren Softwaresystemen
Objektorientierung mit dynamischer Polymorphie
Echtzeitunterstützung
Optionale automatische Speicherbereinigung
Parallele Verarbeitung
2.3 Aufbau der Programmiersprache Ada
2.3.1 Formeller Aufbau der Programme
Der Zeichensatz eines Ada- Programmes besteht aus den 26 Grundbuchstaben des
lateinischen Alphabets in kleiner, als auch in großer Schreibweise. Umlaute sind zwar
möglich, es ist aber zu empfehlen darauf zu verzichten, wenn man Software entwickeln will,
die auch international Verwendung finden soll. Zu den Grundbuchstaben kommen auch alle
Ziffern von 0 bis 9, das Leerzeichen sowie folgende Zeichen hinzu: " # ' ( ) * + , - . / : ; < = > _ | & [ ] { }
Alle lexikalischen Einheiten bestehen aus diesem Zeichensatz. Es gibt Bezeichner, reservierte
Worte, numerische Literale, Zeichenliterale, Zeichenkettenliterale, Begrenzer und
Kommentare. Leerzeichen zwischen zwei lexikalischen Einheiten werden von Ada ignoriert.
Bezeichner für Programmteile, Variablen, usw. beginnen mit einem Buchstaben. Danach
können beliebig viele Buchstaben, Ziffern und Unterstriche folgen. Allerdings dürfen
Unterstriche nicht aufeinander folgen und sie dürfen nicht am Ende des Bezeichners stehen.
Darüber hinaus darf ein Bezeichner maximal bis zum Zeilenende gehen. Zur besseren
Lesbarkeit sind aber Bezeichner zu bevorzugen, die möglichst kurz und prägnant sind. Ada
unterscheidet generell keine Groß- und Kleinschreibung, dennoch sollten Bezeichner in allen
Programmteilen einheitlich geschrieben werden, da sonst der Compiler meckert.
Folgende Schlüsselworte sind in Ada reserviert und können nicht als Bezeichner verwendet
werden:
abort begin else goto new private reverse until abs body elsif not procedure use abstract end if null protected select accept case entry in separate when access constant exception is of raise subtype while aliased exit or range with all declare limited others record tagged and delay for loop out rem task xor array delta function renames terminate at digits mod packages requeue then do generic pragma return type
Echtzeitprogrammierung mit Ada 7
Bei numerischen Literalen gewährt Ada einige Freiheiten. Bei dieser Darstellung der ganzen
und reellen Zahlen können beispielsweise Unterstriche eingefügt werden, um die Lesbarkeit
zu erhöhen. So entspricht 1_500_000 oder 1.5e6 dem Zahlenwert 1500000. Zudem kann jede
Zahl zu einer Basis zwischen 2 und 16 angegeben werden. So entspricht 2#1111 in binärer
Schreibweise, dem Zahlenwert 16#F in hexadezimaler Schreibweise und in dezimaler
Schreibweise dem Zahlenwert 15. Als Dezimaltrennzeichen wird in Ada ein Punkt verwendet.
Zeichenliterale (character) können aus einem beliebigen Zeichen bestehen und werden von
Hochkommata eingeschlossen ('Z'). Zeichenkettenliterale (strings) dagegen können auch aus
keinem Zeichen bestehen und werden von doppelten Hochkommata eingeschlossen
("String").
Begrenzer (delimiter) können einzeln oder zusammengesetzt (compound delimiter) auftreten
und umfassen folgende Zeichen: ' ( ) * + , - . / : ; < = > | &
Als Letztes zu erwähnen gelten hier noch Kommentare. Diese werden durch einen doppelten
Bindestrich gekennzeichnet und gehen bis zum Zeilenende (-- dies wäre ein Kommentar).
2.3.2 Typen
Mit Typen hat der Programmierer die Möglichkeit sich eigene Wertebehälter zu erstellen. Ein
Typ ist beispielsweise die Aufzählung: type Monat is (Januar, Februar, .., Dezember);.
2.3.2.1 Ganze Zahlen
Zur Darstellung von ganzen Zahlen wird in Ada der Typ „integer“ verwendet. Des Weiteren
gibt es noch den Typ „positive“ für alle Zahlen größer Null und den Typ „natural“ für alle
Zahlen größer gleich Null. Eine Besonderheit von Ada ist hier, dass man eigene
Wertebereiche angeben kann. In diesem Fall spricht man dann von einem „subtype“. Falls
man zum Beispiel nicht den gesamten Wertebereich eines Integers braucht, kann man einen
kleineren Wertebereich angeben2. Um einen Wertebereich von 0 bis 10 zu deklarieren,
schreibt man: subtype kleiner_wertebereich is integer range 0 .. 10;.
Will man mit mehreren Ganzzahlen von verschiedenem Wertebereich rechnen, erfolgt eine
automatische Typkonversion. Falls hierbei keine passende Konversion durchgeführt werden
kann, wird ein „constraint_error“ ausgelöst.
Beispiel: X=5 besitzt einen Wertebereich von 0 .. 10 und Y=10 einen Wertebereich von 0 ..
20. Wird nun der Ausdruck X+Y berechnet und in Y zurückgeschrieben ist alles in Ordnung
(Y=15). Wird dieser Ausdruck aber berechnet und in X zurückgeschrieben tritt ein
„constraint_error“ auf, weil der Wertebereich von X nicht ausreicht.
Soll sich der Wert einer Variable nicht mehr ändern, fügt man ein „constant“ vor den Typ ein
(z.B. Anzahl_Monate: constant integer := 12;).
2.3.2.2 Reelle Zahlen
Reelle Zahlen können in Ada als Gleitkomma-, Festkomma- oder Dezimalzahlen angegeben
werden.
Bei Gleitkommazahlen müssen die exakten Dezimalstellen angegeben werden und man kann
auch einen Wertebereich angeben: type Laenge is digits 2; (z.B. 10.55), type Prozent is digits
4 range 0.0 .. 1.0; (z.B. 0.3456).
Bei Festkommazahlen muss die Differenz zweier aufeinanderfolgender Werte angegeben
werden. Analog zu Gleitkommazahlen ist es auch hier optional möglich einen Wertebereich
vorzugeben: type Laenge is delta 0.01;.
Zum Abschluss gibt es noch die Möglichkeit reelle Zahlen als Dezimalzahlen anzugeben.
Hier wird sowohl die Differenz als auch die Dezimalstellen angegeben: type Temperatur is
delta 0.01 digits2;.
2 in Ada entscheidet der Ausführer, abhängig von der Hardware auf dem er benutzt wird, welcher Wertebereich
ein Integer besitzt, mindestens aber der Bereich von -32 768 bis + 32 767 (16Bit)
Echtzeitprogrammierung mit Ada 8
2.3.2.3 Arrays
Bei der Deklaration von Arrays hat man die Möglichkeit, die Grenzen des Arrays exakt
festzulegen (constrained array) oder offenzulassen (unconstrained array): type Acht_Bit is
array(0 .. 7) of boolean; (constrained array), type Vector is array(integer < >) of positive;
(unconstrained array).
Bei der Definition von constrained Arrays braucht man keine Grenzen mehr anzugeben: Byte:
Acht_Bit;. Anders bei einem unconstrained Array, hier muss man die Grenzen angeben:
Quadrat: Matrix(1 .. 5, 1 .. 5);.
Um nun auf ein einzelnes Element eines Arrays zuzugreifen, benutzt man runde Klammern:
Byte(3), Quadrat(2, 4). Außerdem kann man auch einen gewählten Bereich aus einem
vorhandenen Array ausschneiden (Slices) und erhält ein weiteres Array: Byte(3 .. 6).
2.3.2.4 Private (abstrakte) Typen
Um bestimmte Komponenten eines Objektes vor dem, evtl. auch unbeabsichtigten Verändern
zu schützen, stellt Ada die privaten Typen zur Verfügung: type Tag is private;. Diese müssen
in der Paketspezifikation zweimal vereinbart werden. Zum Einen müssen sie im öffentlichen
Bereich (vor dem Schlüsselwort „private“) unvollständig beschrieben werden. D.h. man
vereinbart, dass zum Beispiel eine Variable privat ist (type X is private;). Zum Anderen muss
im nicht sichtbaren Teil dieser Typ dann vollständig beschrieben werden (type X is range -10
.. 10;).
2.3.3 Operatoren
Es gibt in Ada, analog zu anderen Programmiersprachen, verschieden Operatoren. Die
Wichtigsten sind hier aufgeführt:
** Potenzieren = Gleichheit
abs() Absolutbetrag /= Ungleichheit
not Negation <; <= kleiner; kleiner- gleich
* Multiplikation >; >= größer; größer- gleich
/ Division and Konjunktion
+ Addition or Disjunktion
- Subtraktion xor exklusive Disjunktion
Als einen weiteren Operator sei hier noch auf den binären Operator „&“ hingewiesen, der
zwei Strings (eindimensionale Arrays) zusammenfügt.
2.3.4 Befehle in Ada
In Ada werden drei verschiedene Befehle unterschieden. Die Vereinbarung, der Ausdruck und
die Anweisung. Im Folgenden sollen die drei Arten kurz beschrieben werden.
2.3.4.1 Vereinbarungen
Vereinbarungen deklarieren Variablen oder Unterprogramme. Im Grunde gibt man den
Namen an, gefolgt vom Typ und evtl. auch gleich ein Startwert: X : integer := 17;. Hier wurde
der Wertebehälter „X“ als Typ „integer“ mit Startwert 17 deklariert.
2.3.4.2 Ausdrücke
Ausdrücke berechnen einen Wert, verändern dabei aber typischerweise keinen Behälterinhalt.
So ist beispielsweise: 10 + X * 4 ein Ausdruck, der einen Wert abhängig vom Behälterinhalt
„X“ berechnet.
Echtzeitprogrammierung mit Ada 9
2.3.4.3 Anweisungen
Im Gegensatz zu Ausdrücken kann die Anweisung den Inhalt eines Wertebehälters verändern
und muss mit einem Semikolon abgeschlossen werden. Am deutlichsten wird dies bei der
Zuweisungsanweisung: X := X + Y + 5;. Hier wird ein Ausdruck berechnet und sein Ergebnis
in den Wertebehälter „X“ zurückgeschrieben. Hier sei angemerkt, dass beispielsweise auch
der Bildschirm oder die Tastatur als Wertebehälter gelten und es sich somit bei Ein- und
Ausgabebefehlen auch um Anweisungen handelt.
Im Folgenden werden weitere wichtige Anweisungen vorgestellt.
2.3.4.3.1 Die Null- Anweisung
Die Null- Anweisung ist beschrieben durch „null;“ und dient dem Zweck nichts zu tun. Dies
ist oft als Platzhalter für spätere Funktionen sinnvoll.
2.3.4.3.2 Die If- und Case- Anweisung
Zur Selektion dient die If- und Case- Anweisung. Hier hat der
Programmierer die Möglichkeit, dass eine Anweisung unter
Umständen gar nicht ausgeführt wird. Im Gegensatz dazu kann er
mit den Loop- Anweisungen erreichen, dass eine Anweisung
mehrmals aufgerufen wird.
Der Grundaufbau ist in Abbildung 1 dargestellt.
Die If- Anweisung kann zudem aus beliebig vielen Elsif- Zweigen
bestehen, muss aber keinen Else- Aufruf besitzen.
Bei der Case- Anweisung muss der Ausdruck entweder zu dem Typ
Ganzzahl oder dem Typ Aufzählung gehören. Zudem muss der
Wert des Ausdrucks bereits zur Compilezeit bekannt sein und nicht
erst zur Laufzeit. Außerdem muss eine Case- Anweisung
vollständig und eindeutig sein. Ist Vollständigkeit nicht erreichbar,
so muss als letzter Eintrag „others“ verwendet werden.
2.3.4.3.3 Die Exit- Anweisung
Um Schleifen zu verlassen dient die unbedingte und bedingte Exit- Anweisung: exit;, exit
when Ausdruck;. Bei Bedarf kann auch direkt hinter dem Schlüsselwort „exit“ noch der
Schleifenname angegeben werden: exit Schleifennamen when X=Y;. Steht die Exit-
Anweisung vor allen anderen Anweisungen in der Schleife, bezeichnet man sie als
vorprüfende Schleife. Steht die Exit- Anweisung nach allen anderen Anweisungen in der
Schleife, bezeichnet man sie als nachprüfende Schleife.
2.3.4.3.4 Die Loop- Anweisung
Die Loop- Anweisungen werden in drei verschiedene Schleifen- Anweisungen unterteilt.
Es gibt die Loop- Anweisung ohne Iteration, eine While- und eine For- Schleife. Zudem dient
die Loop- Anweisung ohne Iteration dazu Schleifentypen nachzubilden, die es in Ada
eigentlich nicht gibt (z.B. vor- und nachprüfende Until- Schleife). Während die Möglichkeit
besteht, dass eine Loop- oder While- Schleife zur Endlosschleife wird, ist diese Gefahr bei
einer For- Schleife so gut wie nicht gegeben.
For- Schleifen können den kompletten Wertebereich des Variablentyps durchlaufen oder nur
einen beschränkten Wertebereich mit dem Schlüsselwort „range“. Soll die Reihenfolge nicht
aufsteigend (Standardeinstellung) sondern absteigend dem Schleifenparameter zugewiesen
werden, benutzt man das Schlüsselwort „in reverse“.
Abbildung 1 -
Grundaufbau If- und Case-
Anweisung
Echtzeitprogrammierung mit Ada 10
Schleifen können zudem
benannt werden indem der
Name mit Doppelpunkt vor den
Loop- Block geschrieben wird.
So wird ermöglicht, dass man
auch bei verschachtelten
Schleifen immer genau weiß,
welche Schleife hier verlassen
wird. In Abbildung 2 ist der
Grundaufbau von den obigen
Schleifen aufgeführt.
2.3.4.3.5 Die Block- Anweisung
Die Block- Anweisung unterteilt sich in einen Vereinbarungsteil und einem Anweisungsteil.
Der Grundaufbau ist in Abbildung 3 dargestellt. Der
Vereinbarungsteil wird durch „declare“ begonnen und hört
mit „begin“ auf, wo der Anweisungsteil beginnt. Dieser wird
mit „end“ beendet. Die Block- Anweisung erzeugt die im
Vereinbarungsteil deklarierten Wertebehälter und führt
anschließend die Anweisungen aus. Beim Beenden der Block-
Anweisung werden alle erzeugten Wertebehälter wieder
gelöscht. Wenn nicht benötigt, kann der Vereinbarungsteil
auch weggelassen werden. Will man einen Block benennen, so
fügt man den Namen mit gefolgtem Doppelpunkt entweder vor „declare“ (mit
Vereinbarungsteil), oder vor „begin“ (ohne Vereinbarungsteil) ein.
2.3.4.3.6 Die Return- Anweisung
Um Unterprogramme zu verlassen und zum Ursprung des Aufrufs zurückzuspringen benutzt
man die Return- Anweisung. Innerhalb von Prozeduren benutzt man lediglich das
Schlüsselwort „return“ mit abschließendem Semikolon. Bei Funktionen muss noch der
berechnete Ausdruck dem Ursprung des Aufrufs übergeben werden: return Ausdruck;.
2.3.4.3.7 Die Raise- Anweisung
Mit der Raise- Anweisung löst man eine Ausnahmebehandlung (Exceptionhandling) aus. Ada
bietet eine Laufzeitüberwachung an und löst spezielle vordefinierte Ausnahmen
(constraint_error, programm_error, usw.), auch ohne die Raise- Anweisung durch den
Programmierer aus. So zum Beispiel bei der Division durch 0.
Allerdings darf auch der Programmierer Ausnahmen deklarieren und festlegen, wie
vorgegangen werden soll, wenn diese Ausnahme auftritt. Zudem kann er auch auf die von
Ada bereits definierten Ausnahmen zugreifen und diese auslösen ohne sie implementieren zu
müssen.
Ausnahmen werden im Vereinbarungsteil deklariert und im Anweisungsteil ausgelöst. Will
man bei einer Ausnahme eine bestimmte Anweisung aufrufen, kann man hierzu den
Ausnahmebehandler (Exceptionhandler) verwenden. Um diesen zu beschreiben, wird am
Ende eines Anweisungsteils mit dem Schlüsselwort „exception“ ein Ausnahmeteil eingefügt
Abbildung 2 - Grundaufbau Schleifen- Anweisungen
Abbildung 3 - Grundaufbau
Block- Anweisung
Echtzeitprogrammierung mit Ada 11
welcher dann bis zum Schlüsselwort „end“ geht. Nun kann man festlegen, was bei welcher
Ausnahme gemacht werden soll.
Um die Auswirkungen einer Ausnahme zu verdeutlichen gehen wir kurz davon aus, dass eine
Prozedur oder Ähnliches einen Rahmen darstellt.
Wird nun im Anweisungsteil eines inneren Rahmens eine Ausnahme ausgelöst, geht der
Ausführer vom Normalzustand in den Ausnahmezustand über. Hierbei springt er zum
Ausnahmeteil des inneren Rahmens und sucht nach dem Namen der ausgelösten Ausnahme.
Wird dieser Ausnahmebehandler gefunden, führt er dessen Anweisungen aus, geht dann in
den Normalzustand über und beendet den inneren Rahmen. Nun wird der äußere Rahmen an
der Stelle nach dem inneren Rahmen fortgesetzt.
Wird im inneren Rahmen kein passender Ausnahmebehandler gefunden, bleibt der Ausführer
im Ausnahmezustand und beendet den inneren Rahmen. Danach löst er im äußeren Rahmen
die Ausnahme erneut aus und springt in den Ausnahmeteil. Nun sucht er wieder den
passenden
Ausnahmebehandler und
verfährt analog zum
inneren Rahmen.
Wird wieder kein
passender
Ausnahmebehandler
gefunden und es gibt
keinen weiteren äußeren
Rahmen mehr, wird das
komplette Programm mit
einer Fehlermeldung
abgebrochen. Der
Grundaufbau einer
Ausnahmebehandlung ist
in Abbildung 4 dargestellt.
2.3.5 Programmeinheiten
Es gibt in Ada grundsätzlich vier verschiedene Einheiten.
Unterprogramme
Rechenprozesse (Tasks)
Wiederverwendbare Bibliotheken (Pakete)
Gemeinsam genutzte Betriebsmittel (geschützte Variable)
Programmeinheiten werden gewöhnlich unterteilt in eine Spezifikations- (Dateiendung .ads)
und eine Implementierungsdatei (Dateiendung .adb). Die Spezifikationsdatei muss nicht
vorhanden sein, um ein ausführbares Programm zu kompilieren. Es wird aber dringend
empfohlen dieses nützliche Feature von Ada zum leichteren Verständnis von Programmen zu
verwenden. In der Spezifikationsdatei werden alle nötigen Informationen hinterlegt um eine
Programmeinheit aufrufen zu können (Name, Parameter, Parametertyp, Parametermodi, usw.)
zudem sollte ein Kommentar enthalten sein, um kurz zu beschreiben, was diese
Programmeinheit genau macht. Eine Spezifikation ist übersichtlicher und meist deutlich
leichter zu verstehen als eine komplexe Implementierung. In der Implementierungsdatei
werden die Spezifikationen zuerst wiederholt und darauffolgend die Anweisungen formuliert.
Abbildung 4 - Grundaufbau von Ausnahmebehandlung in einer Prozedur
Echtzeitprogrammierung mit Ada 12
2.3.5.1 Unterprogramme
Unterprogramme sind Anweisungen oder Ausdrücke, welche in einem Block
zusammengefasst und mit einem Namen versehen werden. Dadurch kann man sie mehrmals
verwenden ohne jedes Mal den Code von Neuem eingeben zu müssen. Außerdem erleichtert
dies das Verstehen und auch Warten der Software, sowie die Lesbarkeit.
Unterprogramme sind in zwei Abschnitte unterteilt. Am Anfang steht die Deklaration mit
dem Namen, den Parametern und falls es sich um eine Funktion handelt, wird hier auch der
Rückgabewert bestimmt. Der zweite Teil ist die Implementierung mit den Anweisungen.
Zu unterscheiden sind hier einmal die Bibliotheksunterprogramme, die von überall aufgerufen
werden können, und die enthaltenen Unterprogramme, die ausschließlich innerhalb der
Einheit aufgerufen werden können, in der sie beschrieben sind.
In Abbildung 5 ist ein Beispiel für ein enthaltenes
Unterprogramm zu sehen. Die Prozedur „haupt“ ist hier
ein Bibliotheksunterprogramm und die Prozedur „unter“
ist in „haupt“ enthalten und kann nur innerhalb dieser
Prozedur aufgerufen werden. Zu bemerken ist zudem,
dass die Zeilen 2 – 5 lediglich die Prozedur „unter“
erzeugen und diese nicht ausführen. Erst in Zeile 8 wird
diese Prozedur explizit ausgeführt. Hierzu muss diese
mit ihrem Namen aufgerufen und mit einem Semikolon
abgeschlossen werden.
Nachdem ein Unterprogramm aufgerufen wurde,
arbeitet es seine Anweisungen der Reihe nach ab und
führt sie aus. Wird das Schlüsselwort „return“ verwendet, wird das Unterprogramm an dieser
Stelle beendet und es wird an die Stelle zurückgesprungen, von wo das Unterprogramm
aufgerufen wurde.
Zu unterscheiden sind zwei Typen von Unterprogrammen. Einmal die Prozeduren
(procedure) und die Funktionen (function).
Der wesentliche Unterschied besteht darin, dass ein Aufruf einer Prozedur einer Anweisung
entspricht und keinen Wert zurück liefert (z.B. put; get; usw.). Hierbei können
Behälterinhalte verändert werden. Der Aufruf einer Funktion entspricht einem Ausdruck und
liefert einen Wert zurück (z.B. +; -; <; <=; usw.). Hierbei werden Werte berechnet, aber keine
Behälterinhalte verändert.
2.3.5.1.1 Prozedur (procedure)
Eine Prozedur kann (beliebig viele) Parameter in 3 verschiedenen Modi enthalten. Der
Grundaufbau ist in Abbildung 6 dargestellt. Hierbei unterscheidet man Parameter, die von der
Aufrufstelle in die Prozedur transportiert werden (Schlüsselwort „in“ oder ohne
Schlüsselwort), Parameter, die aus der Prozedur zur Aufrufstelle transportiert werden
(Schlüsselwort „out“)
und Parameter die für
beide Wege benutzt
werden (Schlüsselwort
„in out“).
Ein In- Parameter
(beliebiger Ausdruck)
wird von der Aufrufstelle an das Unterprogramm übergeben und wird von diesem als
Konstante behandelt. Ein Out- Parameter (Name einer Variablen) entspricht einer nicht
initialisierten Variablen und wird im Unterprogramm beschrieben und dann der Aufrufstelle
übergeben. Ein In- Out- Parameter (Name einer Variablen) verhält sich wie eine initialisierte
Abbildung 5 - Beispiel für ein
enthaltenes Unterprogramm
Abbildung 6 - Grundaufbau einer Prozedur mit Parameter
Echtzeitprogrammierung mit Ada 13
Variable. Das Unterprogramm bekommt so also eine Variable mit Startwert, darf sie auslesen
und mit einem neuen Wert überschreiben und gibt sie dann der Aufrufstelle wieder zurück.
2.3.5.1.2 Funktion (function)
Eine Funktion kann nur In- Parameter bekommen und muss mindestens eine Return-
Anweisung besitzen. Dabei wird auch der Rückgabewert angegeben der von der Funktion an
die Aufrufstelle zurückgegeben wird: return betrag;.
2.3.5.2 Rechenprozesse (tasks)
Mit den Tasks wird es in Ada möglich Befehlsfolgen nicht nur sequenziell (nacheinander)
sonder auch parallel abzuarbeiten. Ein Ada- Programm wird von Grund auf im Rahmen einer
Haupttask ausgeführt. Der Programmierer hat die Möglichkeit noch weitere Task zu
vereinbaren, die dann nebeneinander und neben der Haupttask ausgeführt werden. Ein
Unterprogramm kann zur selben Zeit im Rahmen von verschiedenen Tasks ausgeführt
werden.
Auch Tasks sind in Spezifikation und Rumpf getrennt und müssen angegeben werden. Eine
Task, die im Vereinbarungsteil einer Programmeinheit deklariert wurde, wird direkt vor der
Ausführung der Anweisungen dieser Programmeinheit gestartet. Allerdings erst nachdem alle
Vereinbarungen abgearbeitet wurden.
2.3.5.2.1 Verzögerungsanweisungen
Damit Tasks nicht direkt nach einem Programmaufruf unkontrolliert ablaufen, gibt es die
Verzögerungsanweisungen. Zum Einen gibt es die Delay- Anweisung, die bewirkt, dass die
Task um die angegebene Zeit (in Sekunden) angehalten wird (delay 5.0; --Task wird 5
Sekunden angehalten). Hierbei kann aber lediglich garantiert werden, dass die Task für diesen
Zeitraum angehalten wird. Ob die Task danach sofort wieder anläuft, kann nicht garantiert
werden, da andere Task zu diesem Zeitraum ausgeführt werden könnten. Zum Anderen gibt es
die Delay- until- Anweisung die im Gegensatz zur relativen Zeitangabe der Delay-
Anweisung eine absolute Zeitangabe vorsieht: delay until time;.
2.3.5.2.2 Synchronisierung von Tasks
Um Tasks zu synchronisieren gibt es in Ada verschiedene
Möglichkeiten.
Das Rendezvous- Konzept sieht vor, dass zwei (oder
mehrere) Tasks zu einem Zeitpunkt synchronisiert werden
und dazwischen unabhängig voneinander ausgeführt
werden. Die schnellere Task muss dann, soll eine
Synchronisation stattfinden auf die langsamere Task
warten. Nach der Synchronisation laufen die Tasks dann
wieder unabhängig voneinander weiter. Der Grundaufbau
einer Rendezvousdeklaration ist in Abbildung 7
dargestellt. Formell muss eine Task einen Eingang (entry
date;) besitzen und dazu eine Accept- Anweisung (accept
date;) ausführen um zu bestätigen, dass sie für ein
Rendezvous bereitsteht. Der Eingang muss von einer
anderen Task aufgerufen werden (Sabine.date;), um so zu
übermitteln, dass auch sie für ein Rendezvous zur
Verfügung steht. Je nachdem welche Task zuerst diese
Bereitschaft bekundet wird angehalten bis die andere Task dem Rendezvous zustimmt. Dann
werden die Anweisungen nach dem Schlüsselwort „do“ abgearbeitet (die Tasks sind zu
diesem Zeitpunkt synchron) und danach geht dann jede Task wieder ihren eigenen Weg.
Abbildung 7 - Grundaufbau
Rendezvous- Konzept
Echtzeitprogrammierung mit Ada 14
Genau wie beim Aufruf von Prozeduren, kann auch der Aufruf zu einem Rendezvous
Parameter (in, out, in out) enthalten und wird analog zu Prozeduren formell so
aufgeschrieben.
Mit der Select- Anweisung (selektive Synchronisation) wird dieses Konzept noch erweitert.
Damit kann eine Task auch mehrere Eingänge besitzen und auswählen (z.B. nach dem FIFO -
Verfahren: first in, first out) welchem Rendezvous sie zustimmt. Danach wird die Task dann
ganz normal fortgeführt und die anderen Rendezvous finden nicht statt. Um zu gewährleisten,
dass mehrere Rendezvous nacheinander stattfinden können, stehen die Select- Anweisungen
oft in Schleifen. Eine andere Möglichkeit ist mit einer Delay- Anweisung die Task nur eine
gewisse Zeit auf ein Rendezvous warten zu lassen. Wird das Rendezvous innerhalb dieses
Zeitraums nicht durchgeführt, führt die Task eine alternative Anweisungsfolge aus.
Eine weitere Methode um Tasks zu synchronisieren sind die gemeinsam genutzten
Betriebsmittel (protected variables). Auch geschützte Objekte besitzen eine Spezifikation und
einen Rumpf (ähnlich einem Paket). Die Spezifikation besteht hierbei aus einem sichtbaren
und einem nicht sichtbaren (privaten) Teil. Hier müssen sämtliche Variablen als „private“
deklariert werden. Somit hat man von außen keine Möglichkeit auf diese Variablen
zuzugreifen und muss die Prozeduren innerhalb der Betriebsmittel aufrufen, da nur diese
Zugriffsrechte auf die Variablen haben.
Sollten gleichzeitig mehrere Tasks auf ein geschütztes Objekt lesend zugreifen, ist dies ohne
Probleme möglich. Schreibender Zugriff ist nur nacheinander erlaubt und wird vom
Ausführer überwacht.
2.3.5.3 Wiederverwendbare Bibliotheken (Pakete)
Pakete dienen dazu mehrere Unterprogramme zu gruppieren, können aber auch Typen und
Objekte beinhalten. Es kann sinnvoll oder nötig sein, dass Teile eines bestehenden
Programms wiederverwendet werden. Um zu gewährleisten, dass dieser Teil auch ohne das
restliche Programm funktionstüchtig ist, werden alle nötigen Unterprogramme und
Vereinbarungen zu einem Paket vereint. Solch ein Paket ist dann einfach einzubinden und
ermöglicht auch die Programmentwicklung mit mehreren, voneinander unabhängigen
Programmierern. Auch machen es Pakete möglich, eine Variable die in verschiedenen
Unterprogrammen benötigt wird als „globale“ Variable zu verwenden, um so die Löschung
durch das Unterprogramm nach dessen Ausführung zu verhindern (Variable bleibt mit ihrem
Wert bestehen).
Solch ein Paket besteht ähnlich wie ein Unterprogramm aus einem Spezifikationsteil (package
specification: package name is .. end name;) und einem Implementierungsteil (package body:
package body name is .. end name;). Diese Einheiten können auch getrennt voneinander
übersetzt werden. Die Vereinbarungen, welche im Paketrumpf beschrieben sind, sind
außerhalb des Paketes nicht sichtbar. Ein Paket ist alleinstehend nicht lauffähig. Hierzu wird
ein Unterprogramm benötigt, das die Programmeinheiten und Variablen aus dem Paket
aufruft. Hierzu muss allerdings erst einmal das Paket eingebunden werden. Dazu wird in die
erste Zeile der Datei das Paket mit dem Schlüsselwort „with“, gefolgt von dessen Namen
eingebunden. Folgt dahinter das Schlüsselwort „use“ mit dem Paketnamen, so sind sämtliche
Routinen aus diesem Paket aufrufbar ohne diese mit „Paketname.Prozedurname“ aufrufen zu
müssen.
3 Aufbau der MPS PA Compact- Workstation
Festo Didactic entwickelt industrienahe Aus- und Weiterbildungssysteme, um den
gewachsenen Bildungsanforderungen in der Industrie gerecht zu werden. Da es finanziell und
oft auch prozesstechnisch kaum möglich ist, Industrieanlagen für die Aus- und Weiterbildung
der eigenen Mitarbeiter stillzulegen, werden Modelle dieser Anlagen benötigt, um das
Echtzeitprogrammierung mit Ada 15
Verständnis der einzelnen Abläufe und Zusammenhänge zu vermitteln. Solche werden von
Festo Didactic entwickelt und wenn nötig betreut.
Eines dieser Modelle ist die in Abbildung 8 dargestellte MPS PA Compact- Workstation.
Abbildung 8 – MPS PA Compact- Workstation der Firma Festo Didactic
Diese Workstation ist ein Modell einer Industrieabfüllanlage und stellt ein Lernsystem für
vielerlei Regelungs- und Steuerungsaufgaben dar. Sie besitzt vier integrierte Regelstrecken,
die jeweils einzeln durch manuelles Umschalten der Kugelhähne betrieben werden können.
Hierdurch ist eine möglichst hohe Komplexität auf engstem Raum gewährleistet. Die
Füllstands-, Durchfluss-, Druck- und Temperaturregelstrecke ermöglichen eine weitreichende
Abdeckung von industriellen Automatisierungsaufgaben und die Verbindung mit
verschiedenen Technologien, wie pneumatischen Prozessantrieben, ergibt eine starke
praxisbezogene Relevanz. Pneumatische Antriebe bei Ventilen werden in der Industrie immer
häufiger bei der Steuerung von fluiden Strömungen eingesetzt, da sie in puncto Sicherheit und
Energieeffizienz deutliche Vorteile besitzen. Die Kombination von verschiedensten
Technologien in der Automatisierungstechnik wird heutzutage immer bedeutender.
Die Compact- Workstation vermittelt Aufgabenstellungen in den Bereichen:
Mechanik
Prozesssteuerung
Pneumatik / Drucklufttechnik
Sensoren / Aktoren
PLC
Geschlossene Regelkreissysteme
Echtzeitprogrammierung mit Ada 16
Geschlossene Regelkreissteuerung
Fehlerfindung
Die Anlage vereint dabei pneumatische, hydraulische sowie elektrische Komponenten.
In Abbildung 9 ist das R&I- Fließschema (Rohrleitungs- und Instrumenten- Fließschema) der
Anlage zu sehen:
V112V102
S
S115
V105P101Pump_P101
S111
LIC
B101
LSH
B114
Proximity_Switch_
Max_Level_B114
LSL
B113
Proximity_Switch_
Min_Level_B113
TIC
B104
Temperature_
Tank_B104
Float_Switch
E104
Sensor_Level_Tank_
B101
S112
Float_Switch_S
112
PIC
B103
B104
FIC
Flow_Meter_Pump_
B102
V106
V109
V104Proportional_Valve_V
106
Pressure_Tank_B103
Tank 101
Tank 102
Heating_Tank_101
VSSL
103
Abbildung 9 – R&I- Fließschema
Die Bestandteile der Anlage, welche eine Interaktion ermöglichen, werden nun bezogen auf
Abbildung 9 genannt und beschrieben:
Die Hauptbestandteile sind die zwei großen Behälter (Tank 101, Tank 102), die über
verschiedene Rohrleitungen miteinander verbunden sind. Hierbei können verschiedene
Regelkreise durch manuelles Öffnen bzw. Schließen der Kugelhähne aktiviert und deaktiviert
werden.
Außerdem verfügt das Modell über mehrere analoge und digitale Sensoren sowie einige
Aktoren.
Die Sensoren stellen alle nötigen Informationen über die Anlage bereit und kommunizieren
über das Kommunikationsmodul EasyPortUSB mit dem Steuerungsprogramm. Da eine USB-
Verbindung nur digitale Werte übermitteln kann, wird von dem EasyPortUSB- Modul die
analogen Messwerte (0 bis 10V) in einer 12bit- Auflösung, also in diskreten Werten von 0 bis
4095 übertragen. Diese Angaben müssen dann von der Software wieder in die entsprechenden
analogen Werte umgerechnet bzw. entsprechend interpretiert werden. Hierbei dient der
EasyPort lediglich als Transferschnittstelle zwischen der Software und der Anlage und
übernimmt keinerlei steuerungstechnische Funktionen. Es werden nur die
Sensorinformationen aus der Anlage an die Software übergeben und die Steuerungsbefehle
der Software an die Aktoren weitergeleitet.
Die Anlage verfügt über vier analoge Sensoren.
Echtzeitprogrammierung mit Ada 17
Analoge Sensoren [Garc12]:
B101 [Füllstandsensor Behälter 102]
ID Sensor_Level_Tank_B101
Sensortyp Ultraschallsensor
Beschreibung Der Sensor befindet sich an der Oberseite des Behälters 101 und misst die Entfernung bis zur Wasseroberfläche. Dadurch wird der Füllstand ermittelt. (Tank voll: 10V; Tank leer: 0V).
Messbereich Entfernung (50 - 345mm)
Ausgang Spannung (10 - 0V DC)
B102 [Durchflusssensor]
ID Flow_Meter_Pump_B102
Sensortyp Durchflusssensor
Beschreibung Der Sensor befindet sich direkt hinter der Pumpe und misst den Wasserdurchfluss durch das Rohr.
Messbereich Durchfluss (0,3 - 9,0l/min)
Ausgang Frequenz (40 - 1200Hz)
Durchflusssensor Messumformer [Frequenz zu Spannung]
ID f/U
Sensortyp Messumformer Frequenz zu Spannung
Beschreibung Der Messumformer konvertiert die, vom Durchflusssensor ausgegebene Frequenz in ein Spannungssignal.
Messbereich Frequenz (0 - 1kHz)
Ausgang Spannung (0 - 10V DC)
B103 [Drucksensor]
ID Pressure_Tank_B103
Sensortyp Drucksensor
Beschreibung Der Sensor misst den Wasserdruck in den Rohren, der durch die Pumpe und das Proportionalventil (V106) erzeugt wird.
Messbereich Druck (0 - 400mbar)
Ausgang Spannung (0 - 10V DC)
B104 [PT100 Temperatursensor]
ID Temperature_Tank_B104
Sensortyp Temperatursensor
Beschreibung Der Sensor misst die Wassertemperatur in Behälter 101.
Messbereich Temperatur (0 - 100°C)
Ausgang Spannung (0 - 10V DC)
Das Kommunikationsmodul EasyPortUSB unterstützt darüber hinaus 16 digitale Ein- und
Ausgänge. In der Anlage werden folgende digitale Sensoren verwendet.
Digitale Sensoren [Garc12] (Ausgang: boolean: true/false):
B102 [Durchflusssensor]
ID Flow_Meter_B102
Beschreibung Dieses Signal wird mit einem Hochgeschwindigkeitszähler benutzt, um die Frequenz zu messen.
Echtzeitprogrammierung mit Ada 18
S111 [Schwimmerschalter]
ID Float_Switch_S111
Beschreibung Mittlerer Füllstand Behälter 101.
S112 [Schwimmerschalter]
ID Float_Switch_S112
Beschreibung Mittlerer Füllstand Behälter 102.
B113 [kapazitiver Näherungsschalter]
ID Proximity_Switch_Min_Level_B113
Beschreibung Minimaler Füllstand Behälter 101. Die Heizung kann ab hier nicht mehr verwendet werden.
B114 [kapazitiver Näherungsschalter]
ID Proximity_Switch_Max_Level_B114
Beschreibung Maximaler Füllstand Behälter 101. Kugelhahn muss geschlossen sein.
S115 [Kugelhahn geschlossen]
ID Ball_Valve_Closed_S115
Beschreibung Kugelhahn ist geschlossen.
S116 [Kugelhahn geöffnet]
ID Ball_Valve_Open_S116
Beschreibung Kugelhahn ist geöffnet.
Des Weiteren verfügt die Anlage über vier Aktoren.
Aktoren [Garc12]:
V102 [Kugelhahn mit pneumatischem Prozessantrieb]
ID Ball_Valve_V102
Typ Kugelhahn mit pneumatischem Antrieb
Beschreibung Das Ventil steuert den Zufluss aus Behälter 102 in Behälter 101.
Steuerung Digitales Signal, um das Ventil zu öffnen oder zu schließen.
101 [Heizung Behälter 101]
ID Heating_Tank_101
Typ Heizung
Beschreibung Die Heizung erwärmt das Wasser in Behälter 101, falls der Füllstand nicht zu niedrig ist.
Steuerung Digitales Signal, um die Heizung an- bzw. auszuschalten.
P101 [Pumpe]
ID Pump_P101
Typ Pumpe
Beschreibung Die Pumpe kann in einem analogen oder digitalen Modus betrieben werden.
Steuerung Pump_P101_Preset_D_A: Auswahlsignal zwischen analogem und digitalem Betriebsmodus. Pump_P101: Im digitalen Betriebsmodus wird die Pumpe durch dieses Signal an- und ausgeschaltet.
Echtzeitprogrammierung mit Ada 19
Pump_P101_Analog: Im analogen Betriebsmodus steuert dieses Signal den Ausgangslevel der Pumpe.
V106 [Proportionalwegeventil]
ID Proportional_Valve_V106
Typ Elektrisches Ventil
Beschreibung Dies ist ein analoges Ventil, das den Durchfluss steuert, indem die Weite der Ventilöffnung variabel einstellbar ist. Dennoch kann es über ein Signal vollständig geöffnet und geschlossen werden.
Steuerung Proportional_Valve_V106: Dieses Signal öffnet und schließt das Ventil vollständig. Proportional_Valve_V106_Analog: Dieses Signal steuert die Weite der Ventilöffnung, um so den Durchfluss zu regulieren.
Die relevanten Kugelhähne, welche von Hand geöffnet und geschlossen werden können sind
in Abbildung 9 mit Vxxx bezeichnet. Hiervon ausgenommen sind V102 (Kugelhahn mit
pneumatischem Antrieb), V106 (Proportionalwegeventil) und V111 (nicht vorhanden).
4 Aufbau des vorhandenen Ada- Process- Controller
Das System basiert auf dem bereits vorhandenem Ada- Process- Controllers, der im Rahmen
der Masterarbeit von Miguel Garcia erstellt wurde.
Der Aufbau des Ada- Controllers ist in drei Hauptebenen unterteilt. Dies erleichtert den
Umgang mit komplexen Programmen deutlich und unterstützt das leichtere Verständnis des
Programms.
Die Hauptebenen sind:
Process Control Ebene:
Diese Ebene ist verantwortlich für die graphische Schnittstelle zum Benutzer und
ermöglicht das Starten und Stoppen der Anlage. Außerdem dient es zur Überwachung
und Steuerung der Anlage.
Process Variable Ebene:
Diese Ebene dient dazu die Befehle für das EasyPortUSB Modul zu encodieren und zu
decodieren.
Field Ebene:
Diese Ebene dient dazu mit dem seriellen Anschluss zu kommunizieren.
4.1 Field Ebene
Die Field Ebene kommuniziert direkt mit dem EasyPortUSB- Modul und übergibt diesem die
Werte für die Aktoren aus dem Steuerprogramm und liest die Sensorwerte, welche vom
EasyPort- Modul übermittelt werden aus.
Die Field Ebene ist unterteilt in vier Unterebenen:
Communication Manager
Communication Command
Communications Link
Module Interface
Echtzeitprogrammierung mit Ada 20
4.1.1 Communications Link Ebene
Diese Ebene stellt die Prozeduren zur Verfügung, die dazu verwendet werden den seriellen
Anschluss zu öffnen und zu schließen, sowie ihn auszulesen, ihn zu beschreiben und zu
konfigurieren.
Benutzt wird hierzu die Serial_Communication Bibliothek mit dem Standarddatentyp
„Ada.Streams.Stream_Element_Array“. Dieses Array muss allerdings, um vom
Steuerprogramm bearbeitet werden zu können in einen String umgewandelt werden. Hierzu
dient die Communications Link Ebene.
Die Hauptprozeduren sind ReadMessage, SendMessage und InitConnectPort.
Die Prozedur ReadMessage liest den Port aus und speichert alles in einem String.
Die Prozedur SendMessage überträgt die Informationen an den seriellen Port.
Die Prozedur InitConnectPort initialisiert und konfiguriert den Port.
4.1.2 Communication Command Ebene
Diese Ebene beschreibt die Funktionen und Prozeduren um mit dem EasyPortUSB- Modul zu
kommunizieren.
Hierfür werden im Grunde zwei Arten von Prozeduren verwendet. Die eine Art liest
Informationen aus dem Modul aus und die Andere übergibt Informationen an das Modul.
Die Funktion ReadI benutzt den speziellen Befehl um den Input auszulesen und gibt
den decodierten Wert (von Hex zu Dezimal) zurück.
Die Prozedur WriteO schreibt den Ausgang im Hexadezimal System aus.
Zusätzliche gibt es noch eine ConfigSetup Prozedur.
Die Prozedur ConfigSetup liest die Adresse des EasyPort aus und überprüft die
Richtigkeit der Antwort. Diese Nachricht wird als allererstes an den EasyPort
geschickt, um eine Kommunikation erst zu ermöglichen.
4.1.3 Communication Manager Ebene
Die Communication Manager Ebene stellt die Prozeduren zur Verfügung, um die Eingänge
aus dem EasyPort zu lesen und die Ausgänge an den EasyPort zu übergeben. Hierfür werden
drei Prozeduren verwendet.
Die Prozedur InitCommunications erstellt ein neues Objekt vom Typ EasyPort und
ermöglicht dann die Kommunikation mit dem EasyPort. Erst nachdem diese Prozedur
aufgerufen wurde, ist die Kommunikation mit dem EasyPort möglich. Diese Prozedur
ermöglicht außerdem den Anschluss und die Kommunikation mit mehreren
EasyPortUSB- Modulen.
Die Prozedur UpdateInputs liest sämtliche Eingänge aller EasyPorts aus und speichert
sie in dem jeweiligen Objekt.
Die Prozedur UpdateOutputs übergibt sämtliche Ausgänge an das EasyPortUSB-
Modul.
4.1.4 Module Interface Ebene
Die Module Interface Ebene stellt die Funktionen und Prozeduren zur Verfügung, welche für
die Konvertierung der Ein- und Ausgänge benötigt werden.
4.2 Process Variable Ebene
Die Process Variable Ebene dient dazu die Rohdaten der Sensoren in brauchbare
Informationen umzurechnen und die Befehle für die Ausgänge zu enkodieren und sie im
Wertebereich des EasyPorts auszugeben.
Echtzeitprogrammierung mit Ada 21
4.2.1 Analoge Schnittstellen
Das EasyPortUSB- Modul unterstützt vier analoge Eingänge und zwei analoge Ausgänge in
einem Wertebereich von entweder 0V DC bis 10V DC oder -10V DC bis +10V DC. Zur
digitalen Übertragung dieser Informationen wird vom EasyPort ein Wertebereich von 0 bis
4095 diskreten Wertenverwendet. Dies entspricht einer Auflösung von 12bit. In dieser Anlage
wird stets ein Wertebereich der Sensoren von 0V DC bis 10V DC benutzt.
Die Formeln zur Umrechnung zwischen der gewünschten Spannung und den Rohdaten und
umgekehrt lauten [Garc12]:
𝑆𝑝𝑎𝑛𝑛𝑢𝑛𝑔 =Rohdaten
4095∗ 10
Rohdaten =Spannung
10∗ 4095
4.2.1.1 Füllstandsensor B101[Garc12]:
ID Sensor_Level_Tank_B101
Sensortyp Ultraschallsensor
Beschreibung Der Sensor befindet sich an der Oberseite des Behälters 102 und misst die Entfernung bis zur Wasseroberfläche. Dadurch wird der Füllstand ermittelt. (Tank voll: 10V; Tank leer: 0V).
Messbereich Entfernung (50 - 345mm)
Ausgang Spannung (10 - 0V DC)
Anschluss Analoger Eingang 1
Funktion Sensor_Level_Tank_B101.get
𝐹ü𝑙𝑙𝑠𝑡𝑎𝑛𝑑 = (12𝑙
340𝑚𝑚) ∗ ((
345𝑚𝑚 − 50𝑚𝑚
4095) ∗ 𝑅𝑜ℎ𝑤𝑒𝑟𝑡 + 50)
4.2.1.2 Durchflusssensor [Garc12]:
ID Flow_Meter_Pump_B102
Sensortyp Durchflusssensor
Beschreibung Der Sensor befindet sich direkt hinter der Pumpe und misste den Wasserdurchfluss durch das Rohr.
Messbereich Durchfluss (0,3 - 9,0l/min)
Ausgang Frequenz (40 - 1200Hz)
ID f/U
Sensortyp Messumformer Frequenz zu Spannung
Beschreibung Der Messumformer konvertiert die, vom Durchflusssensor ausgegebene Frequenz in ein Spannungssignal.
Messbereich Frequenz (0 - 1kHz)
Ausgang Spannung (0 - 10V DC)
Anschluss Analoger Eingang 2
Funktion Flow_Meter_Pump_B102.get
𝐷𝑢𝑟𝑐ℎ𝑓𝑙𝑢𝑠𝑠 = 𝑅𝑜ℎ𝑤𝑒𝑟𝑡 ∗ (10𝑉
4095) ∗ (
1𝑘𝐻𝑧
10𝑉) ∗ (
9𝑙
𝑚𝑖𝑛1,2𝑘𝐻𝑧
)
Echtzeitprogrammierung mit Ada 22
4.2.1.3 Drucksensor [Garc12]:
ID Pressure_Tank_B103
Sensortyp Drucksensor
Beschreibung Der Sensor misst den Wasserdruck in den Rohren, der durch die Pumpe und das Proportionalventil (V106) erzeugt wird. Der Sensor befindet sich hinter der Pumpe.
Messbereich Druck (0 - 400mbar)
Ausgang Spannung (0 - 10V DC)
Anschluss Analoger Eingang 4
Funktion Pressure_Tank_B103.get
𝐷𝑟𝑢𝑐𝑘 = 𝑅𝑜ℎ𝑤𝑒𝑟𝑡 ∗ (10𝑉
4095) ∗ (
400𝑚𝑏𝑎𝑟
10𝑉)
4.2.1.4 Temperatursensor [Garc12]:
ID Temperature_Tank_B104
Sensortyp Temperatursensor
Beschreibung Der Sensor misst die Wassertemperatur im Behälter 101.
Messbereich Temperatur (0 - 100°C)
Ausgang Spannung (0 - 10V DC)
Anschluss Analoger Eingang 3
Funktion Temperature_Tank_B104.get
𝑇𝑒𝑚𝑝𝑒𝑟𝑎𝑡𝑢𝑟 = 𝑅𝑜ℎ𝑤𝑒𝑟𝑡 ∗ (10𝑉
4095) ∗ (
100°𝐶
10𝑉)
4.2.1.5 Pumpe [Garc12]:
ID Pump_P101
Typ Pumpe
Beschreibung Die Pumpe kann in einem analogen oder digitalen Modus betrieben werden.
Steuerung Pump_P101_Preset_D_A: Auswahlsignal zwischen analogem und digitalem Betriebsmodus. Pump_P101: Im digitalen Betriebsmodus wird die Pumpe durch dieses Signal an- und ausgeschaltet. Pump_P101_Analog: Im analogen Betriebsmodus steuert dieses Signal den Ausgangslevel der Pumpe.
Maximale Leistung
Durchfluss 10l/min
Eingang Spannung (0 - 10V DC)
Anschluss Analoger Ausgang 1
Funktion Pump_P101_Analog.set()
𝑅𝑜ℎ𝑤𝑒𝑟𝑡 = 𝑃𝑟𝑜𝑧𝑒𝑛𝑡 ∗ (4095
100)
4.2.1.6 Proportionalwegeventil [Garc12]:
ID Proportional_Valve_V106
Typ Elektrisches Ventil
Beschreibung Dies ist ein analoges Ventil, das den Durchfluss steuert indem die Weite der Ventilöffnung variabel ist. Dennoch kann es über ein Signal vollständig geöffnet und geschlossen werden.
Steuerung Proportional_Valve_V106: Dieses Signal öffnet und schließt das Ventil vollständig.
Echtzeitprogrammierung mit Ada 23
Proportional_Valve_V106_Analog: Dieses Signal steuert die Weite der Ventilöffnung um so den Durchfluss zu regulieren.
Maximaler Wert
Durchfluss 10l/min
Eingang Spannung (0 - 10V DC)
Anschluss Analoger Ausgang 2
Funktion Proportional_Valve_V106_Analog.set()
𝑅𝑜ℎ𝑤𝑒𝑟𝑡 = 𝑃𝑟𝑜𝑧𝑒𝑛𝑡 ∗ (4095
100)
4.2.2 Digitale Schnittstellen
Das EasyPortUSB- Modul unterstützt 16 digitale Ein- bzw. 16 digitale Ausgänge. Um die
Verarbeitung bzw. Schreib- und Lesevorgänge zwischen der Steuerung und dem EasyPort zu
beschleunigen, werden alle digitalen Ein- und Ausgänge auf einmal in einem 16 stelligen
Register ausgelesen. Hierfür wird dann nur ein einziger Befehl benötigt um alle Ein- bzw.
Ausgänge auszulesen bzw. zu beschreiben.
Die folgende Tabelle zeigt die Zuweisung der Sensoren zu den digitalen Eingängen [Garc12].
Eingang Sensor Funktion Beschreibung
0 B102 Flow_Meter_B102 Dieses Signal wird mit einem Hochgeschwindigkeitszähler verwendet um die Frequenz zu messen.
1 S111 Float_Switch_S111 Mittlerer Füllstand des Behälters 101.
2 S112 Float_Switch_S112 Mittlerer Füllstand des Behälters 102.
3 B113 Proximity_Switch_Min_Level_B113 Minimaler Füllstand des Behälters 101. Ab hier kann weder die Pumpe, noch die Heizung verwendet werden.
4 B114 Proximity_Switch_Max_Level_B114 Hoher Füllstand des Behälters 101. Ab hier muss der Kugelhahn geschlossen sein.
5 S115 Ball_Valve_Closed_S115 Kugelhahn ist geschlossen.
6 S116 Ball_Valve_Open_116 Kugelhahn ist geöffnet.
Die folgende Tabelle zeigt die Zuweisung der Aktoren zu den digitalen Ausgängen [Garc12].
Ausgang Aktuator Funktion Beschreibung
0 V102 Ball_Valve_V102 Der Kugelhahn mit pneumatischem Prozessantrieb steuert den Zufluss von Behälter 102 in Behälter 101.
1 E104 Heating_Tank_101 Heizung Behälter 101.
2 P101 Pump_P101_Preset_D_A Pumpenmodus (0 =̂ Digital, 1 =̂ Analog).
3 P101 Pump_101 Wenn der digitale Pumpenmodus aktiviert ist, schaltet dieses Signal die Pumpe ein.
4 V106 Proportional_Valve_V106 Das Proportionalwegeventil wird über dieses Signal angesteuert (0 =̂ Ausgeschaltet, 1 =̂ Eingeschaltet).
4.3 Process Control Ebene
Die Process Control Ebene steuert die Anlage. Ihr Hauptprogramm wird wie bei einer SPS
(Speicherprogrammierbare Steuerung) zyklisch abgearbeitet und wiederholt. Sie beinhaltet
Echtzeitprogrammierung mit Ada 24
die graphische Schnittstelle zum Benutzer und stellt Funktionen bereit um verschiedene
Szenarien auszuwählen, sowie die Anlage zu starten und zu stoppen.
4.4 Graphische Oberfläche
Die graphische Schnittstelle zum Benutzer wird über eine GUI aus der GTK- Bibliothek
realisiert. In dieser Bibliothek sind alle nötigen Elemente vorhanden um eine funktionale
Oberfläche bereitzustellen, die es dem Benutzer ermöglicht effizient auf die Anlage
zuzugreifen, sie zu steuern und zu überwachen.
4.5 Szenario Experiment
Um die Abfüllanlage zu steuern und den Fachpraktikumsversuch durchzuführen muss nach
Ausführung der exe- Datei „AdaController“ über die Schaltfläche oben links „Select
Scenario“ das Szenario „Experiment Scenario“ ausgewählt werden.
Abbildung 10 - Graphische Oberfläche zum Fachpraktikumsversuch
Das GUI des Praktikums, nach erfolgreicher Verbindung zur Anlage über die Schaltfläche
„Connect“, ist in Abbildung 10 dargestellt.
Die graphische Oberfläche ist in folgende Bereiche unterteilt:
Kommunikationssteuerung
Versuchssteuerung
Analoge Eingangssignale
Digitale Eingangssignale
Analoge Ausgangssignale
Digitale Ausgangssignale
Echtzeitprogrammierung mit Ada 25
4.5.1 Kommunikationssteuerung
Die Kommunikationssteuerung befindet sich oben unter der Überschrift ADA Experiment.
Sie umfasst den Button „Select Scenario“ mit dessen Hilfe ein erstelltes Szenario ausgewählt
werden kann. Im Rahmen des Ada Fachpraktikumversuchs ist hier das Szenario „Scenario
Experiment“ auszuwählen.
Der Button „Connect“ verbindet den PC mit der Compact Workstation und ermöglicht erst
dann eine Kommunikation mit der Anlage sofern ein Szenario ausgewählt wurde. Das
schwarze Label „Not Connected“ unterhalb des Buttons wechselt in ein grünes „Connected“
sofern eine erfolgreiche Verbindung hergestellt wurde. Sollte nach Betätigung des Buttons ein
rotes „Error Connection“ erscheinen, so konnte keine Verbindung hergestellt werden. Um den
Fehler zu beheben genügt es den USB- Stecker an der Rückseite des PC herauszuziehen und
wieder zu verbinden. Stellen Sie bitte sicher, dass Sie wieder den richtigen USB- Anschluss
auf der Rückseite des Computers verwenden.
4.5.2 Analoge Eingangssignale
Die Box „Analog Input Signals“ zeigt den aktuellen Messwert der analogen Sensoren an.
4.5.3 Digitale Eingangssignale
Die Box „Digital Input Signals“ zeigt den aktuellen Zustand der digitalen Sensoren.
4.5.4 Analoge Ausgangssignale
Die Box „Analog Output Signals“ ermöglicht die Eingabe eines analogen Wertes zur
Ansteuerung der analogen Aktoren Pumpe (P101) und Proportionalwegeventil (V106).
4.5.5 Digitale Ausgangssignale
Die Box „Digital Output Signals“ ermöglicht die Ansteuerung per Mausklick der digitalen
Aktoren Heizung (Heating_Tank_101) und elektrisches Ventil (V102), sowie das Ein- und
Ausschalten der Pumpe und des Proportionalwegeventils. Zudem kann hier für die Pumpe
zwischen dem analogen und digitalen Betrieb umgeschaltet werden.
4.5.6 Versuchssteuerung
Die oberste Box „Experiment Control“ ermöglicht die Steuerung des Praktikums.
Der Button „Starting Position“ stellt den gewünschten Startzustand her. Hier bedeutet dies,
dass das Ventil V102 geschlossen ist und sich der Wasserpegel von Tank 101 direkt unterhalb
des Sensors B113 (also B113 aus) befindet.
Der Button „Panic Switch“ hat die Funktion eines Notausschalters wie es in der Industrie
eigentlich bei jeder Anlage üblich ist. Er ist in Software realisiert und überführt die Anlage in
jedem Betriebszustand augenblicklich in einen sicheren Zustand. Das bedeutet, dass jeder
Aktor (Pumpe, Heizung, Ventile) ausgeschaltet wird. Nach Betätigung des Notausschalters ist
die weitere Bedienung der Anlage aber wieder uneingeschränkt möglich.
In der Mitte kann man zudem die gewünschte Temperatur für die Temperaturregelung im
Bereich zwischen 20°C .. 30°C einstellen und das Label unterhalb der Beschriftung
„Temperature Control“ zeigt farbig an, ob die Temperatursteuerung aktiv (grünes „Running“)
oder inaktiv (rotes „Stopped“) ist.
Um den Button „Start Control“ betätigen zu können, muss zuallererst der Startzustand
hergestellt werden, ansonsten ist die Betätigung ohne Funktion.
Der „Stop Control“- Button unterbricht das Automatisierungsprogramm in jeder Phase und
stellt den Startzustand wieder her. Nach Betätigung des „Stop Control“- Buttons ist die
weitere Bedienung der Anlage aber wieder uneingeschränkt möglich.
Echtzeitprogrammierung mit Ada 26
5 Benutzungsanleitung
Die Abbildung 11 zeigt die Ordnerstruktur des Ada- Process- Controllers. Um die ausführbare
exe- Datei mit der Projekt- Datei „experiment.gpr“ zu erstellen, muss diese Struktur
beigehalten werden.
In der Eingabeaufforderung wird mit dem Befehl „gnatmake -Pexperiment“ der
Programmcode kompiliert und die ausführbare exe- Datei „AdaController“ erstellt.
trunk
0_Field_Layer 1_Process_Variable_Layer 2_Process_Control_Layer
gui_module.adb
gui_module.ads
main_gui.adb
main_gui.ads
Emergency.adb
Emergency.ads
StartingPosition.adb
StartingPosition.ads
TemperatureControl.adb
TemperatureControl.ads
com_layer.adb
com_layer.ads
link_layer.adb
link_layer.ads
mngr_layer.adb
mngr_layer.ads
module_interface.adb
module_interface.ads
AdaController.adb
experiment.gpr
scenario_experiment.adb
scenario_experiment.ads
lib
Abbildung 11 - Die Ordnerstruktur des Ada- Process- Controllers
Echtzeitprogrammierung mit Ada 27
5.1 Mögliche Probleme beim Praktikumsversuch
Sollte beim Kompilieren des Programmcodes der Fehler auftreten, dass das Outputfile nicht
geöffnet werden konnte (access denied), dann muss der Prozess „AdaConroller.exe“ im Task
Manager beendet werden. Danach sollte eine Kompilierung möglich sein.
Sollte es zu einem Programmabsturz kommen, kann der AdaController einfach neu gestartet
und verbunden werden. Danach kann man die Anlage wieder steuern.
Sollte es nicht möglich sein, eine erfolgreiche Verbindung zur Anlage herzustellen, dann
muss der USB- Stecker an der Rückseite des PCs kurz gezogen und neu verbunden werden.
Danach sollte es wieder möglich sein eine Verbindung zur Anlage herzustellen. Hierbei sollte
beachtet werden, dass der USB- Anschluss (Port 4) beibehalten wird.
6 Beispielprojekt „Automatisierung einer Abfüllanlage“
6.1 Einführung
Der Geschäftsführer einer Chemikalienabfüllfabrik hat folgendes Problem. Neue Forschungen
haben ergeben, dass es bei längerer Standzeit und bei einer zu niedrigen Temperatur der
Flüssigkeit im Abfüllbehälter zu Ausscheidungen von bestimmten Chemikalien kommen
kann. Diese Chemikalien lagern sich im Behälter ab und verursachen zum Einen eine
Verringerung der Chemikalienkonzentration der abgefüllten Flüssigkeit. Zum Anderen kann
sich bei erneuter Befüllung des Behälters eine gefährlich hohe Konzentration in der
Flüssigkeit einstellen, wenn Verwirbelungen dafür sorgen, dass sich die Ablagerungen wieder
mit der Flüssigkeit verbinden. Der Abfüllprozess stellt das Ende der Produktionsanlage dar
und die Qualitätssicherung findet direkt vor dem Abfüllbehälter statt. Folglich gibt es keine
Überwachungseinheit, um die chemische Konzentration der Flüssigkeit direkt vor der
Abfüllung zu überprüfen.
Bei einem ordnungsgemäßen Betrieb der Anlage ist die Verweildauer der Flüssigkeit im
Abfüllbehälter zu gering, damit sich das beschriebene Phänomen einstellt. Allerdings
verlängert sich die Dauer bei einem Fehlerfall in der Anlage. Falls der Prozess unterbrochen
werden muss, könnte sich dann die Konzentration der Flüssigkeit ändern. Da die Abnehmer
der Flüssigkeiten so gut wie keine Toleranzen bei Konzentrationsschwankung hinnehmen
können und eine Routineüberprüfung des TÜV dieses Problem feststellte, muss der
Geschäftsführer schnell handeln.
Entweder muss ein sehr teures Überwachungssystem für den Abfüllbehälter installiert
werden, welches bei einem Fehlerfall aber die bereits vorhandene Flüssigkeit nicht
aufbereitet, oder es muss eine Lösung gefunden werden, um die Flüssigkeit bei einem
Fehlerfall auf einer gewissen Temperatur zu halten.
Wird dieses Problem nicht in kürzester Zeit behoben, droht der Firma die Stilllegung der
Anlage mit einem nicht absehbaren finanziellen Schaden.
Um Zeit und Geld zu sparen, entscheidet sich der Geschäftsführer für die Alternative eine
Temperaturregelung einzusetzen.
Sie als Softwareentwickler haben nun die Aufgabe diese und weitere Funktionen zu
implementieren.
6.2 Aufgabenstellung
Da bisher für die Anlage nur ein in Hardware realisierter Notausschalter existiert, sollen Sie
zunächst einen in Software realisierten Notausschalter für die Anlage entwerfen.
Echtzeitprogrammierung mit Ada 28
Da es sich bei der Anlage um ein Modell handelt muss am Anfang eine sinnvolle
Ausgangslage hergestellt werden, um die spätere Temperaturregelung ablauffähig zu machen.
Um zudem Ablagerungen einer Flüssigkeit in Behälter 102 zu vermeiden, muss die
Flüssigkeit auf eine bestimmte Temperatur gebracht und gehalten werden. Dazu sollen Sie
eine Temperaturregelung entwickeln. Da es nicht möglich ist, eine Heizung in Behälter 102
zu integrieren, entscheidet sich der Geschäftsführer dazu, einen ausgedienten Behälter mit
Heizung zu reaktivieren. Glücklicherweise sind die Behälter bereits durch ein
Rohrleitungssystem miteinander verbunden. Der Geschäftsführer stellt sich das System bei
einem Fehlerfall folgendermaßen vor:
Die Flüssigkeit die in Behälter 102 zwischengelagert wird, soll über das elektrische Ventil
V102 nach und nach in den reaktivierten Behälter 101 abgelassen werden und soll dort auf
eine gewisse Temperatur gebracht werden. Sobald die Temperatur den Sollwert erreicht hat,
wird die Heizung abgeschaltet und die Flüssigkeit zurück in Behälter 102 gepumpt. Dieser
Vorgang soll solange fortgesetzt werden, bis der Fehlerfall beseitigt wurde. Danach muss die
Ausgangslage wiederhergestellt werden. Damit ist die Regelung beendet.
Folgende Anforderungen werden an die Automatisierung gestellt:
Der Notausschalter soll zu jedem Zeitpunkt sämtliche Aktoren abschalten.
Solltemperatur der Flüssigkeit soll 23°C betragen
Die Automatisierung muss mit dem Button „Stop Control“ jederzeit beendet werden
können
Sobald der Fehler quittiert wurde (Stop- Button), muss die Ausgangslage
wiederhergestellt werden
Die Temperaturregelung darf nur gestartet werden können, falls die Ausgangslage
hergestellt wurde
Realisierung des Notausschalters:
Zur Realisierung des Notausschalters, muss zunächst die Datei Emergency.adb implementiert
werden. Die zugehörige Spezifikationsdatei befindet sich im Anhang.
Der Notausschalter soll innerhalb der Prozedur „PanicSwitch“ als Exception realisiert werden.
Der Notausschalter muss zu jeder Zeit die Anlage in einen sicheren Zustand überführen. Das
bedeutet:
Die Temperaturregelung muss angehalten werden
Das Ventil Valve_V102 muss geschlossen werden
Die Pumpe Pump_P101 muss ausgeschaltet werden
Der Pumpen Preset muss auf falsch gesetzt werden
Das Proportionalwegeventil Proportional_Valve_V106 muss geschlossen werden
Die Heizung Heating_Tank_101 muss ausgeschaltet werden
Nach Betätigung des Notschalters soll es weiter uneingeschränkt möglich sein die Anlage zu
steuern. Hierfür müssen sämtliche benötigten Variablen sinnvoll überschrieben werden. Es
wird empfohlen, nachdem die Ausgänge codiert und aktualisiert wurden, eine Delay-
Anweisung (500ms) auszuführen und dann den Anweisungsblock mit dem Überschreiben der
Variable „Panic_Switch_Hit“ zu beenden.
Realisierung der Ausgangslage:
Da es sich bei der Compact Workstation um ein Modell handelt, soll zunächst eine sinnvolle
Ausgangslage hergestellt werden, um die Temperaturregelung dann ablaufen zu lassen. Dazu
muss die Datei StartingPosition.adb implementiert werden. Die zugehörige
Spezifikationsdatei befindet sich im Anhang.
Echtzeitprogrammierung mit Ada 29
Die Ausgangslage bedeutet, dass das Ventil V102 geschlossen ist und sich der Füllstand des
Wassers in Tank 101 kurz unterhalb des Sensors B113 befindet. Sie soll zum Einen über die
Schaltfläche „Starting Position“ vom Benutzer aktiviert werden können, als auch automatisch
durch die Temperaturregelung.
Bevor die Ausgangslage hergestellt werden kann, soll zunächst überprüft werden, ob sich zu
Beginn zu wenig Flüssigkeit in Tank 101 befindet. Erst danach beginnt die Schleife
„StartPosition“ für die Ausgangslage.
Falls der Füllstand in Tank 101 unterhalb von Sensor B113 ist, soll der Variablen
„Low_Level_Tank_101“ wahr zugewiesen werden. Andernfalls soll der Variablen der Wert
falsch zugewiesen bekommen und die Variable „Start_Created“ ebenso.
Ablauf:
Falls die Ausgangslage nicht bereits hergestellt wurde, soll die Schleife „StartingPosition“
gestartet werden.
Zunächst werden die Eingänge aktualisiert und decodiert.
Falls der Füllstand in Tank 101 (Low_Level_Tank_101) zu niedrig ist, soll zunächst mittels
der Prozedur „FillingTank“ das Ventil V102 geöffnet und anschließend die Ausgänge codiert
und aktualisiert werden.
In der folgenden Schleife „FillingLoop“ werden lediglich die Eingänge aktualisiert und
dekodiert, gefolgt von einer kurzen Wartepause von 200ms. Die Schleife „FillingLoop“ soll
verlassen werden, sobald der Sensor B113 aktiv ist.
Danach muss mit der Prozedur „StopFillingTank“ (Aufbau identisch zu „FillingTank“) das
Ventil V102 geschlossen werden. Nun ist der zu niedrige Füllstand zu Beginn behoben und
die eigentliche Ausgangslage kann hergestellt werden.
Hierzu wird mit der Prozedur „CreateStart“ zunächst nochmals sichergestellt, dass das Ventil
V102 geschlossen wird. Anschließend wird das Proportionalwegeventil V106 komplett
geöffnet. Hierzu muss zunächst der Analogwert gesetzt werden und dann das Ventil V106
eingeschaltet werden. Erst anschließend wird die Pumpe eingeschaltet.
Abschließend sollten noch die Ausgänge codiert und aktualisiert werden.
Nun folgt eine Schleife „StartingLoop“ die identisch zur Schleife „FillingLoop“ aufgebaut ist.
Sie soll verlassen werden, sobald der Füllstand unterhalb des Sensors B113 ist.
Als Abschluss der Schleife „StartingPosition“ soll nun mit Hilfe der Prozedur „StopStart“ die
Pumpe und dann das Proportionalwegeventil V106 ausgeschaltet werden. Anschließend
müssen noch die Ausgänge codiert und aktualisiert werden.
Abschließend müssen dann noch die erforderlichen Variablen überschrieben werden. Nun ist
die Prozedur „StopStart“ vollständig und die Ausgangslage hergestellt. Beachten Sie, dass es
zu jedem Zeitpunkt möglich sein muss, die Anlage mit Hilfe des Notausschalters in einen
sicheren Zustand zu überführen.
Realisierung des Automatisierungsprogramms:
Zu Testzwecken soll der Fehlerfall aus Abschnitt 6.1 mittels des Buttons „Start Control“
durch den Benutzer im GUI ausgelöst werden. Hierdurch wird die Temperaturregelung
(„RunningLoop“) aktiviert, allerdings nur, wenn die Ausgangslage hergestellt wurde.
Nach dem Auslösen des Fehlers werden zunächst die Eingänge aktualisiert und decodiert.
Danach wird mit der Prozedur „StartSetLevel“ der aktuelle Füllstand von Behälter 102
ausgelesen und dann der Sollfüllstand (1,5 Liter weniger) bestimmt. Danach wird das Ventil
V102 geöffnet und die Ausgänge codiert und aktualisiert.
Die folgende Schleife „LevelLoop“ ist wieder identisch aufgebaut wie „FillingLoop“. Die
Schleife soll verlassen werden, sobald der Sollfüllstand erreicht ist.
Danach muss mittels der Prozedur „StopSetLevel“ das Ventil V102 wieder geschlossen
werden und die Ausgänge codiert und aktualisiert werden.
Echtzeitprogrammierung mit Ada 30
Nach wiederholter Aktualisierung und Decodierung der Eingänge wird die eingestellte
Solltemperatur für die Regelung mit dem Befehl „SetPoint_Temperature :=
Float(Get_Value(Set_Point_Spinner));“ eingelesen.
Mit der Prozedur „SetTemperature“ wird lediglich die aktuelle Temperatur ausgelesen und
der Variablen "CurrentTemperature" zugewiesen.
Falls nun die aktuelle Temperatur niedriger als die Solltemperatur ist, soll mit der Prozedur
„StartHeating“ die Heizung eingeschaltet werden mit darauffolgender Codierung und
Aktualisierung der Ausgänge.
Die folgende Schleife „TemperatureLoop“ ist identisch zur Schleife „FillingLoop“ und soll
verlassen werden, sobald die Solltemperatur erreicht wurde.
Nun muss mit der Prozedur „StopHeating“ (Aufbau identisch zu „StartHeating“) die Heizung
wieder abgeschaltet werden.
Bevor nun für eine Sekunde gewartet wird, soll die Möglichkeit gegeben sein, die Schleife
„RunningLoop“ über den Button „Stop Control“ oder „Panic Switch“ zu verlassen. Vergessen
Sie nicht, dass dies zu jedem Zeitpunkt der Temperaturregelung möglich sein muss.
Nachdem eine Sekunde gewartet wurde, soll die Ausgangslage wiederhergestellt und die
Schleife „RunningLoop“ verlassen werden.
Weitere Hinweise:
Das komplette Programm dieses Versuchs läuft innerhalb einer Task im
scenarioexperiment.adb ab. Alle Schleifen sind in dieser Task zu implementieren. Siehe
hierzu den entsprechenden Auszug im Anhang.
Die Pakete Emergency, StartingPosition und Temperaturecontrol sollen nur die Steuerung
von Aktoren und die Beschreibung von Variablen zusammenfassen, sodass das Programm in
der scenario_experiment Datei übersichtlicher bleibt. Halten Sie sich dabei konkret an die
jeweiligen Spezifikationsdateien. Hier sind alle benötigten Methoden mitsamt Parametern
beschrieben. Vergessen Sie auch nicht, dass alle diese Parameter benutzt werden müssen um
einen ordnungsgemäßen Ablauf sicherzustellen. Dies dient zu Lernzwecken um Ihnen
Modularität und der Umgang mit Parametern und Exceptions in Ada näherzubringen.
Beachten Sie, wenn Sie Aktoren steuern, müssen sie anschließend auch die Ausgänge
codieren und aktualisieren, damit die Befehle an die Anlage weitergegeben werden. Analog
müssen Sie mit den Eingängen verfahren, um den aktuellen Wert zu erhalten (Eingänge
aktualisieren und decodieren). Diese Methoden sind bereits vorhanden und können benutzt
werden. Siehe Anhang.
In den Abbildungen 12 und 13 sind die jeweiligen Flussdiagramme für die Ausgangslage und
die Temperaturregelung dargestellt.
Hinweis: Die Flussdiagramme stellen nur die Hauptfunktionen dar und sind nicht vollständig.
Für die genaue Beschreibung der einzelnen Programmteile, halten Sie sich an Kapitel 6.2.
Echtzeitprogrammierung mit Ada 31
Start Control
Level higher than
StopLevel?
Close valve V102
no
Temperature less than setpoint?
Stop Heating
Start Heating
Set Current Temperature
Temperature less than setpoint?
yes
no
no
Create starting position
SetStartLevel
SetStopLevel
Open Valve V102
Read SetPoint Temperature
Starting position
Close Valve V102
Turn off Pump P101
Start Created
Analog value V106 := 100.0
Open Valve V106
Turn on Pump P101
B113 = true?
no
Close Valve V106
Low_Level_Tank_101=true?
Open Valve V102yes B113 = false?
no no
Abbildung 12 - Flussdiagramm Ausgangslage
Abbildung 13 - Flussdiagramm Temperaturregelung
Echtzeitprogrammierung mit Ada 32
7 Aufgaben und Versuche
7.1 Hinweise zur Versuchsdurchführung
Die Hauptaufgabe dieses Praktikumsversuches liegt darin, das Automatisierungsprogramm zu
implementieren, welches in Abschnitt 6 beschrieben wurde. Die Hardwarenahe Steuerung der
Anlage wurde bereits realisiert und ist nicht Teil der Aufgabe dieses Versuches. Sämtliche
Programmeinheiten, die dazu dienen Sensordaten zu beschaffen und zu verarbeiten, sowie
Aktoren anzusteuern liegen bereits vor und können verwendet werden. Diese sind im Anhang
beigefügt und müssen vor Versuchsdurchführung durchgearbeitet werden. Es müssen keine
Rohdaten umgerechnet werden. Der Füllstandsensor gibt einen Wert in Litern zurück.
Der Versuch wird an der in Abschnitt 3 vorgestellten Compact- Workstation durchgeführt.
Als Prozessrechner steht ein PC mit Windows 8 zur Verfügung. Für die Ada-
Programmierung wird das Programm Notepad++ verwendet. Bitte speichern Sie sämtliche
Dateien die Sie bearbeiten ausschließlich in Ihrem Gruppenordner. Um Quellcode zu
kompilieren wird die Windows Eingabeaufforderung verwendet. Diese können Sie durch cmd
im Suchfenster des Windows- Startmenüs aufrufen. In der Eingabeaufforderung müssen Sie
zunächst auf Laufwerk C: navigieren. Dazu geben Sie C: ein und bestätigen mit Enter. Um in
der Eingabeaufforderung in verschiedene Ordner zu navigieren wird der Befehl cd verwendet
(cd Ordnername um in den Unterordner „Ordnername“ im aktuellen Ordner zu navigieren;
cd.. um in den übergeordneten Ordner zu navigieren). Um nun eine Datei zu kompilieren
benutzen Sie den Befehl gnatmake Programmname für eine einzelne Datei, den Befehl
gnatmake -PProjektname für ein Projekt. Um ein Programm auszuführen muss nur der
Programmname in der Eingabeaufforderung im jeweiligen Ordner aufgerufen werden.
Um zu gewährleisten, dass der Versuch sinnvoll und zügig bearbeitet werden kann, muss die
Anleitung komplett durchgelesen werden und die folgenden Aufgaben sind vor der
Versuchsdurchführung schriftlich zu bearbeiten. Darüber hinaus sind Ergebnisse während des
Versuchs zu protokollieren.
Hinweise zur Anlage: Das Ventil V105 muss zu jedem Zeitpunkt geschlossen sein. Um den
Versuch ordnungsgemäß durchzuführen stellen Sie bitte zu Beginn der Versuchsdurchführung
folgendes fest und füllen Sie die Checkliste aus:
Ventil V101 ist geschlossen
Ventil V103 ist geschlossen
Ventil V104 ist geschlossen
Ventil V105 ist geschlossen
Ventil V107 ist geöffnet
Ventil V108 ist geöffnet
Ventil V110 ist geöffnet
Ventil V112 ist geschlossen
7.2 Einführungsaufgaben
Vorbereitungsaufgabe 1: Ablauf von Rechenprozessen
a) Sobald alle Vereinbarungen eines Programms abgearbeitet wurden, werden sämtliche
darin deklarierten Tasks und die Haupttask (also das Hauptprogramm selbst wird auch
als Task ausgeführt) gestartet. Alle Tasks laufen dann in einer beliebigen Reihenfolge
unabhängig voneinander ab. Diese Reihenfolge kann bei einer erneuten
Echtzeitprogrammierung mit Ada 33
Programmausführung zufällig dieselbe sein, muss aber nicht. Nun wird aber häufig
eine bestimmte Reihenfolge benötigt. Welche Möglichkeiten hat der Programmierer
mit Ada um eine bestimmte Reihenfolge einzuhalten und wie kann er ein
unkontrolliertes Starten der Task beim Programmstart verhindern? Geben Sie ein
Beispiel für eine Taskvereinbarung und einen Taskrumpf an.
b) Sobald eine Task ihren Anweisungsteil abgearbeitet hat, wird sie beendet. Es ist nun
nicht mehr möglich diese Task aufzurufen außer durch einen Neustart des
Hauptprogramms. Oft wird aber eine mehrmalige Ausführung einer Task während
eines Programms benötigt. Welche Möglichkeit gibt es, um eine Task mehrmals
ausführen zu können? Geben Sie ein Beispiel für einen solchen Taskrumpf an.
Vorbereitungsaufgabe 2: zyklische Rechenprozesse und Parameterübergabe
Die Automatisierungstechnik verlangt häufig die Verwendung von zyklischen Prozessen (z.B.
Abtastregelungen). Zusätzlich ist es oft notwendig, dass Parameter zwischen
Rechenprozessen übergeben werden um beispielsweise Sensordaten einmal einzulesen und
woanders weiterzuverarbeiten. Das folgende Beispielprogramm "Dating" soll die
Funktionsweise von Parameterübergaben und der Synchronisation zwischen Tasks mit Hilfe
des Rendezvous- Konzepts verdeutlichen.
Neben dem Hauptprogramm sind noch vier weitere Tasks implementiert. Eva, Dirk, Paul und
John. Dirk, Paul und John stellen Eva eine Rendezvous Anfrage mit Namen „Request“ und
übergeben ihr einen Parameter vom Typ String namens „Gift“. Eva überprüft nun, ob das
„Gift“ „Flowers“ sind und verweist diese Task an ihren privaten Eingang „Rendezvous“. Sind
es keine „Flowers“ dann gibt sie aus, dass sie das „Gift“ nicht mag.
a) Die Task Eva besitzt also zwei Eingänge. Einen öffentlichen Eingang „Request“ und
einen privaten Eingang „Rendezvous“. Beide Eingänge übernehmen einen Parameter
namens „Gift“ vom Typ String. Erstellen Sie die Spezifikation der Task Eva und den
anderen benötigten Tasks. Beachten Sie hierbei die im Anhang verfügbare
Spezifikationsdatei Dating.ads.
Hinweis: Um einen privaten Eingang zu implementieren wird das Schlüsselwort
„private“ verwendet. Hierbei wird der oder die privaten Eingänge von „private“ und
„end Taskname;“ eingeschlossen.
b) Die Task Dirk führt wie die beiden Tasks Paul und John zuerst eine Delay-
Anweisung (2s) durch. Danach soll sich die Task entweder (select) mit Eva
synchronisieren und ihr hierbei den Parameter „Gift“ dem „Flowers“ zugewiesen wird
übergeben, oder aber, wenn die Task Eva nach 10s immer noch nicht für die
Synchronisation bereit ist eine alternative Anweisung ausführen (hier die Ausgabe
„Dirk: I do not want to wait any longer, bye.“ ausgeben). Die Tasks Paul und John
führen keinen alternativen Anweisungsblock durch. Pauls Parameter wird "Bread and
butter" und John's Parameter wird "Boot polish" zugewiesen. Erstellen Sie den Rumpf
der Tasks Dirk, Paul und.
Hinweis: Im Vereinbarungsteil wird TIO als Abkürzung für Ada.Text_IO deklariert
und kann analog dazu verwendet werden (Bsp: TIO.Put_Line („Hallo.“);.
c) Der Rumpf der Task Eva soll nun abschließend erstellt werden. Innerhalb einer For-
Schleife sollen die drei Synchronisationsanfragen abgearbeitet werden. Nachdem eine
Delay- Anweisung (1s) ausgeführt wurde soll die Task Eva die
Sychronisationsanfragen akzeptieren und verarbeiten. Dabei wird eine If-
Verzweigung verwendet. Sollte der Parameter „Gift“ den String „Flowers“ enthalten,
wird diese Task an den privaten Eingang weitergeleitet („requeue Eingangsname with
abort;“ der Zusatz „with abort“ ermöglicht der Task Eva sich zu beenden, auch wenn
die Synchronisation nicht zustande kommt und verhindert so ein Dauerwarten der
Task Eva und somit auch des kompletten Programms „Dating“). Sollte der Parameter
Echtzeitprogrammierung mit Ada 34
nicht „Flowers“ sein, so wird eine weitere Delay- Anweisung (1s) ausgeführt, gefolgt
von der Ausgabe „Eva: Sorry, but I don‘t like " &Gift& ".". Nun folgt eine weitere
Delay- Anweisung (1s) und die Ausgabe "Eva: I made my decision.". Nun soll in einer
darauffolgenden Select- Anweisung die Synchronisationsanfrage, welche an den
privaten Eingang umgeleitet wurde entweder akzeptiert werden und nach einer
weiteren Verzögerung (1s) die Ausgabe "Eva: Thank you for " &Gift& ". Let's go."
ausgegeben werden, oder es wird eine Verzögerung um 5s durchgeführt mit der
Ausgabe "Eva: I should have made up my mind faster." Erstellen Sie den Rumpf der
Task Eva.
Versuch 1: Vervollständigen Sie das Ada- Programm „Dating“ aus Vorbereitungsaufgabe 2
und erzeugen Sie die
Ausgabe aus Abbildung
14. Ändern Sie danach im
Rumpf der Task Eva die
Verzögerung nach der
For- Schleife von 1s auf
10s und führen Sie das
Programm erneut aus.
Begründen Sie das Ergebnis.
7.3 Implementierung der Ausgangslage und Notausschalterfunktionalität
Vorbereitungsaufgabe 3: Um sämtliche Funktionalitäten benutzen zu können müssen
diverse Variablen deklariert werden. Listen Sie alle benötigten Variablen auf und legen Sie,
wenn nötige einen sinnvollen Startwert fest. Es werden nur diese Variablen benötigt, die auch
als Parameter verwendet werden plus einer, die im Flussdiagramm benannt ist. Hinweis:
Insgesamt werden 10 Variablen benötigt wobei eine bereits gegeben ist. Beachten Sie hierbei
die im Anhang verfügbaren Dateien.
Vorbereitungsaufgabe 4: Entwerfen Sie den Notausschalter gemäß Abschnitt 6. Erstellen
Sie hierzu die Datei Emergency.adb. Beachten Sie hierbei die im Anhang verfügbare
Spezifikationsdatei Emergency.ads.
Vorbereitungsaufgabe 5: Entwerfen Sie die Funktionalität „Starting Position“. Erstellen Sie
hierzu die Datei StartingPosition.adb und den jeweiligen Teil im scenario_experiment.adb.
Beachten Sie hierbei die im Anhang verfügbare Spezifikationsdatei StartingPosition.ads. Die
Ausgangslage muss gemäß der Abbildung 12 entworfen werden.
Versuch 2: Implementieren Sie die entworfenen Programmteile aus den Vorbereitungsfragen
3 bis 5. Testen Sie zuerst die Funktionalität des Notausschalters indem Sie das Ventil V102
öffnen und dann den Notausschalter betätigen. Prüfen Sie nun, ob die korrekte Ausgangslage
hergestellt wird indem Sie die Schaltfläche „Starting Position“ betätigen. Lassen Sie nun
wieder etwas Wasser ab und testen Sie den Notausschalter während die Ausgangslage
hergestellt wird auf korrekte Funktionalität.
7.4 Implementierung der Temperaturregelung
Vorbereitungsaufgabe 6: Entwerfen Sie das Steuerungsprogramm Temperaturregelung aus
Kapitel 6. Erstellen Sie hierzu die Datei TemperatureControl.adb und den jeweiligen Teil im
scenario_experiment.adb. Beachten Sie hierbei die im Anhang befindliche Spezifikationsdatei
TemperatureControl.ads. Die Temperaturregelung muss gemäß der Abbildungen 13
entworfen werden.
Abbildung 14 - Ausgabe des Beispielprogramms "Dating"
Echtzeitprogrammierung mit Ada 35
Versuch 3: Implementieren Sie das aus Vorbereitungsaufgabe 6 entworfene
Automatisierungsprogramm. Testen Sie Ihr Programm mit Hilfe des Szenarios „Scenario
experiment“.
Zu Beginn stellen Sie die Ausgangslage her indem Sie den Button „Starting Position“
aktivieren. Nachdem die Ausgangslage hergestellt wurde, können Sie einen Fehler auslösen
und die Temperaturregelung starten, indem Sie den Button „Start Control“ betätigen. Warten
Sie nun mindestens zwei Kreisläufe ab und betätigen Sie dann den Button „Stop Control“.
Nun sollte sich die Ausgangslage wieder einstellen. Prüfen Sie nun, ob jeweils der
Notausschalter und der Stop- Schalter zu jeder Phase (Wasser ablassen, Wasser erhitzen,
Ausgangslage wiederherstellen) das gewünschte Ergebnis liefert. Erstellen Sie eine Checkliste
für jede mögliche Option um ihre Ergebnisse zu überprüfen.
Hinweis: Die Checkliste soll eine Tabelle mit 2 Zeilen und 3 Spalten darstellen. Es reicht die
Ergebnisse dann mit einem Haken zu bestätigen.
Echtzeitprogrammierung mit Ada 36
8 Literatur
[AXE12] AXE: Ada Reference Manual, ISO/IEC 8652:2012(E) Language and Standard
Libraries. 3. Aufl., AXE Consultans, 2012.
[Blie98] Blieberger, J.: Rendezvous mit Ada Eine echtzeitige Annäherung. TU Wien,
http://www.auto.tuwien.ac.at/~blieb/ADA-Skriptum_TeX/gesamt/node9.html,
1998.
[Fest] Festo: MPS PA Datenblätter. Festo Didactic.
[Fest09] Festo: Prozessautomation und Regelungstechnik. Festo Didactic, 2009
[Fest13] Festo: MPS PA Compact- Workstation. Festo Didactic, http://www.festo-
didactic.com/de-de/lernsysteme/prozessautomation,regelungstechnik/compact-
workstation/mps-pa-compact-workstation-messen,steuern-und-regeln-auf-
kleinstem-raum.htm?fbid=ZGUuZGUuNTQ0LjEzLjE4Ljg4Mi43NjQ3, 2013.
[Garc12] Garcia, M.: Concept and realization of a process control for a bottling plant in
Ada. Masterarbeit, IAS, 2012.
[Göhn10] Göhner, P.: Automatisierungstechnik I, Vorlesungsskript Sommersemester 2010.
IAS, 2010.
[Grud01] Grude, U.: Einführung in Ada Ada95- Skript. TFH Berlin, http://public.tfh-
berlin.de/~grude/SkriptAda.pdf, 2001.
[Hube01] Huber, S.: Die Programmiersprache Ada. http://www.huber-net.de/adagag.htm,
2001.
[IAS07] IAS: Versuch Nr. 2 Echtzeitprogrammierung mit Ada95 Versuchsanleitung. IAS,
2007.
Echtzeitprogrammierung mit Ada 37
9 Anhang
--------------------------------------------------------------------------------------
-- File: Dating.ads
-- Project: Example program Dating
-- Author: Chris Brand
--
-- Main unit of Example program Dating
--------------------------------------------------------------------------------------
with Ada.Text_IO;
procedure Dating is
task Eva is
entry Request (Gift : string); --Task call with parameter called "Gift" of type
string.
private
entry Rendezvous (Gift : string); --private task call; for other tasks not
visible/accessible.
end Eva;
task Dirk;
task Paul;
task John;
end Dating;
--------------------------------------------------------------------------------------
-- File: Dating.adb
-- Project: Example program Dating
-- Author: Chris Brand
--
-- Main unit of Example program Dating
--------------------------------------------------------------------------------------
with Ada.Text_IO;
procedure Dating is
--------------------------------------------------------------------------------
package TIO renames Ada.Text_IO; --TIO is used as an abbreviation. Useful for programs
with many integrated libraries instead of "use".
--------------------------------------------------------------------------------
-- Task specifications --
--------------------------------------------------------------------------------
-- Body of task Eva --
task body Eva is
begin
delay 2.0;
TIO.Put_Line ("Eva is waiting for requests...");
end Eva;
Echtzeitprogrammierung mit Ada 38
--------------------------------------------------------------------------------
-- Body of task Dirk --
--------------------------------------------------------------------------------
-- Body of task Paul --
--------------------------------------------------------------------------------
-- Body of task John --
--------------------------------------------------------------------------------
begin
delay 1.0;
TIO.Put_Line ("Dirk, Paul and John vie for the attention of Eva...");
end dating;
--------------------------------------------------------------------------------------
-- File: Emergency.ads
-- Project: Temperature Control
-- Author: Chris Brand
--
-- Unit of Panic Switch
--------------------------------------------------------------------------------------
package Emergency is
procedure PanicSwitch (Create_Start: in out Boolean; Start_Created: in out Boolean;
Running: in out Boolean; PreviousState_Running: in out Boolean; Panic_Switch_Hit:
in out Boolean);
end;
--------------------------------------------------------------------------------------
-- File: StartingPosition.ads
-- Project: Temperature Control
-- Author: Chris Brand
--
-- Unit of Starting Position
--------------------------------------------------------------------------------------
package StartingPosition is
procedure FillingTank;
procedure StopFillingTank;
procedure CreateStart;
procedure StopStart(Create_Start: in out Boolean; Start_Created: in out Boolean);
end;
--------------------------------------------------------------------------------------
-- File: TemperatureControl.ads
-- Project: Temperature Control
-- Author: Chris Brand
--
Echtzeitprogrammierung mit Ada 39
-- Unit of Temperature Control
--------------------------------------------------------------------------------------
package TemperatureControl is
procedure StartSetLevel(Start_Level_Tank_101: in out Float; Stop_Level_Tank_101: out
Float);
procedure StopSetLevel;
procedure SetTemperature(Current_Temperature: in out Float);
procedure StartHeating;
procedure StopHeating;
end;
--------------------------------------------------------------------------------------
-- File: scenario_experiment.adb
-- Project: Experiment
-- Author: Chris Brand
--
-- Main unit for experiment
--------------------------------------------------------------------------------------
--------------------------------------------------------------------------------------
-- following package import area must not be modified by students --
--------------------------------------------------------------------------------------
...
with Emergency; use Emergency;
with StartingPosition; use StartingPosition;
with TemperatureControl; use TemperatureControl;
------------------------------------
-- end package import area --
------------------------------------
package body scenario_experiment is
type Controller_Experiment_Pointer is access Controller_Experiment;
---------------------------------------------------------------------
-- beginning declaration area for experiment variables --
---------------------------------------------------------------------
Starting_Position_Boolean : Boolean := False;
--------------------------------------------------
-- end declaration area for experiment --
--------------------------------------------------
...
---------------------------------------------------------------------------------------
-- beginning experiment buttons, must not be modified by students --
---------------------------------------------------------------------------------------
-- this procedure gets activated by pressing the button Panic Switch
Echtzeitprogrammierung mit Ada 40
procedure Panic_Switch_Clicked (Widget : access Gtk_Widget_Record'Class) is
begin
Panic_Switch_Hit := true;
Set_Markup (Temperature_Control_L,("<span weight=""light""
color=""red"" size=""xx-large"">Stopped</span>"));
Emergency.PanicSwitch(Create_Start, Start_Created, Running,
PreviousState_Running, Panic_Switch_Hit);
end Panic_Switch_Clicked;
-- this procedure gets activated by pressing the button Starting Position
procedure Starting_Position_Clicked (Widget : access Gtk_Widget_Record'Class) is
begin
Create_Start := True;
end Starting_Position_Clicked;
-- this procedure gets activated by pressing the button Start Control
procedure Start_Control_Clicked (Widget : access Gtk_Widget_Record'Class) is
begin
if not (Task_Controller = null) then
if Start_Created = true then
Set_Markup (Temperature_Control_L,("<span weight=""light""
color=""green"" size=""xx-large"">Running</span>"));
Running := True;
PreviousState_Running := True;
end if;
end if;
end Start_Control_Clicked;
-- this procedure gets activated by pressing the button Stop Control
procedure Stop_Control_Clicked (Widget : access Gtk_Widget_Record'Class) is
begin
if not (Task_Controller = null) then
Set_Markup (Temperature_Control_L,("<span weight=""light""
color=""red"" size=""xx-large"">Stopped</span>"));
Running := False;
if PreviousState_Running = true and Panic_Switch_Hit = false then
Create_Start := true;
end if;
end if;
end Stop_Control_Clicked;
-----------------------------------
-- end experiment buttons --
-----------------------------------
...
----------------------------------------------------------------
-- beginning of programming area for experiment --
----------------------------------------------------------------
task body Controller_Experiment is
-- temperature used as set point with initial value 23.0°C (possible range 20.0°C till 30.0°C)
Echtzeitprogrammierung mit Ada 41
SetPoint_Temperature: Float := 23.0;
begin
P_area.P;
--------------------------------------------
-- here the process control begins --
--------------------------------------------
while Destroy = false loop
UpdateInputs;
Decode_Inputs;
-----------------------------------------------------------------------------------------------
-- following if statements must not be modified by students since it is for safety
of the plant --
-----------------------------------------------------------------------------------------------
if Pump_P101.get = true then
Safety.DigitalStartPump;
while Flow_Meter_Pump_B102.get > 0.40 and Panic_Switch_Hit =
false and Pump_P101.get = true loop
UpdateInputs;
Decode_Inputs;
delay 0.2;
end loop;
Safety.DigitalStopPump;
elsif Pump_P101_Preset_D_A.get = true then
Pump_Analog_Value := Float(Get_Value(Pump_P101_Analog_L));
Safety.AnalogStartPump(Pump_Analog_Value);
while Flow_Meter_Pump_B102.get > 0.40 and Panic_Switch_Hit =
false and Pump_P101_Preset_D_A.get = true loop
UpdateInputs;
Decode_Inputs;
delay 0.2;
end loop;
Safety.AnalogStopPump;
end if;
---------------------------------------
-- end of safety if statements --
---------------------------------------
------------------------------
-- low level tank 101? --
------------------------------
----------------------------------
-- end low level tank 101 --
----------------------------------
------------------------------------------------------------------------------
-- here the loop StartPosition for the starting position begins --
------------------------------------------------------------------------------
Echtzeitprogrammierung mit Ada 42
StartPosition:
---------------------------------------------------------------
-- end loop StartPosition for the starting position --
----------------------------------------------------------------
------------------------------------------------------------------------------------
-- here the loop RunningLoop for the temperature control begins --
------------------------------------------------------------------------------------
---------------------------------------------------------------------
-- end loop RunningLoop for the temperature control --
---------------------------------------------------------------------
Code_Outputs;
UpdateOutputs;
delay 0.2;
end loop;
--------------------------------------------------------
---------- end of process control -----------------
-- end of programming area for experiment --
--------------------------------------------------------
------------------------------------------------------------------
-- following area must not be modified by students --
------------------------------------------------------------------
P_area.V;
Task_Controller := null;
exception
when others =>
P_area.V;
Set_Markup (Connect_Status,("<span weight=""light"" color=""red"" size=""xx-
large"">Error Connection</span>"));
Task_Controller := null;
end Controller_Experiment;
procedure Destroy_Scenario is
begin
Ball_Valve_V102.set(false);
Pump_P101.set(false);
Pump_P101_Preset_D_A.set(false);
Proportional_Valve_V106.set(false);
Heating_Tank_101.set(false);
Destroy := True; -- Protect variable
P_area.P;
Code_Outputs;
UpdateOutputs;
P_area.V;
end Destroy_Scenario;
...
end scenario_experiment;