Step 7 [SCL] IN1, IN2, .., INX indirekt adressieren ?

Flux

Level-1
Beiträge
314
Reaktionspunkte
11
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo Leute,

als IN-Parameter hat mein FB IN1, IN2, ... INX vom Typ MyUDT (Slave-Datensätze). Nun würde ich gerne in einer Schleife die Eingänge durchtakten.
IN[Slave_No] würde nur bei Arrays funktionieren nehme ich an.
Geht das zur Not iwie mit String-Operationen ?

:confused:

Grüße
Flux
 
Hallo,
nein ... das geht nicht.
Du kannst zwar, wenn dir der UDT vom Aufbau her bekannt ist auf dessen Unterelemente zugreifen - du kannst aber nicht auf eine Gruppe von IN-Parametern (oder alle) eine AT-Sicht (o.ä.) legen, die das Ganze dann wie ein Array behandelt. Auch nicht wenn alle IN's vom Typ her gleich sind.
Was aber geht ist, sie auf ein Baustein-internes Array umzukopieren und das dann weiter zu bearbeiten ...
Oder eben ein Array of UDT übergeben ...

Gruß
Larry
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Ja, IN[Slave_No] funktioniert nur bei Arrays.
Mit String? Hmm, glaube ich eher nicht das dies funktioniert.

Was soll denn deine Schleife machen?
Vielleicht gehts ja anders zum lösen, zb den Code der in der Schleife steht in einen eigenen FB/FC und dann diesen mehrmals aufrufen mit dem passenden Parameter.
 
Guten Morgen Larry!

Die UDTs, eigentlich INOUT, da beidseitig gelesen und geschrieben wird, dienen als Schnittstelle zwischen Slaves und Kopfbaustein.


Was aber geht ist, sie auf ein Baustein-internes Array umzukopieren

Du meinst eine Art Prozessabbild zu schaffen, also am FB-Anfang und -Ende hardcoded zu hinterlegen:

TempArray[1..MaxSlave] OF MyUDT

TempArray[1] := INOUT1
...

//Logik
//TempArray[ID]
//ID++

INOUT1 := TempArray[1]
...

Speicherfresser... :(


Oder eben ein Array of UDT übergeben ...

Ok, dann könnte ich die UDTs nicht mehr einzeln verschalten, sondern müsste das "Prozessabbild" auf einen DB auslagern und diesen dem FB zuführen.

Geht das indirekte Adressieren von Anschlüssen vllt. in AWL ?
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Die Sollwerte aus dem Slave-UDT versenden und Messwerte empfangen und in den jew. Slave-UDT zurückschreiben. Es kann immer nur ein Slave gleichzeitig behandelt werden, deshalb die Schleife

Dann kannst du diesen Code eh perfekt in einen Baustein packen und diesen mehrmals aufrufen.

Oder du übergibst die UDT's nicht einzeln sondern in einem Array. Dann kannst du dies mit einer Schleife lösen.
 
Geht das indirekte Adressieren von Anschlüssen vllt. in AWL ?

Im Prinzip Ja ... und auch wieder Nein.
Du könntest dir auf den ersten IN-Parameter einen Pointer bilden und einen auf den Zweiten. Dadurch kennst du die Breite des Datenbereichs und kannst dann über indirekte Adressierung darauf zugreifen. Es ist dann aber eben kein UDT mehr sondern nur noch irgendein Adressbereich - im Nachhinein schwer nachvollziehbar da es eben keinen direkten Bezug mehr zu den Ursprungsdaten gibt.

Ich würde hier auf jeden Fall beim dem ursprünglichen Datenformat bleiben - wahrscheinlich auch bei SCL ...

Wie wäre denn Folgendes :
Du hast nur noch einen IN-Parameter vom Typ UDT und einen IN-Parameter vom Typ INT als Index.
Du arbeitest mit einem FB und bildest in dem dein Array of UDT ab. Durch den Index bestimmst du nun wohin die eingehenden Daten sollen ...
Dieser Vorschlag funktioniert natürlich nur dann sinnvoll wenn er in dein Konzept (das ich nicht kenne) so hineinpasst - denk mal drüber nach ...

Gruß
Larry
 
Im Prinzip Ja ... und auch wieder Nein.
Du könntest dir auf den ersten IN-Parameter einen Pointer bilden und einen auf den Zweiten. Dadurch kennst du die Breite des Datenbereichs und kannst dann über indirekte Adressierung darauf zugreifen. Es ist dann aber eben kein UDT mehr sondern nur noch irgendein Adressbereich
Hm, du meinst per Point auf dem eigenen IDB rumkratzen.. Symbolik ade

einen IN-Parameter vom Typ UDT und einen IN-Parameter vom Typ INT als Index.
Du arbeitest mit einem FB und bildest in dem dein Array of UDT ab. Durch den Index bestimmst du nun wohin die eingehenden Daten sollen ...

Hm, leider kann ich nicht mehrere Slaves auf einen Eingang des Kopf-Bst. verknüppeln..

also doch zurück zum TempArray a la Prozessabbild.

Danke für eure Antworten und Überstunden am Sonntag :)

Gruß
Flux
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Dann kannst du diesen Code eh perfekt in einen Baustein packen und diesen mehrmals aufrufen.

Oder du übergibst die UDT's nicht einzeln sondern in einem Array. Dann kannst du dies mit einer Schleife lösen.

Der Kopf-Bst. quatscht mit nem Protokoll-Treiber, und der kann halt nur einen gleichzeitig, daher wird das Auflösen der Schleife in ParallelInstanzen nicht gehen
 
Der Kopf-Bst. quatscht mit nem Protokoll-Treiber, und der kann halt nur einen gleichzeitig, daher wird das Auflösen der Schleife in ParallelInstanzen nicht gehen
Was sind ParallelInstanzen :confused:

