# Gutes und Böses oder was sollte man nicht machen (TwinCAT/CoDeSyS)



## suud (19 September 2008)

Hallöchen,

lese interessehalber schon länger bei euch im Forum mit. Doch da ich jetzt selber mal eine SPS-Steuerung (mit TwinCAT PLC also SoftSPS) programmieren darf/muss und auf dem Gebiet noch keine Erfahrung habe, sind mir da einige allgemeine Fragen in den Sinn gekommen.
Erstmal zu mir: Ich bin Informatiker und programmiere schon sehr lange in allen möglichen Sprachen, eben das was am besten passt. Das ist also nicht das Problem bzw. vermutlich doch, denn ich bin objektorientiertes Denken gewöhnt. Von den Segnungen der modernen Hochsprachen findet man im SPS-Gebiet aber leider nicht viel. Jedenfalls empfinde ich das alles als sehr gewöhnungsbedürftig. Und wenn ich AWL sehe fange ich recht schnell an nach Handschellen und Peitsche zu suchen. ;-) Dagegen ist x86 Assembler ja schon ne richtige Hochsprache.
OK genug Balbla, hier mal meine Fragen/Verständnisprobleme, oder wie im Titel geschieben: Was sollte man wie machen bzw. was kann man, aber sollte man auf keinen Fall machen? 


1. Ich schreibe gerade einen FB zu Ansteuerung eines Motorventils. Es gibt an EAs die Endschalter AUF und ZU (E_AUF, E_ZU), das Motor-Signal Auffahren und Zufahren (M_AUF, M_ZU) und eine aktuelle Position (ACTPOS) die über eine Poti ausgewertet wird.
Dem Baustein wird zusätzlich noch eine Soll-Position übergeben (SETPOS).
Der FB Kopf würde allgemein also so aussehen:

```
FUNCTION_BLOCK FB_VxMotor
VAR_INPUT
    SETPOS: INT := 0; (* Soll-Position *)
    ACTPOS: INT := 0; (* Ist-Position *)
    E_AUF: BOOL := FALSE; (* Endschalter AUF Signal *)
    E_ZU: BOOL := FALSE; (* Endschalter ZU Signal *)
END_VAR
VAR_OUTPUT
    M_Zu: BOOL := FALSE; (* Motor Zufahren Signal *)
    M_Auf: BOOL := FALSE; (* Motor Auffahren Signal *)
END_VAR
```
Ich könnte ihn aber auch so schreiben:

```
FUNCTION_BLOCK FB_VxMotor
VAR_INPUT
    SETPOS: INT := 0; (* Soll-Position *)
    ACTPOS AT %I*: INT := 0; (* Ist-Position *)
    E_AUF AT %I*: BOOL := FALSE; (* Endschalter AUF Signal *)
    E_ZU AT %I*: BOOL := FALSE; (* Endschalter ZU Signal *)
END_VAR
VAR_OUTPUT
    M_Zu AT %Q*: BOOL := FALSE; (* Motor Zufahren Signal *)
    M_Auf AT %Q*: BOOL := FALSE; (* Motor Auffahren Signal *)
END_VAR
```
Dann könnte ich die Ein- und Ausgänge direkt in TwinCAT verknüpfen. Andernfalls würde ich alle direktn Ein- und Ausgänge in extra Arrays anlegen und die Werte in den Array entsprechend an den FB übergeben.
Was ist da die "richtige" Lösung?

Die 3. Möglichkeit sieht so aus:

```
FUNCTION_BLOCK FB_VxMotor
 VAR_INPUT
     SETPOS: INT := 0; (* Soll-Position *)
 END_VAR
VAR
    ACTPOS AT %I*: INT := 0; (* Ist-Position *)
     E_AUF AT %I*: BOOL := FALSE; (* Endschalter AUF Signal *)
     E_ZU AT %I*: BOOL := FALSE; (* Endschalter ZU Signal *)
     M_Zu AT %Q*: BOOL := FALSE; (* Motor Zufahren Signal *)
     M_Auf AT %Q*: BOOL := FALSE; (* Motor Auffahren Signal *)
 END_VAR
```
Dann kann ich die Variablen immernoch in TwinCAT verknüpfen aber im Progamm nicht mehr von aussen zugreifen.
Wann deklariert ihr was wie wo? Wo kommen die direkten EA-Variablen hin, wenn der Baustein ein physikalisch vorhandenes Gerät repräsentiert?

