TIA 1500er Get / Put

volker

Supermoderator
Teammitglied
Beiträge
5.805
Reaktionspunkte
1.027
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo

Ich habe hier einen Parametrierbaren FB der Get (Put) benutzt. Das ganze funktioniert in der 1500er nicht mehr.
Beim Übersetzen bekomme ich folgenden Fehler der sich auf die Temp-Variable #Quellzeiger, welcher am Get auf ADDR_1 liegt, bezieht.

Code:
PLC_1,,1,0,09:01:37
Programmbausteine,,1,0,09:01:37
use_SFB14_GET_V1.1 (FB114),,1,0,09:01:37
Netzwerk 5,Nur absolute Any-Pointer sind erlaubt.,,,09:01:37
,Übersetzen beendet (Fehler: 1; Warnungen: 0),,,09:01:38

Ich habe auch mal probiert den #Quellzeiger in der Deklaration in den In-Bereich zu legen. Selber Fehler.

Jemand eine Idee wie ich das Problem lösen kann?

Ich könnte den Baustein jetzt natürlich 'unparamerierbar machen und mehrere Kopien erzeugen für jeden Aufruf den ich brauche. Aber das kann ja nicht des Rätsels Lösung sein
 

Anhänge

  • use_sfb14.awl.txt
    3,5 KB · Aufrufe: 54
Zuletzt bearbeitet:

Ich denke, er will das wirklich fest Adressiert haben.:confused:

Glaube nicht, das es da einen Umweg gibt.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Vermute ich auch fast. Aber das ist doch Müll. Dann muss ich wohl wahrhaftig für jeden Aufruf einen eigenen FB schaffen.
Sind bei z.b. 10 Anlagen ja nur 20 Bausteine (put/get).

Werde dann wohl den Baustein parametrierbar lassen und nur die Eingangsdaten zum erzeugen des Quellzeigers entfernen. Dann muss ich in den FB's 'NUR' :-( ADDRR_1 anpassen.


Mal wieder ein grosse Lob an Big S.:sw22:
 
Muß der Eingang ADDR_1 beschaltet werden? Wenn nicht, dann könnte man vielleicht den ANY aus TEMP in die GET-Instanz kopieren oder gleich dort zusammenbauen.

Harald
 
An dem Problem mit den Varianttypen habe ich mir schon länger die Zähne ausgebissen. Man kann ja Remote und Variant nach draussen an die Schnittstelle führen. Aber im Baustein kann man weder "Variant" noch "Remote" irgendwie verändern. Oft hab ich ja Put/Get so benutzt das ich sowohl Quelle wie auch Ziel den gleichen Speicherbereich nutzen. Ich hatte also in der S7-300/400 oft ein und denselben Pointer an Ziel und Quellbereich angelegt. Alles nicht mehr möglich. Wie soll man eine dynamische Kommunikation aufbauen mit einem Variant datentyp, wenn man den nicht wärend der Laufzeit bearbeiten kann?

mfG René
 
Zuviel Werbung?
-> Hier kostenlos registrieren
@pn/dp
ADDR_1 muss beschaltet werden.

...Man kann ja Remote und Variant nach draussen an die Schnittstelle führen. Aber im Baustein kann man weder "Variant" noch "Remote" irgendwie verändern....
Das brachte mich auf die Idee den #Quellzeiger (im Temp-Bereich) als Remote zu definieren. (Hätte ich eigentlich auch vorher drauf kommen können. Steht ja im Tooltip was an addr_1 erwartet wird)

Ich hatte das in allen möglichen varianten mit Any probiert.

Der Baustein lässt sich jetzt auch Fehlerfrei übersetzen.

Wird das funktionieren? Wegen Aussage von Vollmi.

Testen kann ich zur Zeit nicht. Keine passende Hardware. Nächste Woche mal versuchen ob ich es in einer Simu testen kann.
 
Der Baustein lässt sich jetzt auch Fehlerfrei übersetzen.

Wird das funktionieren? Wegen Aussage von Vollmi.

Testen kann ich zur Zeit nicht. Keine passende Hardware. Nächste Woche mal versuchen ob ich es in einer Simu testen kann.

Was willst du denn mit dem Remotezeiger im Temp machen? Da kannst du doch nix zuweisen.

Bis jetzt bin ich kein stück weiter als Remote und Variant des PUT/GET über die INOUT Schnittstelle des Aufrufenden Bausteins nach draussen zu geben.

