Step 7 Auslesen des Inhaltes eines UDT-Poiners mit SCL

SPS-Totalizer

Level-1
Beiträge
173
Reaktionspunkte
40
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo zusammen,

ich suche eine Möglichkeit den Zeiger eines UDT-Parameters (DB-Nr., DBX-Nr.) an einem FB mit SCL auszulesen.
Dabei ist mir der Aufbau grundsätzlich bekannt, da ich dies in AWL schon mehrfach umgesetzt habe.
Ein Versuch dies mit "AT" zu lösen scheiterte leider kläglich, da dabei immer der DB-Inhalt ausgegeben wurde.
Das Problem interessiert mich zwar Vordringlich in S7 Klassik, aber auch eine TIA-Lösung wäre interessant.
 
Mit welcher CPU arbeitest du ? Bei 300/400 geht das meines Wissens nicht. Bei 1500er bin ich nicht sicher. Ich denke aber das der Parameter explizit als ANY deklariert sein muss. Du kannst es aber ausprobieren, machen kann man das z.B. Mit AT-Sicht, da gibts etliche Beiträge im Forum

Edit: Das mit dem AT hab ich in deinem Post überlesen.

Was genau hast du vor ? Kannst du den UDT um DB-Nr und DBX Addr erweiteren ? Diese Variablen könntest du an einer anderen Stelle beschreiben (auch vollautomatisch) wenn du sie als ANY an einen FC der nur für das zuständig ist übergibst.
 
Zuletzt bearbeitet:
Zuviel Werbung?
-> Hier kostenlos registrieren
Wie sieht die Deklaration Deines FB-Übergabeparameters aus?
Falls Du eine S7-300/400 hast und der UDT in VAR_IN deklariert ist: da kann man nicht die Adresse des Aktualparameters lesen, weil da nicht die Adresse übergeben wird sondern eine Kopie der UDT-Variable. Die Adresse wird nur bei VAR_INOUT-Parametern übergeben.

PS: Wozu soll das Lesen der Aktualparameter-Adresse gut sein, was hast Du eigentlich vor?

Harald
 
Sorry es dauerte ewas länger.

Hier nochmal ein paar Eckpunkte:
1. Es geht hauptsächlich um S7-Klassik als 300/400er.
2. Auch TIA (1500er) wäre aber interessant.
3. Es sollen (müssen) InOut-Paramerter Verwendet werden
4. Die Lösung die Daten im Datenfeld (durch UDT Pointer angewählter DB) zu hinterligen ist mir Bekannt macht jedoch doppelt Arbeit
und ist damit eigentlich nicht O.K.
5. Damit soll der Direktzugriff über Pointer auf den DB erfolgen, da ich jedoch auch direkte UDT-Zugriffe tätige, benutze ich beide Varianten.
6. In AWL (300/400) greife ich mittels Pointer auf die UDT-Paramer zu und kann den DB im 1.Wort auslesen, und in Wort 2 und 3 befindet
sich der Byte/-Bitpointer

Der Grund warum ich seit ca 2 Jahren mehr und mehr Programmteile auf SCL umstelle liegt in der Tatsache begründet, dass immer
weniger Kollegen AWL richtig verstehen.

P.S. mit Asembler wird die welt schnell (gell).....
4. In AWL wird dies folgendermaßen gelöst
 
Sorry Leute,

eigentlich hatte ich mir ein paar Antworten erhofft, anstelle von Fragen.

Nun versuche ich es doch wohl besser über N-Morenbrunn.

Danke Trotzdem
 
So wie TP-Inc schon gleich in #2 schrieb: Das geht nicht in SCL.
Weil der SCL-Compiler das AT nicht als "AT Übergabeparameter" übersetzt sondern als "AT Aktualparameter". Vermutlich haben sich die SCL-Compiler-Bauer das so gedacht: AT ist eine Sicht auf eine Variable. Der Übergabeparameter ist nicht die Variable, sondern der außen angeschlossene Aktualparameter ist die Variable auf die sich das AT bezieht. Einen Adressoperator gibt es in SCL nicht, deshalb kann man diese Interpretation nicht umgehen.