Nächste Frage: 
Wenn ich eine Variable in einem FB als VAR_INPUT deklariere kann ich sie ja trotzdem innerhalb des FB ändern und die geänderte Variable von aussen Abfragen, also so als wäre es ein VAR_IN_OUT. Hintergrund der Frage ist, dass ich bei obigem FB z.B. noch ein RESET-Eingang als VAR_INPUT deklarieren könnte der alle internen Variablen zurücksetzt. Diesen Eingang könnte ich dann innerhalb des FB, nachdem ich den Reset durchgeführt habe, wieder zurücksetzen.
Warum kann man das? Und "darf" man das machen, bzw. macht es Sinn?

Und noch eine Grundsätzliche Frage:
Ich muss eine Steuerung + Visualisierung am PC schreiben. Was gesteuert wird sind letztlich nur ein Haufen Ventile, der Rest ist reine Steuerungslogik, also wann welches Ventil wie weit öffnet etc.
Würdet ihr die komplette Steuerungslogik auf der SPS implementieren oder nur die Teile, die die Ventile steuern + Sicherheitsabfragen etc. und den "komplexen" Steuerungsteil, also die Logik mit in die Visualisierung packen?
Komplexe Vorgänge lassen sich nunmal wesentlich eleganter in einer objektorietierten Hochsprache implementieren, wodurch auch die Fehleranfälligkeit sinkt. Pro / Contra?
EDIT: In meinem Fall ist letzteres bereits vorhanden, also eine reine PC-Steuerung die die Ventile über exterene proprietäre Hardware ansteuert. Daher soll das jetzt per SPS gemacht werden. Die Software wird aber trotzdem komplett neu entwickelt, es spielt also fast keine Rolle, dass der Programmcode für die Logik eigentlich schon vorhanden ist.

Naja, sind vermutlich sau blöde Fragen aber wenn man im SPS-Bereich noch nichts gemacht hat ist das alles erstmal nicht so klar. Habe leider noch kein Buch "SPS für C++ Pogrammierer" o.ä. gefunden. ;-)
Danke schon mal für eure Hilfe.
Werde aber sicher noch ein paar mehr Fragen haben wenn sie mir wieder einfallen. Aller Anfang ist halt schwer.


----------



## johnij (19 September 2008)

Ich kriege Kopfschmerzen, wenn ich dein Buch lese.....



suud schrieb:


> .
> noch kein Buch "SPS für C++ Pogrammierer" o.ä. gefunden. ;-)


 
Ich programmiere zur Zeit in C#,Java,C/C++, VB....
Sps-Programmierung (AWL,FUP,SCL ) habe ich mir selbst beigebracht nach dem Motto "Lerning by doing" (das Forum hier hat auch viel geholfen)

Du sollst Dir die Online -TIA-Unterlagen runterladen (es wäre nicht schlecht dir eine SPS zu besorgen zum üben). 

Fragen ohne Grundlagen brint eher wenig


----------



## suud (19 September 2008)

johnij schrieb:


> Ich kriege Kopfschmerzen, wenn ich dein Buch lese.....



War nicht meine Absicht. 



> Ich programmiere zur Zeit in C#,Java,C/C++, VB....
> Sps-Programmierung (AWL,FUP,SCL ) habe ich mir selbst beigebracht nach dem Motto "Lerning by doing" (das Forum hier hat auch viel geholfen)


Dito.



> Du sollst Dir die Online -TIA-Unterlagen runterladen (es wäre nicht schlecht dir eine SPS zu besorgen zum üben).
> 
> Fragen ohne Grundlagen brint eher wenig


