TIA 1500er Get / Put

Zuviel Werbung?
-> Hier kostenlos registrieren
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.
ich muss noch mal fragen, anscheinend bin ich doch zu doof!?
wie muss ich den:
Sendebereich / Empfangsbereich aufbauen, wenn ich z.B.
in der Lokalen CPU im DB35 10 Byte ab Adresse 100
zur entfernten CPU im DB100 ab Adresse 0
Daten austauschen möchte?

für meine Anwendung müßte die Länge und die DBs variabel sien.
Ich bin in der ganzen Pointer Geschichte nicht so fitt!
Bereits habe ich auch schon versucht die ANY_POINTER Struktur voll zu schreiben:
SyntaxID := 16#84; //DB-Bereich
Bereichstyp : 16#02; //Byte
Anzahl_Werte : 10
DB_Nr : 35/100;
Startadresse : 10/0;
Aber leider ging das nicht!

Kann man mir irgendwie Starthilfe geben.

Danke
 
Der Code ist hier nur so aufgebaut dass der Speicherbereich in der Aufrufenden CPU gleich ist wie in der Adressierten CPU. Das heisst wenn du da einen Pointer DB35.DBX100.0 Byte 10 angibst dann landet das zeug auch in der Remote Adresse an dem Ort.
Jetzt kannst du den Baustein aber auch so anpassen dass du Quelle und Ziel individuell angeben kannst.

Mit Variabel meinst du vermutlich, du willst offline angeben wie die Adressen lauten, nicht du willst nach jedem PUT/GET Auftrag einen neuen Auftrag mit anderen Adressen auslösen? Da müsstest du noch ein bisschen drumrumbauen.

Um Lokal und Remote zu trennen, müsstest du nur diesen Code entfernen
Code:
   // 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;

und die werte entsprechend zuweisen.
bzw. dieses verdoppeln. für Lokal und Remote getrennt.
Code:
  #SndSD := #Sendebereich; // in Temp kopieren für überlagerung
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Tatsächlich wäre es auch machbar, im gleichen DB in beiden SPSn aber der Startbereich sollte sich unterscheiden…
Ichhab aber noch nicht verstanden, wie ich die Adresse angegeben soll
 
Zurück
Oben