TIA E/A Adressen zur Laufzeit bestimmen

NBerger

Level-3
Beiträge
1.390
Reaktionspunkte
387
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo erstmal,
Gibt es eine Möglichkeit zur Laufzeit die Ein/Ausgangsadressen zu bestimmen ?

In der Art :

L P#Sensor_1
...

Sollte möglicht für 300/400 1200 u. 1500 funktionieren.
 
@c.wehn
Wie passt die Antwort zur Fragestellung?

@TE

Was willst du denn genau machen? Also beschreibe mal deine Aufgabenstellung.
Gesendet mit Tapatalk



Ich dachte dort wird die Peripherieadressierung erklärt... Also auf Eingänge direkt zuzugreifen und nicht auf das Prozessabbild.
 
Zuletzt bearbeitet:
Hi NBerger

erstens wozu und zweitens von welchen Adressen sprichst du? Wenn du ein Tag hast, dann hast du doch schon die Adresse. Da gibt es nichts mehr zu bestimmen.

Wenn es um Parameter von FC und FB geht, dann muss man zwischen einfachsten Typen (wie INT und REAL) und komplizierteren (wie UDT) unterscheiden. Daumenregel (mit hundert Ausnahmen) die einfachen per Wert, die komplizierteren per Referenz.
FB-Parameter werden über die Instanz übergeben. Beim Zugriff auf den Parameter bekommst du den Wert aus der Kopie im DB. Wenn du die Adresses eines FB-Parameter erfragst, dann ist dessen Adresse in der Instanz des FB. Was nutzt die? Das ist bestimmt nicht die E/A Adresse von dem was du angelegt hast.

Spannender sind FC-Parameter. Bei 300/400 werden Werte per Referenz übergeben, beim Zugriff wird durch MC7 dereferenziert. Das hat total krumme Effekte. Du legst am Input ein EB10 an. Nun programmierst du innen ein T #para:p. Damit schreibst du dann auf PAB10 und nicht wie du vielleicht erhofft hast auf PEB10. (Hey, wer mach so einen Blödsinn) Gut das das bei der 1500 nicht mehr geht. Aber um zu deiner ursprünglichen Frage zurück zu kommen. Wenn du nach der Adresse von P##para fragst, dann hast du tasächlich im Akku die Adresse E10.0. So kodiert wie das auch im Adressregister liegen würde. Wenn der Aufruf aber nicht mit E, A oder M versorgt wird, dann wird es schon wieder seltsam. Zumeist findest du einen Verweis auf den L-Stack des Aufrufers. Scheinbar wird vorher rein und nacher raus kopiert, ganz so wie beim FB. Solltest du mit mehreren Ablaufeben arbeiten und der FC wird durch einen anderen OB unterbrochen, ergeben sich ganz komische Effekte. Wird im aufgerufenen FC auf den Paramter geschieben, dann wirkt das bei E,A und M sofort. Die unterbrechende Ebene sieht sofort was geschrieben wurde. Bei Versorgung mit DB oder L, arbeitest du im FC mit einer Kopie. Der geschriebene Wert wird erst sichtbar wenn der FC wieder verlassen ist. Für das Lesen gilt das Gleiche, die Auswirkungen sind halt anders. Der Unterbrecher kann dir deine mit EAM versorgten Parameter kaputt machen, bei DB und L gewinnt der FC.

Bei der 1200/1500 werden die Parameter aber wie beim FB übergeben. Die einfachen per Wert, die komplizierteren per Referenz. Ich weiß nur nicht wo. Eine Instanz gibt es nicht und im L-Stack sind sie auch nicht. :confused: Trotzdem sind sie da und das ist auch gut so. Es gibt keine Unterschiede/Probleme wenn verschiedene Ablaufebenen unterwegs sind -- das ist sogar noch besser :cool:. Aber zurück zu deiner Frage: Adressen ... es gibt keine Adressen. Die sind total unwichtig :rolleyes:.

Wozu willst du die Adressen haben, wenn du doch nur auf Kopien arbeitest.