Hm ist vielleicht nicht richtig rübergekommen.
Also ich habe hier die Beckhoff-Doku sowie 3 EtherCAT-Buskoppler mit einigen Klemmen, angeschlossenen Ventilen & Sensoren etc. und TwinCAT PLC als SPS. 
Ist also alles da zum Rumspielen. 
Nur beim Rumspielen sind mir ja eben diese Fragen aufgekommen.


----------



## zotos (19 September 2008)

Ich habe den "Roman" auch nur überflogen ;o)

Ich würde bei der 1. Version bleiben. Bei FCs und FBs halte ich die Zuordnung zu den Speicherbereichen %I,%Q,%M für ungünstig. Wenn sich später rausstellt das man das doch über eine andere Variable in den Baustein führen möchte stört diese Zuordnung.

@johnij: TIA (Total Irre Abzocke) ist von Deinem Arbeitgeber und hat mit Beckhoff/CoDeSys wenig zu tun.


----------



## vierlagig (19 September 2008)

[off topic]



johnij schrieb:


> Sps-Programmierung (AWL,FUP,SCL ) habe ich mir selbst beigebracht



*ROFL* ...dieser prozess wird von dir hoffentlich noch nicht als abgeschlossen angesehen ... da fehlt noch bißchen was ...

[/off topic]


----------



## trinitaucher (19 September 2008)

Zu den VAR_IN_OUT:
Die sind ähnliche eines Pointers. Sie MÜSSEN an der Bausteininstanz mit Variablen oder Werten belegt, es findet kein umkopieren statt.
Bei VAR_INPUT oder VAR_OUTPUT wird umkopiert auf bausteininterne Variablen.

Zu der Deklaration:
1. Werte mit "0" oder "FALSE" musst du nicht initialisieren. Das macht TwinCAT sowieso
2. Die Speicherzuordnung der 3. Variante finde ich persönlich auch gut, nämlich immer dann, wenn du einen universellen Baustein hast, dessen Grundfunktion mit I/Os immer gleich sind. Gerade für Bausteine, die komplette Einheiten, wie Motoren, Pumpen oder Ähnliches steuern und dazu noch in verschiedenen Programmen wiederverwendet werden sollen.
Auch bei der Verknüpfung im System-Manager vereinfacht es die Sache. Wenn du später mehr oder weniger Bausteininstanzen im Programm hast, musst du nicht nachträglich welche in der MAIN-Programmdeklaration hinzufügen oder löschen. Die I/Os sind auch direkt dem jeweiligen Baustein im System Manager zugeordnet,  was die Verknüpfung vereinfacht, z.B.:

```
MAIN.fbMotorsteuerung1.Eingang1
MAIN.fbMotorsteuerung2.Eingang1
```
Zugriff auf diese bausteininternen Variablen sind im Programm über fbMotorsteuerung2.Eingang1 genauso möglich. Damit greifst du zwar auf einen Wert zu, der nicht als VAR_INPUT / OUTPUT gegeben ist (Vorsicht beim Schreiben auf den bausteininternen Ausgang!), aber oft sind diese I/Os ohnenhin nur für den Baustein selbst wichtig.
Ansonsten kann man gleich über eine Deklaration im MAIN nachdenken.


----------



## hugo (19 September 2008)

wenn du erst mit sps anfängst und bereits hochsprachen kennst würde ich dir st empfehlen das ist nichts anderes als pascal, und wenn du c kannst kannst du auch pascal.

ansonsten lade dir mal die oscat open source bibliothek (www.oscat.de)
dort findest du hunderte von routinen alle im source code die du verwenden oder auch nur ansehen kannst.

die oscat lib ist ausschliesslich in st geschrieben und deshalb der source code auch gut lesbar.

einen kleine ansatz von objekt orientierung gibt es aber ansonsten bewegen wir und mit twincat / codesys 2.3 wirklich in der steinzeiot der softwarentwicklung