Du mußt den Baustein ja nicht in einer Schleife aufrufen. Du kannst ja auch nur einen Aufruf machen solange nötig, dann den Aufruf für die nächste Instanz..

Beachte daß Du Deinen Code auch in einem halben Jahr noch verstehen mußt und daß man durch die indirekte Adressierung nicht die Programmausführung einer bestimmten Instanz beobachten kann falls mal eine Fehlersuche nötig wird.

Harald
 
Was sind ParallelInstanzen :confused:

ich meinte mehrere Instanzen die "parallel" existieren

Beachte daß Du Deinen Code auch in einem halben Jahr noch verstehen mußt und daß man durch die indirekte Adressierung nicht die Programmausführung einer bestimmten Instanz beobachten kann falls mal eine Fehlersuche nötig wird.

Jo, ich bin eigentlich ein Freund von L X, T Y ... statt LOOP. Insofern bau ich jetzt das TempArray ein, zum Unmut meines Chefs, der mit den zusätzlich benötigten Speicher vom Gehalt abziehen wird :cool:
 
Zuviel Werbung?
-> Hier kostenlos registrieren
ich meinte mehrere Instanzen die "parallel" existieren

Ja aber die werden nicht parallel abgearbeitet, sondern genau so wie in der Schleife nacheinander.

Jo, ich bin eigentlich ein Freund von L X, T Y ... statt LOOP. Insofern bau ich jetzt das TempArray ein, zum Unmut meines Chefs, der mit den zusätzlich benötigten Speicher vom Gehalt abziehen wird :cool:

Spricht eigentlich was dagegen, gleich ein Array dem Baustein zu übergeben?
Dann ersparst du dir das kopieren auch.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
.. Insofern bau ich jetzt das TempArray ein, zum Unmut meines Chefs, der mit den zusätzlich benötigten Speicher vom Gehalt abziehen wird :cool:
Zu Recht tut er das. UDTs als IN_OUT und dann auch noch umkopieren nach TEMP ist schon übelst recourcenfressend. Indirekte Adressierung kommt nicht in Betracht? Wenn man es gut kommentiert ist es durchaus ordentlich machbar.
 
Wenn man in KOP/FUP/AWL UDTs als IN_OUT übergibt stimmt das mit dem Ressourcenfressen, aber nicht in SCL.
SCL "frisst" in dem Fall zwar tatsächlich etwas weniger Ressourcen als AWL, frisst aber auch. Um die Adressberechnung zum UDT-Member an INOUT kommt auch SCL nicht herum. (mal abgesehen von möglichen Compiler-Optimierungen bei Folge-Zugriffen auf andere Variablen des selben INOUT-UDT)

Wird der UDT an IN eines FB übergeben, dann benötigt SCL genau wie AWL 4 Byte Programmcode für den Zugriff auf eine INT-Variable aus dem UDT.
Wird der UDT an INOUT eines FB übergeben, dann benötigt AWL 42 Byte Programmcode, SCL benötigt "ressourcensparend" nur 26 Byte.

Harald
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Wird der UDT an IN eines FB übergeben, dann benötigt SCL genau wie AWL 4 Byte Programmcode für den Zugriff auf eine INT-Variable aus dem UDT.
Wird der UDT an INOUT eines FB übergeben, dann benötigt AWL 42 Byte Programmcode, SCL benötigt "ressourcensparend" nur 26 Byte.

Toll, und wenn ich den FB lösche habe ich sogar nochmal 26 Bytes gespart ;-)

Es macht nicht viel Sinn IN und IN_OUT miteinander zu vergleichen. Man verwendet IN_OUT ja nicht weil der Name so toll ist, sondern weil man die Funktion haben möchte.
 
Hm, woher habt ihr die zahlen? compilierten bst ohne quelle öffnen und anweisungen zählen? wieviel programmcode bräuchte die fb-interne idb-adressierung im vergleich, pi mal schnauze versteht sich?
 
Es macht nicht viel Sinn IN und IN_OUT miteinander zu vergleichen. Man verwendet IN_OUT ja nicht weil der Name so toll ist, sondern weil man die Funktion haben möchte.
Wenn man IN_OUT braucht dann muß man selbstverständlich IN_OUT benutzen - egal was es kostet.

Meinen Vergleich habe ich gebracht, weil Du behauptet hast, das ressourcenfressende Vergrößern des Programmcodes gäbe es nur bei KOP/FUP/AWL aber nicht bei SCL. Und das ist leider nicht korrekt.


Hm, woher habt ihr die zahlen? compilierten bst ohne quelle öffnen und anweisungen zählen? wieviel programmcode bräuchte die fb-interne idb-adressierung im vergleich, pi mal schnauze versteht sich?
Im FB egal ob Zugriff auf IN/OUT/STAT oder TEMP: 4 Byte
Zugriff auf eine Variable in einem UDT an IN_OUT: 26 Byte bei SCL-Quelle bzw. 42 Byte bei KOP/FUP/AWL-Quelle
Auch deshalb ist es oft sinnvoll, UDT zur Verarbeitung zuerst von IN_OUT in TEMP zu kopieren.

Codegröße ermitteln:
- SCL Quelle übersetzen
- den erzeugten Baustein in einen anderen Bausteine-Ordner kopieren
- da den Baustein öffnen - man sieht den erzeugten AWL-Code
- den Baustein einmal speichern --> Bausteingröße wird nun 2 Byte größer als das SCL-Compilat
- diese Bausteingröße merken --> als Bausteingröße_vorher
- nun den interessierenden Code löschen oder auskommentieren
- den Baustein speichern --> Bausteingröße_vorher minus Bausteingröße_jetzt entspricht dem Bedarf des Codes

Harald
 
Zurück
Oben