Ich habs nicht fertiggebracht irgendwie einen ANY auf den REMOTE oder VARIANT Zeiger zu kopieren. Noch REMOTE oder VARIANT irgendwie zu verändern.
REMOTE und VARIANT kann man auch nicht in TEMP oder STAT deklarieren wenn der Baustein optimiert angelegt ist, warum auch immer.

Also ich hab da ganz viele Fragen was die Überlegungen bei Siemens waren als sie das so hingebastelt haben.

mfG René
 
Muß der Eingang ADDR_1 beschaltet werden? Wenn nicht, dann könnte man vielleicht den ANY aus TEMP in die GET-Instanz kopieren oder gleich dort zusammenbauen.

Sind INOUTs, müssen also beschaltet werden. Was ja nicht schlimm wäre, könnte man wie von Volker vorgeschlagen im Temp hinterlegen. Nur nützt einem das nix. denn die Instanz von PUT und von GET sind im IDB schlicht nicht sichtbar zum editieren. Man sieht nur das was über die Schnittstelle geht in der Instanz. Also IN OUT und INOUT.



mfG René
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Bis jetzt bin ich kein stück weiter als Remote und Variant des PUT/GET über die INOUT Schnittstelle des Aufrufenden Bausteins nach draussen zu geben.
Wenn der aufrufende Baustein ein FB (mit IDB) ist, muß der REMOTE-Parameter am IN_OUT dann beschaltet werden? Kann der IN_OUT-Parameter nicht irgendwie beschrieben werden? (BLKMOV oder AT-Sicht)

Harald
 
INOUT landet ja sowieso in keiner Instanz müssen also zwingend beschalten werden. für eine AT Sicht müsste man ja wissen wie der aufgebaut ist.
Aber obwohl anzunehmen wäre das REMOTE denselben Aufbau hat wie variant lassen sich nichtmal diese Typen überlagern.

mfG René
 
Zuletzt bearbeitet:
Ne sorry mein fehler landet doch in der instanz, hatte ich irgendwie ausgeblendet. Aber nichtsdestotrotz. muss beschaltet werden zumindest addr_1 und sd_1
Ich meine den IN_OUT des FB, der den GET aufruft, an den Du den ADDR_1 des GET herausgezogen hast (also den IN_OUT den Du beim Aufruf des GET an ADDR_1 dranschreibst).

Harald
 
Was willst du denn mit dem Remotezeiger im Temp machen? Da kannst du doch nix zuweisen.

Bis jetzt bin ich kein stück weiter als Remote und Variant des PUT/GET über die INOUT Schnittstelle des Aufrufenden Bausteins nach draussen zu geben.

Ich habs nicht fertiggebracht irgendwie einen ANY auf den REMOTE oder VARIANT Zeiger zu kopieren. Noch REMOTE oder VARIANT irgendwie zu verändern.
REMOTE und VARIANT kann man auch nicht in TEMP oder STAT deklarieren wenn der Baustein optimiert angelegt ist, warum auch immer.
???

Als mein FB ist nicht Optimiert. Der FB wird in einem anderen FB als Multiinstanz aufgerufen.

Also ich habe im Temp den Any durch Remote ersetzt und wie für den Any auch das indirekt kopiert.
Remote und Any haben ja den gleichen Aufbau. Behaute ich jetzt mal einfach so den der Get akzeptiert am addr_1 einen ganz normalen any-zeiger wenn ich es direkt eingebe.
z.b. P#DB10.DBX0.0 BYTE 32

Also denke ich, das an ADDR_1 genau das gleiche stehen wird wie früher
Code:
 Quellzeiger Remote 0.0     