codesys 3.0 wird dann objektorientiert, das gibts auch schon aber es gibt hier nur eine begrenzte anzahl von spsen die das unterstützen.
z.b. die speedway von wago
codesys 3.0 ist wirklich ein gewaltiger schritt vorwärts in richtung stand der technik.


----------



## suud (22 September 2008)

trinitaucher schrieb:


> 2. Die Speicherzuordnung der 3. Variante finde ich persönlich auch gut, nämlich immer dann, wenn du einen universellen Baustein hast, dessen Grundfunktion mit I/Os immer gleich sind. Gerade für Bausteine, die komplette Einheiten, wie Motoren, Pumpen oder Ähnliches steuern und dazu noch in verschiedenen Programmen wiederverwendet werden sollen.



Wo wäre denn der Vorteil im Vergleich zur 2. Variante?



> Auch bei der Verknüpfung im System-Manager vereinfacht es die Sache. Wenn du später mehr oder weniger Bausteininstanzen im Programm hast, musst du nicht nachträglich welche in der MAIN-Programmdeklaration hinzufügen oder löschen.


Das verstehe ich jetzt nicht ganz. Um mehr oder weniger Instanzen zu haben muss ich doch auch mehr oder weniger Instanzen im MAIN-PG erstellt haben?!



> Die I/Os sind auch direkt dem jeweiligen Baustein im System Manager zugeordnet,  was die Verknüpfung vereinfacht, z.B.:
> 
> ```
> MAIN.fbMotorsteuerung1.Eingang1
> ...


Interessant, wäre jetzt garnicht auf die Idee gekommen auf die internen Variablen von aussen zuzugreifen. 
Aber ich sehe immernoch nicht den Vorteil der 3. Variante gegenüber der 2.



			
				hugo schrieb:
			
		

> codesys 3.0 wird dann objektorientiert, das gibts auch schon aber es gibt hier nur eine begrenzte anzahl von spsen die das unterstützen.
> z.b. die speedway von wago
> codesys 3.0 ist wirklich ein gewaltiger schritt vorwärts in richtung stand der technik.


Das ist doch mal 'ne gute Nachricht.
Der Code-Editor scheint mir auch wesentlich moderner daherzukommen.
Müsste es nicht möglich sein mit Codesys 3 compilierten Code mit TwinCAT zu laden? Also das wird doch zu AWL übersetzt und am reinen CPU-Assembler dürfte sich doch eigentlich nichts geändert haben?
Wäre ja zumindest sehr schön wenn TwinCAT 3 auch mit Codesys 3 arbeiten würde.
Weiss dazu jemand was?

Wo ich mir immernoch unsicher bin, ist ob die Steuerung komplett in der SPS laufen sollte oder ob der Logik-Teil besser in die Visu kommt. Hat den Nachteil, dass die Steuerung nur läuft wenn auch die Visu läuft. 
Andererseits frage ich mich, wie man mit etwas so primitivem wie ST eine komplexe Steuerungslogik implementieren soll, ohne dass der Vorteil der SPS durch die hohe Fehleranfälligkeit beim Programmieren wieder verloren geht? Von der Wartbarkeit und Flexibilität was Erweiterungen angeht mal ganz abgesehen.

Und nochmal ne ganz doofe Frage:
Sehe ich das richtig, dass die Merker (%M*) nur benötigt werden, wenn man auf Speicherbereiche der Klemmen zugreifen will, die weder Ein- noch Ausgänge sind? Also alles was im Prozessabbild nicht angezeigt wird?


----------



## Werner29 (22 September 2008)

suud schrieb:


> Müsste es nicht möglich sein mit Codesys 3 compilierten Code mit TwinCAT zu laden? Also das wird doch zu AWL übersetzt und am reinen CPU-Assembler dürfte sich doch eigentlich nichts geändert haben?


Nein das ist nicht möglich. Und schon die Voraussetzung stimmt nicht. Es wird nicht in AWL übersetzt sondern in Objektcode, und ausserdem hängt da ja insgesamt noch ein bisschen mehr dran als nur code runterladen und laufen lassen.


suud schrieb:


> Wäre ja zumindest sehr schön wenn TwinCAT 3 auch mit Codesys 3 arbeiten würde.
> Weiss dazu jemand was?


 Die nächste Generation TwinCAT wird auch wieder auf CoDeSys aufsetzen.
Die Nummerierung weiss ich nicht.


suud schrieb:


> Andererseits frage ich mich, wie man mit etwas so primitivem wie ST eine komplexe Steuerungslogik implementieren soll, ohne dass der Vorteil der SPS durch die hohe Fehleranfälligkeit beim Programmieren wieder verloren geht? Von der Wartbarkeit und Flexibilität was Erweiterungen angeht mal ganz abgesehen.


  Tschuldigung, aber das kommt ein ziemlich arrogant rüber. Ich sehe nicht
wo ST Nachteile gegenüber Pascal oder C haben soll.
Ich kenne riesige Projekte, die damit realisiert wurden, gerade mit TwinCAT, mit tausenden von Bausteinen, und vielen Megabyte generiertem Code.
Das funktioniert wunderbar, nur können muss man es halt.


suud schrieb:


> Sehe ich das richtig, dass die Merker (%M*) nur benötigt werden, wenn man auf Speicherbereiche der Klemmen zugreifen will, die weder Ein- noch Ausgänge sind? Also alles was im Prozessabbild nicht angezeigt wird?


Merker kannst du vergessen.


----------



## MarkusP (22 September 2008)

suud schrieb:


> [/code]Ich könnte ihn aber auch so schreiben:
> 
> ```
> FUNCTION_BLOCK FB_VxMotor
> ...



