Zuviel Werbung? - > Hier kostenlos beim SPS-Forum registrieren

Ergebnis 1 bis 6 von 6

Thema: PUT_E/GET_E Daten kommen nicht an. Kein Fehlerstatus anstehend.

  1. #1
    Registriert seit
    22.11.2006
    Ort
    CH
    Beiträge
    3.649
    Danke
    789
    Erhielt 655 Danke für 498 Beiträge

    Standard


    Zuviel Werbung?
    -> Hier kostenlos registrieren
    Ich versuch grade das erste mal eine S7 PUT/GET_E Verbindung zu etablieren.

    Ohne Erfolgt bisher. Der Request wird angestossen, mit Done bestätigt trotzdem kommt auf der Anderen Seite nix an und auf der eigenen Seite wird nix abgelegt.

    Sieht jemand einen Fehler in meiner Vorgehensweise?

    CPU ist derzeit eine PN/DP 315

    Code:
    FUNCTION_BLOCK MasterCom
    
    
    VAR_INPUT
        DB_1_Recv : ANY; // 1. DB zum Empfangen
          pDB_1_Recv AT DB_1_Recv : ANY_POINTER;
        DB_2_Recv : ANY; // 2. DB zum Empfangen
          pDB_2_Recv AT DB_2_Recv : ANY_POINTER;
        DB_1_Send : ANY; // 1. DB zum Senden
          pDB_1_Send AT DB_1_Send : ANY_POINTER;
        DB_2_Send : ANY; // 2. DB zum Senden
          pDB_2_Send AT DB_2_Send : ANY_POINTER;
        ID : INT; // VerbindungsID
    
    
    END_VAR
    
    
    VAR
        GET : GET_E;
        PUT : PUT_E;
        tGET : TON;
        tPUT : TON;
    
    
        
        GET_Status : WORD;
        PUT_Status : WORD;
            
        
    END_VAR
    
    
    VAR_TEMP
        Laenge : WORD;
        DB_1_Send_L : WORD;
        DB_2_Send_L : WORD;
        DB_1_Recv_L : WORD;
        DB_2_Recv_L : WORD;
    
    
    END_VAR
    
    
    GET(   ,ID := INT_TO_WORD(ID) // IN: WORD
                ,ADDR_1 := pDB_1_Recv // INOUT: ANY
                ,ADDR_2 := pDB_2_Recv // INOUT: ANY
                ,RD_1 := pDB_1_Recv // INOUT: ANY
                ,RD_2 := pDB_2_Recv // INOUT: ANY
                ); 
     
    IF NOT GET.REQ THEN
      GET.REQ := true;
    END_IF;  
    
    
    IF GET.NDR OR GET.ERROR OR tGET.q THEN
      GET.REQ := false;
    END_IF;
    
    
    IF GET.error THEN
        GET_Status := GET.status;
    END_IF;
    
    
    tGET(IN :=  GET.REQ// IN: BOOL
              ,PT := t#30s // IN: TIME
              ); 
    
    
    
    
    PUT(        ID := INT_TO_WORD(ID) // IN: WORD
                ,ADDR_1 := pDB_1_Send // INOUT: ANY
                ,ADDR_2 := pDB_2_Send // INOUT: ANY
                ,SD_1 :=  pDB_1_Send// INOUT: ANY
                ,SD_2 :=  pDB_2_Send // INOUT: ANY
                ); 
    
    
    
    
    IF NOT PUT.REQ THEN
      PUT.REQ := true;
    END_IF;  
    
    
    IF PUT.DONE OR PUT.ERROR OR tPUT.q THEN
      PUT.REQ := false;
    END_IF;
      
     IF PUT.error THEN
        PUT_Status := PUT.status;
    END_IF;  
    
    
    tPUT(IN :=  PUT.REQ// IN: BOOL
              ,PT := t#30s // IN: TIME
              ); 
      
    END_FUNCTION_BLOCK
    Der Aufruf
    Code:
          CALL  #Slave1
           DB_1_Recv:=P#DB2201.DBX0.0 BYTE 200
           DB_2_Recv:="Nord_RU_KLP_HW_Input".HW_INPUT
           DB_1_Send:=P#DB2202.DBX0.0 BYTE 40
           DB_2_Send:="Nord_RU_KLP_HW_Output".DB_VAR
           ID       :=1
    Zitieren Zitieren PUT_E/GET_E Daten kommen nicht an. Kein Fehlerstatus anstehend.  

  2. #2
    Registriert seit
    22.03.2007
    Ort
    Detmold (im Lipperland)
    Beiträge
    11.797
    Danke
    398
    Erhielt 2.418 Danke für 2.014 Beiträge

    Standard

    Hallo René,

    den Code würde ich selbst so nicht umsetzen. Ich würde mir eine Schrittkette erstellen, die z.B. in folgender Reihenfolge arbeitet :
    1 : Get anstossen
    2 : Get-Status = aktiv abfragen
    3 : Get-Status = nicht aktiv abfragen
    4 : warten
    5 : Put anstossen
    6 : Put-Status = aktiv abfragen
    7 : Put-Status = nicht aktiv abfragen
    8 : warten
    9 : wieder von vorne

    ... das kann man jetzt natürlich noch zusätzlich mit der fehler-Auswertung "würzen"

    Gruß
    Larry

  3. #3
    Avatar von vollmi
    vollmi ist gerade online Erfahrener Benutzer
    Themenstarter
    Registriert seit
    22.11.2006
    Ort
    CH
    Beiträge
    3.649
    Danke
    789
    Erhielt 655 Danke für 498 Beiträge

    Standard

    hmpf. Ich hab das jetzt schnell in awl nachgebaut da tuts genau so.
    PUT/GET_E völlig nicht gegeneinander verriegelt funktioniert in AWL einwandfrei. Irgendwas mach ich in SCL da falsch.

    mfG René

  4. #4
    Registriert seit
    22.03.2007
    Ort
    Detmold (im Lipperland)
    Beiträge
    11.797
    Danke
    398
    Erhielt 2.418 Danke für 2.014 Beiträge

    Standard

    ... ich hatte jetzt auch erstmal keinen Fehler gesehen - deshalb mein Ansatz ...
    Es wird aber wohl doch schon ein Unterschied zwischen deinem AWL-Test und dem gesposteten SCL-Code sein ... vielleicht bei den Pointern ...?

    Gruß
    Larry

  5. #5
    Registriert seit
    22.06.2009
    Ort
    Sassnitz
    Beiträge
    11.338
    Danke
    932
    Erhielt 3.333 Danke für 2.691 Beiträge

    Standard

    Hallo René,

    was ist das für ein "komischer" Datentyp ANY_POINTER? Wozu soll das gut sein?
    Code:
    VAR_INPUT
        DB_1_Recv : ANY; // 1. DB zum Empfangen
          pDB_1_Recv AT DB_1_Recv : ANY_POINTER;
        DB_2_Recv : ANY; // 2. DB zum Empfangen
          pDB_2_Recv AT DB_2_Recv : ANY_POINTER;
        DB_1_Send : ANY; // 1. DB zum Senden
          pDB_1_Send AT DB_1_Send : ANY_POINTER;
        DB_2_Send : ANY; // 2. DB zum Senden
          pDB_2_Send AT DB_2_Send : ANY_POINTER;
        ID : INT; // VerbindungsID
    END_VAR
    Versuchst Du, die Adresse der INPUT-Parameter an GET bzw. PUT zu übergeben?
    Es muß der gesamte ANY in die INPUT-Parameter von GET/PUT kopiert werden (also der Wert des ANY-Parameters, nicht dessen Adresse).
    Dein Code sieht gekürzt aus. Fummelst Du in Deinem realen Programm vielleicht noch an den ANYs rum?
    Funktioniert es, wenn Du das mit dem ANY_POINTER wegläßt?
    Code:
    (*
    GET(   ,ID := INT_TO_WORD(ID) // IN: WORD
                ,ADDR_1 := pDB_1_Recv // INOUT: ANY
                ,ADDR_2 := pDB_2_Recv // INOUT: ANY
                ,RD_1 := pDB_1_Recv // INOUT: ANY
                ,RD_2 := pDB_2_Recv // INOUT: ANY
                );
    *)
    
    GET(        ID := INT_TO_WORD(ID) // IN: WORD
                ,ADDR_1 := DB_1_Recv  // INOUT: ANY
                ,ADDR_2 := DB_2_Recv  // INOUT: ANY
                ,RD_1 := DB_1_Recv    // INOUT: ANY
                ,RD_2 := DB_2_Recv    // INOUT: ANY
                );
     
    //IF NOT GET.REQ THEN
      GET.REQ := true;
    //END_IF;
    (das IF.. ist überflüssig)

    (Die Außen beim Aufruf des FB MasterCom übergebenen ANY dürfen nicht auf Variablen in TEMP zeigen.)

    Ansonsten sehe ich in dem SCL-Code keinen Fehler.
    Gibt es die DBs auf beiden CPUs? Und lang genug?

    Harald
    Geändert von PN/DP (12.08.2014 um 03:52 Uhr)
    Es ist immer wieder überraschend, wie etwas plötzlich funktioniert, sobald man alles richtig macht.

    FAQ: Linkliste SIMATIC-Kommunikation über Ethernet

  6. #6
    Avatar von vollmi
    vollmi ist gerade online Erfahrener Benutzer
    Themenstarter
    Registriert seit
    22.11.2006
    Ort
    CH
    Beiträge
    3.649
    Danke
    789
    Erhielt 655 Danke für 498 Beiträge

    Standard


    Zuviel Werbung?
    -> Hier kostenlos registrieren
    [QUOTE=PN/DP;502564]was ist das für ein "komischer" Datentyp ANY_POINTER? Wozu soll das gut sein?

    Das ist ein UDT der den Any_Pointer beschreibt. Und die AT sicht ist ja sozusagen dann der ANY Pointer im Temp. Eigentlich sollte dass ja das machen was man in AWL macht wenn man den Anypointer aus der Schnittstelle nimmt in den Tempbereich zieht um ihn an weitere FBs durchzureichen.

    Hier z.B. habe ich das genau so gemacht um ihn an einen BlockMove weiterzureichen.
    Code:
    FUNCTION_BLOCK Obj_ABLUFTKLP
    
    
    VAR_INPUT
        LS_PAR : ANY; // Pointer aufs erste Wort des Kommunikationsbereichs zum UeLS
          POINTING AT LS_PAR : ANY_POINTER; 
        AumaIN : AumaIN;
    END_VAR
    
    
    VAR_OUTPUT
        AumaOut : AumaOut;
    END_VAR
    
    
    VAR_IN_OUT
        Klp_Fahr: Klp_fahr; // UDT für Automatikanforderungen
        GrpTestRein: INT := 1000; // Welcher Testgruppe zugeordnet?
    END_VAR
    
    
    VAR_TEMP
       Ret : INT;
       KLP : LS_ABL_KLP; // temporäre Variablen
    END_VAR
    
    
    VAR
      Bedienart_save : INT;  // Bedienart sichern
      Automatik : BOOL;
      ST_TIMER : TON;
    END_VAR
    
    
    
    
    (*Pointer auf UDT schreiben zum arbeiten*)
      pointing.Bereichstyp := 2;   // Typ des Bereichs soll Byte sein (INT = 2)
      pointing.Anzahl_Werte := 24; // Länge des Pointers weil wir einen Any ohne Länge angeben wollen
      Ret :=  BLKMOV(SRCBLK := LS_PAR ,DSTBLK := KLP);
    Oh mann jetzt seh ichs. Ich hab da garnicht den UDT ausm Temp an Blockmove gehängt sondern das nur zum verändern des Pointers genutzt.

    jargl. Danke für den Denkanstoss.

    mfG René
    Geändert von vollmi (12.08.2014 um 07:40 Uhr)

Ähnliche Themen

  1. Profibus erweitern - wie kommen Daten in die CPU
    Von ssound1de im Forum Feldbusse
    Antworten: 3
    Letzter Beitrag: 20.07.2012, 06:51
  2. Antworten: 0
    Letzter Beitrag: 03.11.2011, 16:28
  3. Antworten: 2
    Letzter Beitrag: 22.04.2009, 15:59
  4. ALARM_S-Meldungen kommen nicht durch
    Von RAN im Forum Simatic
    Antworten: 7
    Letzter Beitrag: 16.10.2007, 10:17
  5. Antworten: 4
    Letzter Beitrag: 26.04.2007, 21:05

Lesezeichen

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •