TIA Ethernetverbind S7-1500 zu S7-400

Nadya

Level-1
Beiträge
15
Reaktionspunkte
0
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo zusamen,

hier soll eine Ethernetverbindung zwischen einer 1518 PN/DP und einer 414 mit CP 443-1 erstelllt werden um ein paar Bits zu tauschen.

Hab schon gelesen das dies auf seitens der 1500er mit PUT/GET funktioniert. Aber wie wird das ganze auf beiden Seiten projektiert?
Den CP gibt es in der Device Config von TIA, aber wie sieht das ganze im Step7 aus?

Für ein Beispiel wäre ich dankbar.

Gruß
Nadya
 
Also grundsätzlich wenn du mit PUT/GET arbeitest. Muss auf Step7 Seite eigentlich nix programmiert werden. Ich mag das aber nicht so. Für mich Nehme dazu immer BSEND/BRECV über S7-Verbindung her.
Willst du denn die 414 in Step7 Projekt belassen und dich einfach mit ner 1500er dranklemmen? Dann kannst du sowohl in der Step7 als auch in TIA eine S7-Verbindung projektieren zu einem unspezifizierten Partner. auf die Verbindung setzt du dann die BSEND/BRECV auf.

Ich hab hier speziell für mich ein paar rudimentäre Bausteine gemacht für die Verbindung alte <-> neue Welt.

https://www.dropbox.com/sh/ljyqfg2cvymnilj/AADBM5Y7Zxjoj_nV6jkbTtKqa?dl=0

Vor allem das Word kannste dir mal zu gemüte führen.

Auf TIA Seite kannst du einfach den Baustein nehmen.
Code:
FUNCTION_BLOCK "MasterCom"
{ S7_Optimized_Access := 'FALSE' }
AUTHOR : Vor
FAMILY : Com
VERSION : 1.11
// Dieser Baustein regelt die Kommunikation zu einer Partnerstation Slave
// Es ist pro S7 Verbindung nur ein MasterCom zulässig da die Koppel_ID im Baustein vergeben wird
// Da BSend und BRCV verwendet werden sind nur S7 Verbindungen erlaubt
// Nach möglichkeit sind die SFB12/13 BSEND/BRCV zu verwenden, wenn nicht durch die CPU unterstützt
// dann die FB12/13 aus der Kommunikationsbibliothek Step7 in die CPU laden. 
// SFB und FB arbeiten zusammen
//
// V1.0 Startversion
// V1.1 Umgebaut auf ANY_Pointer
// V1.2 ANY in Baustein Integriert (Structur gebildet)
// V1.10 Baustein erkennt jetzt selbstständig ob Ein DB, Pointer oder Structur angehängt wurde
// V1.11 Angsstimer hinzugefügt. Resetet den Request wenn er länger als 10sek ansteht.
   VAR_INPUT 
      DB_1_Recv : Any;   // Daten die empfangen werden sollen DB, ANY oder Struct
      DB_1_Send : Any;   // Daten die gesendet werden
      ID : Word;   // Lokale VerbindungsID aus Netpro
      Master : Bool;   // Eine seite des OBJ_MasterCom muss master sein, sonst passen die KoppelID nicht
   END_VAR


   VAR_OUTPUT 
      zykl : Time;   // Zyklus in denen ein Telegramm gesendet wird beendet wird
      WD : Bool;   // Wenn Senden oder Empfangen länger als 5sek kein Done liefert, Error.
   END_VAR


   VAR 
      SEND {OriginalPartName := 'BSEND_SFB_PART'; LibVersion := '1.2'} : BSEND;
      RECV {OriginalPartName := 'BRCV_SFB_PART'; LibVersion := '1.2'} : BRCV;
      save_status_SEND : Word;
      save_status_RECV : Word;
      Zeit_alt : Time;
      Watchdog_Empfangen {OriginalPartName := 'IEC_TIMER'; LibVersion := '1.0'} : TON_TIME;
      Watchdog_Senden {OriginalPartName := 'IEC_TIMER'; LibVersion := '1.0'} : TON_TIME;
      Angsttimer {OriginalPartName := 'IEC_TIMER'; LibVersion := '1.0'} : TON_TIME;
      tReset : Bool;
   END_VAR


   VAR_TEMP 
      zDB_1_Recv : Any;
      pDB_1_Recv AT zDB_1_Recv : Struct
         SyntaxID : Byte;
         Bereichstyp : Byte;
         Anzahl_Werte : Int;
         DB_Nr : Int;
         Startadresse : DWord;
      END_STRUCT;
      zDB_1_Send : Any;
      pDB_1_Send AT zDB_1_Send : Struct
         SyntaxID : Byte;
         Bereichstyp : Byte;
         Anzahl_Werte : Int;
         DB_Nr : Int;
         Startadresse : DWord;
      END_STRUCT;
      wDummy : Word;
      RetVAL : Int;
      Write_Prot : Bool;
      Zeit : Time;
      Anzahl_Werte_RECV : Word;
      Anzahl_Werte_SEND : Word;
      Attrib_RCV : Byte;
      Attrib_SND : Byte;
      uiAnzahl_Werte_RECV : UDInt;
      uiAnzahl_Werte_SEND : UDInt;
   END_VAR