Ich mach es genau so, das ist ja genau die Stärke von TwinCAT. Ich stelle aber häufig fest, daß sogar eingefleischte Beckhoff Programmierer diese Möglichkeit nicht nutzen oder gar nicht kennen. Variablenlisten schreibe ich, seit ich TwinCAT verwende, nicht mehr. Wenn ich in einem Programm mit 1000 E/A's 5 "händisch" deklarierte habe, sind es viele. Zudem müssen die E/A's des FB im Code nicht mehr behandelt werden, können aber. (damit kann man z.B. nicht verwendete Eingänge eines FB immer noch extern auf TRUE oder FALSE setzen)
Damit kann man sehr gut einheitliche FB's bauen, mit zig Eingängen, die bei Bedarf blind geschaltet werden. Variante 3 scheidet damit dann natürlich aus, da so deklarierte Variablen nicht mehr über TwinCAT PLC-Control beschrieben werden könenn. (sind ja lokale - private Variablen)

Wenn Du dann noch die E/A's automatisch verknüpfen lässt, bist Du schon auf der Siegerstraße. Alles in allem, habe ich durch Umstellung auf Beckhoff eine Zeitersparnis von mehr als 60% erreichen können. Und das bereits im ersten Jahr, wo für uns alles neu war. Händisch getippt oder gemalt wird nicht mehr viel. (--> Codegeneratoren, Schnittstelle zu EPLAN etc.)

Im Unterschied zu Deinem Ansatz, übergebe ich die Variablen aber in einer Struktur, dann hat der Baustein im besten Fall nur einen Eingang oder Ausgang (=Struktur mit allen deklarierten Eing- und Ausgängen) Wenn Du jemals einen Eingang nachträglich hinzufügen oder entfernen willst, wirst Du mir für den Tip sehr dankbar sein. Wenn man z.B. mit CFC arbeitet, wird unter Umständen die Grafik "zerstört" und Anschlüsse werden gelöscht. Das merkt man sogar nicht sofort, erst ein <Alles Übersetzen> bringt diese Warnung an das Tageslicht.

Übrigens macht Beckhoff dies selbst auch zum Teil so >> Eingangsstrukturen für komplexe Klemmen.