schönen Tag auch
HB

wer wird denn gleich in die Luft gehen
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Hi NBerger

erstens wozu und zweitens von welchen Adressen sprichst du? Wenn du ein Tag hast, dann hast du doch schon die Adresse. Da gibt es nichts mehr zu bestimmen.

Wenn es um Parameter von FC und FB geht, dann muss man zwischen einfachsten Typen (wie INT und REAL) und komplizierteren (wie UDT) unterscheiden. Daumenregel (mit hundert Ausnahmen) die einfachen per Wert, die komplizierteren per Referenz.
FB-Parameter werden über die Instanz übergeben. Beim Zugriff auf den Parameter bekommst du den Wert aus der Kopie im DB. Wenn du die Adresses eines FB-Parameter erfragst, dann ist dessen Adresse in der Instanz des FB. Was nutzt die? Das ist bestimmt nicht die E/A Adresse von dem was du angelegt hast.

Spannender sind FC-Parameter. Bei 300/400 werden Werte per Referenz übergeben, beim Zugriff wird durch MC7 dereferenziert. Das hat total krumme Effekte. Du legst am Input ein EB10 an. Nun programmierst du innen ein T #para:p. Damit schreibst du dann auf PAB10 und nicht wie du vielleicht erhofft hast auf PEB10. (Hey, wer mach so einen Blödsinn) Gut das das bei der 1500 nicht mehr geht. Aber um zu deiner ursprünglichen Frage zurück zu kommen. Wenn du nach der Adresse von P##para fragst, dann hast du tasächlich im Akku die Adresse E10.0. So kodiert wie das auch im Adressregister liegen würde. Wenn der Aufruf aber nicht mit E, A oder M versorgt wird, dann wird es schon wieder seltsam. Zumeist findest du einen Verweis auf den L-Stack des Aufrufers. Scheinbar wird vorher rein und nacher raus kopiert, ganz so wie beim FB. Solltest du mit mehreren Ablaufeben arbeiten und der FC wird durch einen anderen OB unterbrochen, ergeben sich ganz komische Effekte. Wird im aufgerufenen FC auf den Paramter geschieben, dann wirkt das bei E,A und M sofort. Die unterbrechende Ebene sieht sofort was geschrieben wurde. Bei Versorgung mit DB oder L, arbeitest du im FC mit einer Kopie. Der geschriebene Wert wird erst sichtbar wenn der FC wieder verlassen ist. Für das Lesen gilt das Gleiche, die Auswirkungen sind halt anders. Der Unterbrecher kann dir deine mit EAM versorgten Parameter kaputt machen, bei DB und L gewinnt der FC.

Bei der 1200/1500 werden die Parameter aber wie beim FB übergeben. Die einfachen per Wert, die komplizierteren per Referenz. Ich weiß nur nicht wo. Eine Instanz gibt es nicht und im L-Stack sind sie auch nicht. :confused: Trotzdem sind sie da und das ist auch gut so. Es gibt keine Unterschiede/Probleme wenn verschiedene Ablaufebenen unterwegs sind -- das ist sogar noch besser :cool:. Aber zurück zu deiner Frage: Adressen ... es gibt keine Adressen. Die sind total unwichtig :rolleyes:.

Wozu willst du die Adressen haben, wenn du doch nur auf Kopien arbeitest.

schönen Tag auch
HB

wer wird denn gleich in die Luft gehen

Hä?
Ich hab die Frage anders interpretiert...
Du willst die Symbol Adressierung der Absoluten Zuordnung während der Laufzeit bestimmen?!

Bin mal gespannt was hier wirklich gewusst werden will :)
 
Hä?
Ich hab die Frage anders interpretiert...
Du willst die Symbol Adressierung der Absoluten Zuordnung während der Laufzeit bestimmen?!

Bin mal gespannt was hier wirklich gewusst werden will :)

symbol_of( %e1.0 ) soll dann wohl einen STRING liefern.
Wir sind doch nicht bei .Net :p -- obwohl da geht das auch nicht.