BEGIN
    #zDB_1_Recv := #DB_1_Recv;
    #zDB_1_Send := #DB_1_Send;
    
    #Zeit := TIME_TCK();
    
    (*Pointer aufbereiten*)
    IF #pDB_1_Recv.Bereichstyp = B#16#19 THEN
    (*Empfangen*)
      #pDB_1_Recv.SyntaxID := B#16#10;                                 // Typ des Bereichs soll Byte sein (INT = 2)
      #pDB_1_Recv.Bereichstyp := 2;                                         // Typ des Bereichs soll Byte sein (INT = 2)
      #pDB_1_Recv.DB_Nr := DWORD_TO_INT(#pDB_1_Recv.Startadresse);  // Länge des Pointers weil wir einen Any ohne Länge angeben wollen
      #RetVAL := ATTR_DB(REQ:=True,DB_NUMBER:=UINT_TO_DB_ANY(DWORD_TO_UINT(#pDB_1_Recv.Startadresse)) ,DB_LENGTH=>#uiAnzahl_Werte_RECV, ATTRIB=>#Attrib_RCV);
      #Anzahl_Werte_RECV:=UDINT_TO_WORD(#uiAnzahl_Werte_RECV);
      #pDB_1_Recv.Anzahl_Werte := UDINT_TO_INT(#Anzahl_Werte_RECV);             // Länge des Pointers weil wir einen Any ohne Länge angeben wollen
      #pDB_1_Recv.Startadresse := DW#16#84000000;
    END_IF;
    
    IF #pDB_1_Send.Bereichstyp = B#16#19 THEN
    (*Senden*)
      #pDB_1_Send.SyntaxID := B#16#10;                                 // Typ des Bereichs soll Byte sein (INT = 2)
      #pDB_1_Send.Bereichstyp := 2;                                         // Typ des Bereichs soll Byte sein (INT = 2)
      #pDB_1_Send.DB_Nr := DWORD_TO_INT(#pDB_1_Send.Startadresse);  // Länge des Pointers weil wir einen Any ohne Länge angeben wollen
      #RetVAL :=ATTR_DB(REQ:=True,DB_NUMBER:=UINT_TO_DB_ANY(DWORD_TO_UINT(#pDB_1_Send.Startadresse)) ,DB_LENGTH=>#uiAnzahl_Werte_SEND,ATTRIB=>#Attrib_SND);
      #Anzahl_Werte_SEND:=UDINT_TO_WORD(#uiAnzahl_Werte_SEND);
      #pDB_1_Send.Anzahl_Werte := UDINT_TO_INT(#Anzahl_Werte_SEND);             // Länge des Pointers weil wir einen Any ohne Länge angeben wollen
      #pDB_1_Send.Startadresse := DW#16#84000000;
    END_IF;
    
    // Senden des Datenbausteins
    
    
    
    
    
    #Anzahl_Werte_SEND := INT_TO_WORD(#pDB_1_Send.Anzahl_Werte);
    IF #Master THEN
      #SEND.R_ID := 1;
    ELSE
      #SEND.R_ID := 2;
    END_IF;
    
    #SEND(ID:=#ID,SD_1:=#zDB_1_Send,LEN:=#Anzahl_Werte_SEND);
    
    #Angsttimer(IN :=#SEND.REQ,
                PT := t#10s,
                Q=>#tReset);
    
    #SEND.REQ := TRUE;
    
    IF #SEND.ERROR OR #SEND.DONE OR #tReset THEN
      #SEND.REQ := FALSE;
    END_IF;
    
    IF #SEND.ERROR THEN
      #save_status_SEND := #SEND.STATUS;
    END_IF;
    
    IF #SEND.DONE THEN
      #zykl := #Zeit - #Zeit_alt;
      #Zeit_alt := #Zeit;
    END_IF;
    
    #Watchdog_Senden(IN := NOT #SEND.DONE,
                     PT := t#5s);
    
    // Empfangen des Datenbausteins
    IF #Master THEN
      #RECV.R_ID := 2;
    ELSE
      #RECV.R_ID := 1;
    END_IF;
    
    
    
    
    #RECV(EN_R:=TRUE,ID:=#ID,
          RD_1:=#zDB_1_Recv,
          LEN:=#Anzahl_Werte_RECV);
    
    IF #RECV.ERROR THEN
      #save_status_RECV := #RECV.STATUS;
    END_IF;
    
    #Watchdog_Empfangen(IN := NOT #RECV.NDR,
                        PT := t#5s);
    
    #WD := #Watchdog_Empfangen.Q OR #Watchdog_Senden.Q;
    