Das spartanische Erscheinungsbild der Programmieroberfläche hat mich Anfangs auch etwas gestört, heute bin ich doch sehr zufrieden damit. Früher hatte ich auch grafisch sehr aufgemotzte Programmiersysteme, dabei blieb jedoch das Wesentliche auf der Strecken. Zudem bin ich Programmierer und kein Maler 

Auf die Implementierung von Codesys V3.0 warte ich auch schon, Beckhoff wird sich mit diesem Schritt meines Wissens nach aber noch etwas Zeit lassen. Die Akzeptanz bei den Hardcore AWL-Programmierern wird noch abzuwarten sein. Übrigens kann man bereits jetzt sehr gut programmieren, zudem es AKTIONEN bei den Bausteinen gibt. Dies ist im weitesten Sinne ähnlich einer Methode bei der Objektprogrammierung. (verzeih' mir bitte den Vergleich) Zusammen mit den Strukturen und Pointer-Adressierung, habe ich bis jetzt alles lösen können. (sogar unser Hochsprachen C++ bzw. C# Programmierer ist von TwinCAT positiv überrascht, er kannte bis dato nur klassische SPS System)

Zusammenfassend muss ich sagen, dass ich mich von vielem, das ich in den letzten 20 Jahren gelernt habe, loslösen musste, und mir ein anderes Denken aneignen musste, um die wirklichen Vorteile eines Systems wie TwinCAT nutzen zu können. Das geht über die Funktionalität von Codesys noch darüber hinaus.

So, genug der Lobhudelei,

liebe Grüße

Markus.


----------



## trinitaucher (22 September 2008)

suud schrieb:


> Wo wäre denn der Vorteil im Vergleich zur 2. Variante?
> ....
> Das verstehe ich jetzt nicht ganz. Um mehr oder weniger Instanzen zu haben muss ich doch auch mehr oder weniger Instanzen im MAIN-PG erstellt haben?!


Die 3. Variante trennt strickt zwischen I/Os, die nur den FB selbst "was angehen" und solchen, die man regulär auch im Hauptprogramm (MAIN) benutzt.
Wenn du I/Os im MAIN deklarieren willst (weil du die dort auch benutzt), kannst du die an die FBs anlegen.  (über die Input/Outputs). Wenn die I/Os nur im FB stehen, dann sind sie über den normalen FB-Aufruf nicht sichtbar. Erst die "Zwischenlösung" über FB.Variable lässt sie sichtbar werden.
Im System Manager bei TwinCAT besteht der Unterschied darin, dass du die I/Os entweder unter "MAIN.Ausgang" findest, oder unter "MAIN.fbBaustein.Ausgang", also direkt dem FB zugeordnet.
Rein technisch besteht kein Unterschied.

Wenn du in den Baustein-In-/Outputs auch noch physikalische Adressen reinpackst (deine 2. Variante), sieht es deklarationstechnisch so aus, dass du beim Baustein-Aufruf im MAIN einen Aus- oder Eingang siehts, der "offiziell" belegt werden kann, aber ja schon durch eine direkte I/O-Verknüpfung beschrieben wird. Das könnte zu Missverständnissen oder Doppelbelegungen führen. Und das könnte bei großen Programmen schnell zur Unübersichtlichkeit führen.
Daher trenne ich immer strickt zwischen bausteininternen I/Os und solchen, die auch für's restliche Programm wichtig sind.


suud schrieb:


> Wo ich mir immernoch unsicher bin, ist ob die Steuerung komplett in der SPS laufen sollte oder ob der Logik-Teil besser in die Visu kommt. Hat den Nachteil, dass die Steuerung nur läuft wenn auch die Visu läuft.
> Andererseits frage ich mich, wie man mit etwas so primitivem wie ST eine komplexe Steuerungslogik implementieren soll, ohne dass der Vorteil der SPS durch die hohe Fehleranfälligkeit beim Programmieren wieder verloren geht? Von der Wartbarkeit und Flexibilität was Erweiterungen angeht mal ganz abgesehen.


Wenn ich dürfte, würde ich dir mal eines unserer Programme schicken. Da is nichts mit "primitiv". Wir erledigen SPS-Logik, NC-Steuerung (Achskopplungen), Visu, Datenbankhandling und Diagnose über TwinCAT PLC und NC-I  => Alles mit ST :TOOL:


----------



## suud (24 September 2008)

Vielen Dank für eure ausführlichen Antworten und Tipps. 
Ich denke mit der Zeit kommt dann auch der Durchblick, wie überall, oder fast überall. 
Beschäftige mich aber auch erst seit 2 Wochen aktiv damit, von daher hab ich noch ein bischen was vor mir.

Wo ich gerade dran denke fällt mir aber noch eine speziellere Frage zu TwinCAT ein.
Kann dazu aber auch gerne einen neuen Thread aufmachen, falls das besser ist.
Wie läßt sich denn am besten eine Art Watchdog-Task/Programm implementieren. Ich möchte gerne mit einem Programm in einem anderen Task überwachen, ob mein Haupt-Task noch läuft. Wenn er nicht mehr läuft, sollen bestimmte Geräte in einen sicheren Zustand gebracht werden (z.B. Ventile zufahren).
 Gibt's da eine besonders elegante/sichere Methode, z.B. über die Verwendung von Bus-Controllern statt Bus-Kopplern o.ä?


----------



## kiestumpe (24 September 2008)

Zunächst mal voraus, ich habe schon länger nichts mehr mit TwinCat gemacht, aber sowohl die Variante 2 und 3 werfen bei mir mehr Fragen auf.
Soll den der FB seine Daten kapseln, oder ist das gar nicht die Absicht?
Also ich würde Variante 1. verwenden. 
Den AT- Befehl nehm ich eigentlich nur dann, wenn mal ein Word oder DWord in einzelne Bits aufgedröselt werden soll.
Ansonsten soll gibt's doch noch die IN-OUT-Schnittstellen.
Ich sehe in 2. und 3. keine wirklichen Vorteil, ausser dass es komplizierter wird.


----------



## trinitaucher (28 September 2008)

kiestumpe schrieb:


> Also ich würde Variante 1. verwenden.
> ...
> Ansonsten soll gibt's doch noch die IN-OUT-Schnittstellen.
> Ich sehe in 2. und 3. keine wirklichen Vorteil, ausser dass es komplizierter wird.


Wir haben es in unserer "Programmierrichtlinie" so vereinbart, dass Variablen eines FBs, die dort als Inputs oder Outputs deklariert sind, generell im übergeordneten Programmteil deklariert sein müssen und auch nur dort dem Baustein übergeben werden.
Das würde bedeuten, dass alle E/A-Verknüpfungen für die FBs z.B. im MAIN zu deklarieren sind. Bei entsprechend vielen FB-Instanzen müssen ebensoviele E/As deklariert werden. Wird eine neue Instanzt hinzugefügt, darf man die E/A-Deklaration nicht vergessen.
Kapselt man die E/As für den FB, wird die E/A-Variable automatisch durch die FB-Deklaration erstellt (oder umgekehrt auch wieder gelöscht).
Die IN_OUT-Schnittstelle sind ja quasi "Pointer". Hier muss man sehr acht geben, welcher Programmteil diese Variable beschreibt.
Je größer und verschachtelter ein Programm wird, umso mehr hilft einem die Datenkapselung... meine Meinung.


kiestumpe schrieb:


> Den AT- Befehl nehm ich eigentlich nur dann, wenn mal ein Word oder DWord in einzelne Bits aufgedröselt werden soll.


Verwechselst du hier vielleicht CoDeSys und Step7 SCL? Der AT-Befehl kann in CoDeSys nur zur direkten Adressierung von E/As oder Merkern genutzt werden (AT %I..., AT %Q, AT %M...)
WORDs aufschlüsseln funktioniert mit dem "."-Operator (wWord.1).


----------



## Ralle (28 September 2008)

Was Beckhoff angeht, befinde ich mich auch noch im Anfängerstatus, komme ja aus der Step7-Ecke. Die Variante 2 finde ich sehr interessant, spart offensichtlich durchaus viel Arbeit. Variante 3 würde ich eher ablehnen, FB-eigene Daten (lokale) sollten auch da bleiben, wo sie hingehören und nie von "außen" geschrieben oder auch gelesen werden.

Frage zu Variante 2: wo genau wird denn dann der wirkliche physikalische Eingang zugewiesen.

@MarkusP: automatische Verknüpfung der E/A, kannst du das mal ein wenig genauer beschreiben

Ein kleines Beispiel zur "Übergabe als Struktur" würde auch sehr lehrreich sein, ich kann mir das zwar in etwa vorstellen, aber auch hier, als Beckhoff-Neuling, wie bekommst du die wirklichen physikalischen E/A in die Struktur.


----------



## trinitaucher (28 September 2008)

Ralle schrieb:


> ...Variante 3 würde ich eher ablehnen, FB-eigene Daten (lokale) sollten auch da bleiben, wo sie hingehören und nie von "außen" geschrieben oder auch gelesen werden.
> 
> Frage zu Variante 2: wo genau wird denn dann der wirkliche physikalische Eingang zugewiesen.


Variante 3 kapselt ja genau diese FB-eigenen "lokalen" Variablen.
Bei Variante 2 gehören die E/As zum FB, können aber im Falle der Inputs sowohl vom übergeordneten Programm, als auch von den physikalischen Inputs beschrieben werden. Zuweisungen sind hier nicht mehr eindeutig.  Solche Durchmischungen sollten meiner Meinung nach vermieden werden.


----------



## suud (29 September 2008)

Ich habe mich nun auch für Variante 3 zusammen mit dem Tipp, die Ein- und Ausgangsvariablen in Structs zusammenzuführen entscheiden. Wenn ich im FB dann z.B. schreibe
sp := IN.SetPos;
OUT.ActPos := ap;
kann ich direkt am Namen sehen, was Sache ist.
Und die EAs sind meiner Meinung nach auch eher zu Kapseln, da sie zumindest in diesem Fall nur den FB intern etwas angehen.
Übrigens steht auch hier
http://www.ipsta.de/download/automationstechnik/Kap4_CoDeSys.pdf
als Richtlinie auf Seite 4-10 ganz oben, dass VAR_INPUT und VAR_OUTPUT nicht auf Adressen gelegt werden darf. Vermutlich eben wegen der möglichen Doppel-Beschreibung. Variante 2 ist also eher "böse".


----------



## trinitaucher (30 September 2008)

Ralle schrieb:


> Ein kleines Beispiel zur "Übergabe als Struktur" würde auch sehr lehrreich sein, ich kann mir das zwar in etwa vorstellen, aber auch hier, als Beckhoff-Neuling, wie bekommst du die wirklichen physikalischen E/A in die Struktur.


Deklaration der Structuren:

```
TYPE ST_StructIn:
  STRUCT
     bIn1: BOOL;
     bIn2: BOOL;
   END_STRUCT
END_TYPE

TYPE ST_StructOut:
  STRUCT
     bOut1: BOOL;
     bOut2: BOOL;
   END_STRUCT
END_TYPE
```
Im FB dann:

```
VAR
stStructIn AT%I*: ST_StructIn;
stStructOut AT%Q*: ST_StructOut;
END_VAR
```
oder gleich die Adresszuweisung in der Structur und nicht im Baustein durchführen.

Nachteil der Strukturlösung:
- Soll eine Version des FB  weniger oder mehr Eingänge haben, hat das Auswirkungen auf alle anderen FBs.
- Wenn im System Manager die Verknüpfungen durchgeführt sind und nachträglich an der Struktur was geändert wird (hinzufügen oder löschen einer Variable) werden alle Verknüpfungen gelöscht! Bei entsprechend vielen Variablen in den Strukturen ist das sehr ärgerlich 

... is Geschmacksache.


----------