(Es geht nur höchst unsauber durch absoluten oder indizierten Direktzugriff auf die Adresse des INOUT-Parameters im IDB. Oder die Adresse durch zusätzlich zu übergebende DB-Nummer + Offset zusammenbasteln.)

Bei FB: Auf die Adresse des außen angeschlossenen Aktualparameters kann man in SCL nur zugreifen wenn der Übergabeparameter explizit als POINTER oder ANY deklariert ist.

Für das was Du eigentlich tun willst gibt es bestimmt bessere/saubere Wege. Wir warten immer noch auf eine einfache/bildliche Erklärung von Dir. Du bekommst den UDT an den FB übergeben, Du kannst auf jede Variable in dem UDT symbolisch zugreifen - wozu brauchst Du die Adresse des UDT (des Aktualparameters)?

Harald
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Mit SCL auf UDT-Pointer (Any-Pointer) Zugreifen und Daten kopieren geht in SCL schon.
Ich benutze das um einzelne Datensätze z.B. Rezeptdaten oder Betriebsdaten, die als Array angelegt
sind zu kopieren.

Man muss aber aufpassen was man tut, da die Software die grenzen nicht überprüft.
Fei falschen Indexangaben liest man ohne Warnung über den Speicher hinaus.

Ich hab aber keine Ahnung, ob das dass ist was du suchst!

Code:
FUNCTION m7_udtCopyArray : VOID
(*
   udtCopyArray:
   trotz UC Aufruf durch den SCL-Kompiler können keine Daten von/zu TEMP-Variablen erfolgen.
   Daten stimmen in diesem Fall nicht!
*)

TITLE = 'udtCopyArray'
VERSION : '3.0'
AUTHOR  : 'S.Maag'
FAMILY  : 'Maagic7'

(*  ================================================================================

 udtCopyArray:

    Kopiert UDT's aus Arrays, die Datenlänge des UDT wird automatisch ermittelt. 
    Anpassungen der Datenlänge nach Änderungen an den UDT's entfällt somit.
    
    Achtung Array bzw. Speichergrenzen werden nicht überprüft.
    Gegebenenfalls, Indexangaben vorher auf Korrektheit prüfen bzw. limittieren!
    Bei inkorrekten Indexangaben geht CPU in STOP.
    
    Verwendung: Verwaltung von Datensätzen wie Rezepturen, Betriebsdaten, 
    Positionsdaten usw. in der Steuerung. 
    
    Kopiert wird von/zu: DB, statischen Lokaldaten im Instanz-DB 
    (Multinnstanzfähig, ohne zus. Adresskorrektur, da Step7 bei Verwendung von 
    Instanzdaten bei UDT's automatisch als Quelle [#84] DB und Nr. mit korrekter 
    Adress angibt statt nur DI [#85])
    
    Nicht kopiert wrid von/zu lokalen Daten (TEMP), da vor- vorherige Lokaldaten 
    benötigt werden (S7 aber nur vorherige Lokaldaten unterstützt)
    
    [IN]
    srcUdtArray : Anypointer auf den ersten UDT im Quell-Array
    srcIndex    : Index des Quell-UDT im Array, beginnend bei 0
    destUdtArray: Anypointer auf den ersten UDT im Ziel-Array
    destIndex   : Index des Ziel-UDT im Array, beginnend mit 0

 
 AUTHOR: Stefan Maag, Dipl.-Ing. (FH) Elektrotechnik 
 DATE: 10/2007

 CHANGELOG:
 --------------------------------------------------------------------------------
 DATE         NAME        DESCRIPTION
 --------------------------------------------------------------------------------
 20.03.2017   S.Maag      Converted AWL Version m7b_udtCopyArray to SCL
 --------------------------------------------------------------------------------
 *)

VAR_INPUT
    srcUdtArray : ANY;  // AnyPointer to first UDT in SourceArray
    srcIndex : INT;     // Index of Source_UDT in the Array[0..x]
    destUdtArray : ANY; // AnyPointer to first UDT in DestinationArray
    destIndex : INT;    // Index of Destination_UDT in the Array[0..x]
END_VAR

VAR_OUTPUT
    BLKMOVE_RET : INT;    
END_VAR

VAR_TEMP
  
    anySRC : ANY;
    anyDEST :ANY;
   
    p_anySRC AT anySRC: STRUCT  // Mit dem  AT Befehl wird der gleiche Bereich in einer anderen Form définiert
       ID  : WORD;  // ID für ANY (1002 hex = es wird mit Bytes gearbeitet)
       REP :INT;    // Wiederholungsfaktor
       DBNo : INT;   // DB der im ANY Pointer benutzt wird ANY
       PTR : DWORD; // Pointer Doppelwort um den Angfang des Datenbereichs und den Datentyp zu definieren (84hex = DB Datentyp)
    END_STRUCT;
 
     p_anyDEST AT anyDEST: STRUCT  // Mit dem  AT Befehl wird der gleiche Bereich in einer anderen Form définiert
       ID  : WORD;  // ID für ANY (1002 hex = es wird mit Bytes gearbeitet)
       REP :INT;    // Wiederholungsfaktor
       DBNo : INT;   // DB der im ANY Pointer benutzt wird ANY
       PTR : DWORD; // Pointer Doppelwort um den Angfang des Datenbereichs und den Datentyp zu definieren (84hex = DB Datentyp)
    END_STRUCT;
      
    tmpDataPointer : DWORD;
    
END_VAR

BEGIN
    anySRC := srcUdtArray;
    anyDEST := destUdtArray;
    
    tmpDataPointer := DINT_TO_DWORD(DWORD_TO_DINT(p_anySRC.PTR AND DW#16#FFFFFF) + INT_TO_DINT(p_anySRC.REP) * INT_TO_DINT(srcIndex)* 8);
    p_anySRC.PTR := (p_anySRC.PTR AND DW#16#FF000000) OR tmpDataPointer;
 
    tmpDataPointer := DINT_TO_DWORD(DWORD_TO_DINT(p_anyDEST.PTR AND DW#16#FFFFFF) + INT_TO_DINT(p_anyDEST.REP) * INT_TO_DINT(destIndex) * 8);
    p_anyDEST.PTR := (p_anyDEST.PTR AND DW#16#FF000000) OR tmpDataPointer;
   
    BLKMOVE_RET := BLKMOV(srcblk:= anySRC, dstblk:= anyDEST); // SFC20
    OK := TRUE; // ENO
END_FUNCTION
 
Hallo Beisammen,

wenn mich nicht alles Täuscht geht es Folgendermaßen an die Adresse einer Struktur am In Out zu kommen.
Also eine Struktur oder Udt im InOut Anlegen. Jetzt im Temp einen Any anlegen. Jetzt einfach den Udt oder Struct den Any übergeben. Einfach mit := so den Any kann mann per At nun Überlagern. Weis aber leider nicht mehr wo ich das gesehen habe.



Gruß Tia
 
Jetzt im Temp einen Any anlegen. Jetzt einfach den Udt oder Struct den Any übergeben. Einfach mit := so den Any kann mann per At nun Überlagern. Weis aber leider nicht mehr wo ich das gesehen habe.
Ach ja, diesen Tick hatte ich schon wieder vergessen :oops: den hatten wir vor knapp 1 Jahr hier ausführlich behandelt. So kann man den SCL-Compiler überreden, doch den POINTER zu liefern.

@SPS-Totalizer
PS: Was hat eigentlich die Konsultation von N-Morenbrunn ergeben?

Harald
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Ach ja, diesen Tick hatte ich schon wieder vergessen :oops: den hatten wir vor knapp 1 Jahr hier ausführlich behandelt. So kann man den SCL-Compiler überreden, doch den POINTER zu liefern.

@SPS-Totalizer
PS: Was hat eigentlich die Konsultation von N-Morenbrunn ergeben?

Harald



Danke Pn/DP habe heute auf Arbeit bereits meinem gesammelte Werke Ordner durchsucht aber nichts gefunden.
Jetzt weis ich es wieder.

Gruß Tia
 
Zurück
Oben