END_FUNCTION_BLOCK

Und auf Step7 dann diesen:

Code:
FUNCTION_BLOCK MasterCom
{ S7_Optimized_Access := 'FALSE' }
// Dieser Baustein regelt die Kommunikation zu einer Partnerstation Slave
// Es ist pro S7 Verbindung nur ein MasterCom zulässig da die Koppel_ID im Baustein vergeben wird
// Da BSend und BRCV verwendet werden sind nur S7 Verbindungen erlaubt
// Nach möglichkeit sind die SFB12/13 BSEND/BRCV zu verwenden, wenn nicht durch die CPU unterstützt
// dann die FB12/13 aus der Kommunikationsbibliothek Step7 in die CPU laden. 
// SFB und FB arbeiten zusammen
//
// V1.0 Startversion
// V1.1 Umgebaut auf ANY_Pointer
// V1.2 ANY in Baustein Integriert (Structur gebildet)
// V1.10 Baustein erkennt jetzt selbstständig ob Ein DB, Pointer oder Structur angehängt wurde
// V1.11 Angsttimer hinzugefügt. Resetet Req nach 10s wenn nötig
VERSION : '1.11'


VAR_INPUT
  DB_1_Recv : ANY ;    // Daten die empfangen werden sollen DB, ANY oder Struct
  DB_1_Send : ANY ;    // Daten die gesendet werden
      ID : WORD ;    //Lokale VerbindungsID aus Netpro
  Master : BOOL; // Eine seite des OBJ_MasterCom muss master sein, sonst passen die KoppelID nicht
END_VAR
VAR_OUTPUT
  zykl : TIME ;  // Zyklus in denen ein Telegramm gesendet wird beendet wird  
  WD: BOOL;   // Wenn Senden oder Empfangen länger als 5sek kein Done liefert, Error.
END_VAR
VAR
  SEND : "BSEND";    
  RECV : "BRCV";    
  save_status_SEND : WORD ;    
  save_status_RECV : WORD ;    
  Zeit_alt : TIME ;    
  Watchdog_Empfangen : TON;
  Watchdog_Senden : TON;
  Angsttimer : TON;
  
END_VAR
VAR_TEMP
  zDB_1_Recv : ANY ;  
        pDB_1_Recv AT zDB_1_Recv :  STRUCT  
                                       SyntaxID : BYTE ;    
                                       Bereichstyp : BYTE ;    
                                       Anzahl_Werte : INT ;    
                                       DB_Nr : INT ;    
                                       Startadresse : DWORD ;    
                                    END_STRUCT ;    
  zDB_1_Send : ANY ;
        pDB_1_Send AT zDB_1_Send : STRUCT  
                                       SyntaxID : BYTE ;    
                                       Bereichstyp : BYTE ;    
                                       Anzahl_Werte : INT ;    
                                       DB_Nr : INT ;    
                                       Startadresse : DWORD ;    
                                    END_STRUCT ;    
  wDummy : WORD ;    
  RetVAL : INT ;    
  Write_Prot : BOOL ;    
  Zeit : TIME ;  
  Anzahl_Werte_RECV:  WORD;  
  Anzahl_Werte_SEND:  WORD;  