// Zusammenstellung des Quellzeigers
      LAR1  P##Quellzeiger       //zeiger ins adressregister laden
      L     W#16#10              //SyntaxID. bei AWL immer 10
      T LB [ AR1 , P#0.0 ]
      L     W#16#2               //Typ BYTE
      T LB [ AR1 , P#1.0 ]
      L     #Laenge              //Anzahl Bytes
      T LW [ AR1 , P#2.0 ]
      L     #Quell_DB            //Quell-DB
      T LW [ AR1 , P#4.0 ]
      L     #Anfangsadresse_Quelle//Anfangsadresse
      SLD   3
      T LD [ AR1 , P#6.0 ]
      L     B#16#84              //Speicherbereich (hier DB)
      T LB [ AR1 , P#6.0 ]

Nur nützt einem das nix. denn die Instanz von PUT und von GET sind im IDB schlicht nicht sichtbar zum editieren. Man sieht nur das was über die Schnittstelle geht in der Instanz. Also IN OUT und INOUT.
Muss ich doch auch gar nicht editieren. der remote-zeiger wird ja indirekt durch durch die eingangsparameter erzeugt.
genausowenig muss ich einen IN Any auf ein Temp Remote kopieren
oder versteh ich hier was falsch?
 
Zuviel Werbung?
-> Hier kostenlos registrieren
???

Als mein FB ist nicht Optimiert. Der FB wird in einem anderen FB als Multiinstanz aufgerufen.

Also ich habe im Temp den Any durch Remote ersetzt und wie für den Any auch das indirekt kopiert.
Remote und Any haben ja den gleichen Aufbau. Behaute ich jetzt mal einfach so den der Get akzeptiert am addr_1 einen ganz normalen any-zeiger wenn ich es direkt eingebe.
z.b. P#DB10.DBX0.0 BYTE 32

Tatsache du hast recht. Der Remote sieht wirklich so aus wie ein Any im gegensatz zum Variant.
Mich hat immer irritiert das am Remote wie auch am Variant ein anyzeiger erlaubt ist: z.b. P#DB10.DBX0.0 BYTE 32
Direkt eingegeben. Aber der Variant keinerlei speicherbereich für sich beansprucht



muss ich doch auch gar nicht editieren. der remote-zeiger wird ja indirekt durch durch die eingangsparameter erzeugt.
genausowenig muss ich einen IN Any auf ein Temp Remote kopieren
oder versteh ich hier was falsch?

Ich dachte du willst sowohl Addr wie auch sd durchreichen und wie ein any bearbeiten. Bei addr könnte das ja sogar gehen bei sd aber wohl nicht. Bin gespannt.
 
Ich dachte du willst sowohl Addr wie auch sd durchreichen und wie ein any bearbeiten. Bei addr könnte das ja sogar gehen bei sd aber wohl nicht. Bin gespannt.
Nee. Will ich gar nicht.
Quell / und Zieladresse werden im FB indirekt über die Eingangsparameter erzeugt.
Einen Any(Remote) direkt an einen move oder ähnliches anzulegen habe ich bisher nie gemacht.

Ich meine getestet zu haben, dass ich einen remote als InOut deklariert habe den der Get (put) auch an ADDR_1 akzeptiert hat.
RD_1 (SD_1) (also beim mir im code der #empfangszeiger / #euellzeiger)(siehe awl-quelle im post 1) ist ja ein any der ohne probs funktioniert hat


--- das jetzt mal nur am rande ----
Ein Test eben mal zu hause unter s7 classic (hab hier nicht das komlette eq)
Ein Any als IN bzw als INOUT deklariert und versucht das an den sfc20 zu legen. Geht nicht.

Hab auch mal kurz probiert einen any als IN / INOUT in den FB zu übergeben.
Dort habe mal einen Zeiger auf den IN / INOUT gelegt und über das AR zu laden.
Beim beobachten habe ich aber bei allen über die mit AR angesprochenen Vars eine 0.
also
L p##InOutAny
LAR1
L LW[ar1,p#0.0] //hier steht beim beobachten 0
übergeben habe ich an den InOutAny p#db10.dbx10.0 byte 10
Im db10 habe ich dort entsprechende werte eingetragen.
ich hätte jetzt eigentlich erwartet, dass ich im ar die werte sehe die ich im db eingetragen habe


cpu meldet fehler für ob121 und ob88 (das hatte ich noch nie (muss ich mir mal genauer anschauen))

Hab das auch nur kurz getestet ohne mir da jetzt weitere Gedanken zu zu machen.
1. ist hier jetzt auch nicht relevant
2. irgendwann muss ja auch mal Feierabend sein
;)
------------------------------
 
Ich hab da mal was gebastelt So funktionierts mit ANY am Eingang des aufrufenden Bausteins. damit werden sowohl SD wie auch addr belegt und funktionieren tuts auch. Natürlich nur nicht optimierte Daten.

Code:
TYPE "ANY_POINTER"
VERSION : 0.1
   STRUCT
      SyntaxID : Byte;
      Bereichstyp : Byte;
      Anzahl_Werte : Int;
      DB_Nr : Int;
      Startadresse : DWord;
   END_STRUCT;


END_TYPE

FUNCTION_BLOCK "PUTGET"
{ S7_Optimized_Access := 'FALSE' }
VERSION : 0.1
   VAR_INPUT 
      Sendebereich : Any;
      Empfangsbereich : Any;
      ID : Word;
   END_VAR


   VAR 
      PUT_Instance {OriginalPartName := 'PUT_SFB_PART'; LibVersion := '1.3'} : PUT;
      GET_Instance {OriginalPartName := 'GET_SFB_PART'; LibVersion := '1.3'} : GET;
      save_status_Put : Word;
      save_status_Get : Word;
      Put_Reset {OriginalPartName := 'IEC_TIMER'; LibVersion := '1.0'} : TON_TIME;
      Get_Reset {OriginalPartName := 'IEC_TIMER'; LibVersion := '1.0'} : TON_TIME;
      Put_set {OriginalPartName := 'IEC_TIMER'; LibVersion := '1.0'} : TON_TIME;
      Get_set {OriginalPartName := 'IEC_TIMER'; LibVersion := '1.0'} : TON_TIME;
   END_VAR


   VAR_TEMP 
      SndADDR : Remote;
      pSndADDR AT SndADDR : "ANY_POINTER";
      SndSD : Any;
      pSndSD AT SndSD : "ANY_POINTER";
      GetADDR : Remote;
      pGetADDR AT GetADDR : "ANY_POINTER";
      GetSD : Any;
      pGetSD AT GetSD : "ANY_POINTER";
   END_VAR




BEGIN
    #SndSD := #Sendebereich; // in Temp kopieren für überlagerung
    #GetSD := #Empfangsbereich;
    
    // anypointer als udt im ganzen zugewisen
    #pGetADDR := #pSndADDR;
    
    // anypointer einzeln zugewiesen
    #pSndADDR.Anzahl_Werte := #pSndSD.Anzahl_Werte;
    #pSndADDR.Bereichstyp := #pSndSD.Bereichstyp;
    #pSndADDR.DB_Nr := #pSndSD.DB_Nr;
    #pSndADDR.Startadresse := #pSndSD.Startadresse;
    #pSndADDR.SyntaxID := #pSndSD.SyntaxID;
    
    // zeug Senden
    #PUT_Instance(ID:=#ID,
                  ADDR_1:=#SndADDR,
                  SD_1:=#SndSD);
    
    #PUT_Instance.REQ := (#PUT_Instance.ERROR OR #PUT_Instance.DONE OR #Put_set.Q) AND NOT #Put_Reset.Q;
    
    
    IF #PUT_Instance.ERROR THEN
        #save_status_Put := #PUT_Instance.STATUS;
    END_IF;
    
    #Put_Reset(IN:=#PUT_Instance.REQ,
               PT:=t#10s);
    
    #Put_set(IN:=NOT #PUT_Instance.REQ,
             PT:=t#10s);
    
    // zeug Zeug holen
    #GET_Instance(ID:=#ID,
                  ADDR_1:=#GetADDR,
                  RD_1:=#GetSD);
    
    #GET_Instance.REQ := (#GET_Instance.ERROR OR #GET_Instance.NDR OR #Get_set.Q) AND NOT #Get_Reset.Q;
    
    IF #GET_Instance.ERROR THEN
        #save_status_Get := #GET_Instance.STATUS;
    END_IF;
    
    #Get_Reset(IN := #GET_Instance.REQ,
               PT := t#10s);
    
    #Get_set(IN := NOT #GET_Instance.REQ,
             PT := t#10s);
END_FUNCTION_BLOCK

Feierabend is langweilig ;)

Edit: Ich bin mir ziemlich sicher dass ich als ich die 1500er frisch hatte. Ewigs versucht hab denn variant gegen einen any zu ersetzen und keinen Erfolg damit habe. Und jetzt geht es auf einmal. Keinen Plan was ich vorher falsch gemacht habe.
Jetzt werde ich dasselbe noch bei der Offenen Kommunikation ausprobieren. Da nerven nämlich die Variant genauso.

Edit2: Hab s Anstossen noch vergessen falls man automatisch kommunikation starten will.
 
Zuletzt bearbeitet:
Ich hab da mal was gebastelt So funktionierts mit ANY am Eingang des aufrufenden Bausteins. damit werden sowohl SD wie auch addr belegt und funktionieren tuts auch. Natürlich nur nicht optimierte Daten.

Code:
TYPE "ANY_POINTER"
VERSION : 0.1
   STRUCT
      SyntaxID : Byte;
      Bereichstyp : Byte;
      Anzahl_Werte : Int;
      DB_Nr : Int;
      Startadresse : DWord;
   END_STRUCT;


END_TYPE

FUNCTION_BLOCK "PUTGET"
{ S7_Optimized_Access := 'FALSE' }
VERSION : 0.1
   VAR_INPUT
      Sendebereich : Any;
      Empfangsbereich : Any;
      ID : Word;
   END_VAR


   VAR
      PUT_Instance {OriginalPartName := 'PUT_SFB_PART'; LibVersion := '1.3'} : PUT;
      GET_Instance {OriginalPartName := 'GET_SFB_PART'; LibVersion := '1.3'} : GET;
      save_status_Put : Word;
      save_status_Get : Word;
      Put_Reset {OriginalPartName := 'IEC_TIMER'; LibVersion := '1.0'} : TON_TIME;
      Get_Reset {OriginalPartName := 'IEC_TIMER'; LibVersion := '1.0'} : TON_TIME;
      Put_set {OriginalPartName := 'IEC_TIMER'; LibVersion := '1.0'} : TON_TIME;
      Get_set {OriginalPartName := 'IEC_TIMER'; LibVersion := '1.0'} : TON_TIME;
   END_VAR


   VAR_TEMP
      SndADDR : Remote;
      pSndADDR AT SndADDR : "ANY_POINTER";
      SndSD : Any;
      pSndSD AT SndSD : "ANY_POINTER";
      GetADDR : Remote;
      pGetADDR AT GetADDR : "ANY_POINTER";
      GetSD : Any;
      pGetSD AT GetSD : "ANY_POINTER";
   END_VAR




BEGIN
    #SndSD := #Sendebereich; // in Temp kopieren für überlagerung
    #GetSD := #Empfangsbereich;
  
    // anypointer als udt im ganzen zugewisen
    #pGetADDR := #pSndADDR;
  
    // anypointer einzeln zugewiesen
    #pSndADDR.Anzahl_Werte := #pSndSD.Anzahl_Werte;
    #pSndADDR.Bereichstyp := #pSndSD.Bereichstyp;
    #pSndADDR.DB_Nr := #pSndSD.DB_Nr;
    #pSndADDR.Startadresse := #pSndSD.Startadresse;
    #pSndADDR.SyntaxID := #pSndSD.SyntaxID;
  
    // zeug Senden
    #PUT_Instance(ID:=#ID,
                  ADDR_1:=#SndADDR,
                  SD_1:=#SndSD);
  
    #PUT_Instance.REQ := (#PUT_Instance.ERROR OR #PUT_Instance.DONE OR #Put_set.Q) AND NOT #Put_Reset.Q;
  
  
    IF #PUT_Instance.ERROR THEN
        #save_status_Put := #PUT_Instance.STATUS;
    END_IF;
  
    #Put_Reset(IN:=#PUT_Instance.REQ,
               PT:=t#10s);
  
    #Put_set(IN:=NOT #PUT_Instance.REQ,
             PT:=t#10s);
  
    // zeug Zeug holen
    #GET_Instance(ID:=#ID,
                  ADDR_1:=#GetADDR,
                  RD_1:=#GetSD);
  
    #GET_Instance.REQ := (#GET_Instance.ERROR OR #GET_Instance.NDR OR #Get_set.Q) AND NOT #Get_Reset.Q;
  
    IF #GET_Instance.ERROR THEN
        #save_status_Get := #GET_Instance.STATUS;
    END_IF;
  
    #Get_Reset(IN := #GET_Instance.REQ,
               PT := t#10s);
  
    #Get_set(IN := NOT #GET_Instance.REQ,
             PT := t#10s);
END_FUNCTION_BLOCK

Feierabend is langweilig ;)

Edit: Ich bin mir ziemlich sicher dass ich als ich die 1500er frisch hatte. Ewigs versucht hab denn variant gegen einen any zu ersetzen und keinen Erfolg damit habe. Und jetzt geht es auf einmal. Keinen Plan was ich vorher falsch gemacht habe.
Jetzt werde ich dasselbe noch bei der Offenen Kommunikation ausprobieren. Da nerven nämlich die Variant genauso.

Edit2: Hab s Anstossen noch vergessen falls man automatisch kommunikation starten will.
Wahnsinns code, hat mir sehr geholfen
 
Zurück
Oben