Und ein STRING kann es auch nicht sein, denn TIA kann chinesische Variablennamen --- :sw22:
 
Bei der 1200/1500 werden die Parameter aber wie beim FB übergeben. Die einfachen per Wert, die komplizierteren per Referenz.
Das beschreibt der Programmierleitfaden für S7-1200/S7-1500 (Stand V1.1 Oktober 2013) ab Kapitel 3.3 aber anders.
Die bunten Bilder zeigen: die Aussagen gelten ausdrücklich für FB und FC.

* IN-Parameter: Übergabe per Wert (Call-by-value), der FB/FC erhält eine Kopie des Aktualparameters
Abbildung 3-15 zeigt ausdrücklich einen STRING, der in den IN-Parameter kopiert wird

*INOUT-Parameter: Übergabe per Referenz (Call-by-reference), jeder Zugriff im FB/FC arbeitet auf den referenzierten Original-Aktualparameter

3.3.2 Übergabe per Referenz (Call-by-reference) mit InOut-Schnittstellentyp schrieb:
Empfehlung
• Nutzen Sie bei strukturierten Variablen (z.B. vom Typ ARRAY, STRUCT, STRING, …) generell den InOut-Schnittstellentyp, um den benötigten Datenspeicher nicht unnötig zu vergrößern.
:ROFLMAO: ... und damit der Compiler ein versehentliches Schreiben auf Parameter mit eigentlich IN-Funktion garantiert nicht anmeckert. (An INOUT kann man auch keine Konstanten anlegen - doch das ging bei Variablen höheren Typs an IN eh' noch nie.)

* OUT-Parameter: ??? (wird nicht erklärt)

3.2.3 Funktionsbausteine (FB) schrieb:
Eigenschaften
• FBs sind Bausteine mit zyklischem Datenspeicher.
• Temporäre- und Out-Variablen gehen nach Bearbeitung der Funktion verloren.
Sie sind beim Aufruf der Funktion in nicht optimierten Bausteinen mit einem undefiniertem Wert, und bei optimierten Bausteinen mit „0“ vorbelegt (S7-1500 und S7-1200 Firmware V4).
:ROFLMAO:

Naja, man muß ja nicht alles glauben. Auch bei Siemens braucht man mittlerweile mindestens 3 unterschiedliche Quellen um zu entscheiden, welche Informationen wahrscheinlich ziemlich korrekt sind.

Es ist ja schön, daß Siemens einen solchen Programmierleitfaden erstellt hat, doch ist es bei Siemens nicht mehr möglich, daß da nochmal jemand drüberliest ob der Inhalt halbwegs korrekt ist? Kann man nun auch Dokumentationen erst ab V5.0 trauen? :roll:

Harald
 
Zuviel Werbung?
-> Hier kostenlos registrieren
* OUT-Parameter: ??? (wird nicht erklärt)
Eigenschaften
• FBs sind Bausteine mit zyklischem Datenspeicher.
• Temporäre- und Out-Variablen gehen nach Bearbeitung der Funktion verloren.
Sie sind beim Aufruf der Funktion in nicht optimierten Bausteinen mit einem undefiniertem Wert, und bei optimierten Bausteinen mit „0“ vorbelegt (S7-1500 und S7-1200 Firmware V4).

Naja, nicht das sie irgendwann die Firmware der Doku anpassen... Aber das ist schon krank bei so existenziellen Dingen...

Hmm, Atomkraftwerke sollte man mit TIA wohl lieber nicht bauen...
 
Hallo zusammen...
Das ganze soll ein "Ventilsteuerbaustein" werden.

Im Anlauf sollen dann die ADRESSEN der E/A's mit allen anderen Parametern zum Ventil in einem DB abgelegt werden.

Im normalen Zyklus wird dann nur noch über den DB gearbeitet.

Auf dem HMI soll es für den Servicefall eine E/A -Suche geben die den DB nach der Adresse durchsucht und dann den Gesamtstatus der Pneumatikachse ausgibt (EA-Status; Timer;Fehler ...)

Also: Im Anlauf Symbolisch den E/A angeben und die Adresse in DB ablegen.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
...
Abbildung 3-15 zeigt ausdrücklich einen STRING, der in den IN-Parameter kopiert wird

Stimmt. Ich war absichtlich etwas vage bezüglich "einfach" und "kompliziert". String ist irgendwo zwischen einfach und kompliziert. Beim FB ist das by-value, beim FC aber wieder by-reference.

*INOUT-Parameter: Übergabe per Referenz (Call-by-reference), jeder Zugriff im FB/FC arbeitet auf den referenzierten Original-Aktualparameter

stimmt auch nur teilweise. Der Lackmus test für mich ist der Instanz DB. Wenn im Instanz DB der Wert auftaucht, so ist das für mich ein call-by-value. Findet sich im Instanz DB gar nichts oder nur ein POINTER, dann ist das call-by-reference.

An INOUT kann man auch keine Konstanten anlegen - doch das ging bei Variablen höheren Typs an IN eh' noch nie.

Wie auch, wie soll den da was drauf kopiert werden. Da macht es auch keinen Unterschied ob by-value oder by-reference

* OUT-Parameter: ??? (wird nicht erklärt)


mittlerweile mindestens 3 unterschiedliche Quellen um zu entscheiden, welche Informationen wahrscheinlich ziemlich korrekt sind

Leider. Manchmal bin ich auch schon auf sowas wie Handbuch, read-me oder Leitfaden reingefallen. Aber bei der Inbetriebsetzung kommen so manche Zweifel hoch, die sich durch Testprogramme bestätigen.
Um raus zu finden was die 1200/1500 wirklich macht, war ich so gemein und habe im Baustein auf die außen angelegten Variablen zugegriffen. Also gaaanz schlechter Stil, an die Kinder zuhause am Bildschirm: "Bitte nicht nachmachen" :rolleyes:

"DBa".strval1 := 'a';
"DBa".strval2 := 'b';
CALL FC1( in1 := "DBa".strval1 );
Im FC1

"DBa".strval1 := 'c';
"DBa".strval2 := #in1;​

Und schon sieht man, dass "DBa".strval2 zu 'c' wird. Während der gleiche Versuch mit FB anders reagiert.

CALL FB1, DB1( in1 := "DBa".strval1 ); kopiert den 'a' nach DB1.in1,
"DBa".strval1 := 'c'; kopiert eben nicht nach DB1.in1
"DBa".strval2 := #in1; kopiert 'a'


Ich lass mir doch von S kein X für ein V vormachen.
 
...
Also: Im Anlauf Symbolisch den E/A angeben und die Adresse in DB ablegen.

Ich habe keinen Weg gefunden das auf einer 1200 hin zu bekommen.

Peek und Poke sind aber schon mal gut für die zweite Hälfte des Problems.
Also im DB legt man sich

DB_Nr : UINT
Byte_Nr : UDINT
Bit_Nr : USINT

an, dann kann man mit PEEK { oh mann wie heissen jetzt die Parameter, also irgenwie } #bit := PEEK_BOOL( Area := 16#84, DbNumber := "DBx".DB_Nr, ByteOffset := "DBx".ByteNr, BitOffset := "DBx".Bit_Nr, ENO => ENO ) auf die Adresse zugreifen.

Das Problem ist, dass man kein Mach_mir_eine_Adresse( BoolVariable := "VentilX", DbNumber => "DBx".DB_Nr, ByteOffset => "DBx".ByteNr, BitOffset => "DBx".Bit_Nr ) hat.

Auf der 1500 kann man sich das mit dem ANY ertricksen. Da kannst du dir den Mach_mir_eine_Adresse selber machen. BoolVariable ist vom Typ ANY und dann mittel AT über den ANY eine Struktur legen, die dann die Einzelteile wieder raus holt. Wie das geht Steht im Berger Buch und bestimmt ist das hier auch schon mal veröffentlicht worden.
 
Zurück
Oben