END_VAR
zDB_1_Recv := DB_1_Recv;
zDB_1_Send := DB_1_Send;


Zeit := TIME_TCK();


(*Pointer aufbereiten*)
IF pDB_1_Recv.Bereichstyp = B#16#19 then
(*Empfangen*)
  pDB_1_Recv.syntaxid         := B#16#10;                                 // Typ des Bereichs soll Byte sein (INT = 2)
  pDB_1_Recv.Bereichstyp      := 2;                                         // Typ des Bereichs soll Byte sein (INT = 2)
  pDB_1_Recv.DB_Nr            := DWORD_TO_INT(pDB_1_Recv.Startadresse);  // Länge des Pointers weil wir einen Any ohne Länge angeben wollen
  RetVAL := TEST_DB(DB_NUMBER := DWORD_TO_WORD(pDB_1_Recv.Startadresse), DB_LENGTH := Anzahl_Werte_RECV ,WRITE_PROT := Write_Prot);
  pDB_1_Recv.Anzahl_Werte     := WORD_TO_INT(Anzahl_Werte_RECV);             // Länge des Pointers weil wir einen Any ohne Länge angeben wollen
  pDB_1_Recv.Startadresse     := DW#16#84000000;  
END_IF;  
  


IF pDB_1_send.Bereichstyp = B#16#19 then
  (*Senden*)
  pDB_1_send.syntaxid         := B#16#10;                                 // Typ des Bereichs soll Byte sein (INT = 2)
  pDB_1_send.Bereichstyp      := 2;                                         // Typ des Bereichs soll Byte sein (INT = 2)
  pDB_1_send.DB_Nr            := DWORD_TO_INT(pDB_1_send.Startadresse);  // Länge des Pointers weil wir einen Any ohne Länge angeben wollen
  RetVAL := TEST_DB(DB_NUMBER := DWORD_TO_WORD(pDB_1_send.Startadresse), DB_LENGTH := Anzahl_Werte_SEND ,WRITE_PROT := Write_Prot);
  pDB_1_send.Anzahl_Werte     := WORD_TO_INT(Anzahl_Werte_SEND);             // Länge des Pointers weil wir einen Any ohne Länge angeben wollen
  pDB_1_send.Startadresse     := DW#16#84000000;  
END_IF;  
  
// Senden des Datenbausteins










Anzahl_Werte_SEND := INT_TO_WORD(pDB_1_send.Anzahl_Werte);
IF Master THEN 
    SEND.R_ID := w#16#1;
ELSE
    SEND.R_ID := w#16#2;
END_IF;


  SEND(ID := ID,
    SD_1 := zDB_1_Send,
     LEN :=  Anzahl_Werte_SEND); 


Angsttimer(IN :=SEND.REQ,
            PT := t#10s);


SEND.REQ := TRUE;


IF SEND.ERROR OR SEND.DONE OR Angsttimer.q THEN
    SEND.Req := FALSE;
END_IF;


IF SEND.ERROR THEN
    save_status_SEND := SEND.STATUS; 
END_IF;      


IF SEND.done THEN
    Zykl := Zeit - Zeit_alt;
    zeit_alt := zeit;
END_IF;
            
Watchdog_Senden(IN := NOT SEND.DONE, PT := t#5s);


// Empfangen des Datenbausteins
IF Master THEN 
    RECV.R_ID := w#16#2;
ELSE
    RECV.R_ID := w#16#1;
END_IF;
    
    
    
    
      RECV(EN_R := TRUE // IN: BOOL
           ,ID := ID // IN: WORD
           ,RD_1 := zDB_1_Recv // INOUT: ANY
           ,LEN :=  Anzahl_Werte_Recv // INOUT: WORD
           ); 
        
          IF RECV.ERROR THEN
           save_status_RECV := RECV.STATUS; 
          END_IF;  


Watchdog_Empfangen(IN := NOT RECV.NDR, PT := t#5s);


WD := Watchdog_empfangen.q OR Watchdog_Senden.q;


END_FUNCTION_BLOCK

Wenn du die Step7 Quelle in TIA reinmachst wird er motzen wegen ein paar ungültigen zeichen. Einfach so anpassen wie es bei der S71500 Quelle ist.

mfG René
 
Zuletzt bearbeitet:
Zurück
Oben