TIA Wie den maximale Speicherbereich der Put/Get Anweisung übertragen?

Automole

Level-2
Beiträge
22
Reaktionspunkte
0
Zuviel Werbung?
-> Hier kostenlos registrieren
Morgen zusammen,

habe einen Aufbau einer 300er CPU und einer 1500er CPU. Eine S7 Kommunikation habe ich hinbekommen. Mit dieser sende ich Daten von der 1500er zur 300er.

- kurze Frage: meine 1500er ist der Client, das bedeutet ja, dass ich auf der 300er die Put/Get Anweisung aktivieren müsste. Diese gibt es im Simatic Manager aber nicht, deshalb muss ich hier nichts machen, richtig?


- jetzt zu meiner eigentlichen Frage: wie kann ich denn den maximalen Speicherbereich, der z.B. mit der Put Anweisung übertragen werden kann, in einem einzigen Put FB übertragen?

Ich mach das zurzeit noch so, dass ich in den vier möglichen Schreibbereichen ADDR_1 - ADDR_4 jeweils ein DWord übertrage. Daraus ergeben sich dann 16 Byte.

In der Dokumentation von Put/Get steht jedoch: "Folgende Mindestgröße der Nutzdaten für die Anweisung "PUT"mit 1 – 4 Variablen ist garantiert: 160 Byte". Im Internet hab ich auch gelesen, dass 200 Byte möglich sind...

Wie geht das?



Grüße und schon mal Danke für's Lesen

Automole
 
Auf beiden Seiten musst Du auf einen nicht optimierten Datenbaustein verweisen, z.B. DB0.
Dieser beinhaltet in der Struktur in der Du Daten senden und empfangen willst die entsprechenden Word, Bool, etc.
Am Speicherbereich vom PUT musst Du nun als Adresse nicht DB0.DBW0 angeben sondern einen Verweis(Pointer): "P#DB0.DBX0.0 Byte 160". Du legst also den Startpunkt fest sowie die Länge.

300er haben sehr wohl Put und Get-Anweisungen:


Linkliste SIMATIC-Kommunikation über Ethernet

Such nach "S7-Kommunikation", dort sind einige Anleitungen aber auch Put Get beschrieben inkl. Pointer.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
meine 1500er ist der Client, das bedeutet ja, dass ich auf der 300er die Put/Get Anweisung aktivieren müsste.

Die Anweisungen werden auf der Client Seite aufgerufen. Den Server stellt das "Betriebssystem" der CPU automatisch zur Verfügung.
PUT/GET gibt es sowohl für 300er, 400er als auch 1500er.
 
Ich hab da mal vor einiger Zeit einen Baustein geschrieben mit dem mehrere gleichgroße DBs angefordert werden können.
Die max. Blockgröße wird dabei berücksichtigt.

Code:
FUNCTION_BLOCK  "Get_Daten"
VERSION :'0.2'

// Bausteinparameter
VAR_INPUT
    // Eingangsparameter
    id          : WORD; // Verbindungs-ID
    Start       : BOOL; // Datenanforderung starten
    Source_DBNr : INT;  // Nummer des Start-Datenbausteins (Remote)
    Anzahl_DB   : INT;  // Anzahl der Datenbausteine zum Übertragen
    Anzahl_Byte : INT;  // Byte zum Übertragen
    Dest_DBNr   : INT;  // Nummer des Start-Datenbausteins (Local)    
END_VAR

VAR_IN_OUT
    // Durchgangsparameter
    Aktiv   : BOOL; // Datenanforderung läuft    
    DBNr    : INT;  // Aktuell angeforderter DB
    Status  : Word; // Fehler-Code FB "GET"
END_VAR

VAR_OUTPUT
    // Ausgangsparameter
    iO      : BOOL; // Fertig ohne Fehler 
    NiO     : BOOL; // Fertig mit Fehler
END_VAR

VAR
    // statische Variablen
    bStart_FP       : BOOL;  // Start Daten anfordern - Positive Flanke
    bStart_FHM      : BOOL;  // Start Daten anfordern - Flankenmerker
    iBlockgroesse   : INT;   // Anzahl der Byte pro Übertragungsblock
    iBlockanzahl    : INT;   // Anzahl der notwendigen Übertragungsblöcke
    i               : INT;   // Schleifenzähler DB
    j               : INT;   // Schleifenzähler Datenböcke
    iStartAdr       : INT;   // Startadresse
    bReq            : BOOL;  // Daten anfordern
    fbGET           : "GET"; // FB "GET" - Multiinstanz
    fbTimeout       : "TON"; // Timeout - Multiinstanz
END_VAR

VAR_TEMP
    // temporäre Variablen
    anySourceDB              : ANY;   //Any-Pointer DB Remote
    vSourceDB AT anySourceDB : STRUCT //Sicht auf Anypointer DB Remote
        byID  : BYTE;
        byTyp : BYTE;
        iAnz  : INT;
        iDBNr : INT;
        dwPTR : DWORD;
        END_STRUCT;
    anyDestDB            : ANY;   //Any-Pointer Typ-DB Local
    vDestDB AT anyDestDB : STRUCT //Sicht auf Anypointer DB Local
        byID  : BYTE;
        byTyp : BYTE;
        iAnz  : INT;
        iDBNr : INT;
        dwPTR : DWORD;
        END_STRUCT;
END_VAR

(* ------------------------------------------------
Datenbausteine von Partnerstation übertragen
Es wird der FB "GET" und eine S7-Verbindung genutzt
--------------------------------------------------- *)

// Positive Flanke Start Daten anfordern
bStart_FP := Start AND NOT bStart_FHM AND NOT Aktiv;
bStart_FHM := Start;

// Initialisierung
IF bStart_FP THEN 
    Aktiv           := true;
    iO              := false;
    NiO             := false;
    DBNr            := -1;
    bReq            := true;
    Status          := W#16#0;
    iBlockgroesse   := 128;
    iBlockanzahl    := (Anzahl_Byte DIV iBlockgroesse) + 1;
    i               := 0;
    j               := 0;
    iStartAdr       := 0;    
END_IF;

// Any-Pointer für GET initialisieren
vSourceDB.byID  := 16#10;
vSourceDB.byTyp := 16#02;
vDestDB.byID  := 16#10;
vDestDB.byTyp := 16#02;
       
// Source-DBNr ermitteln
vSourceDB.iDBNr := Source_DBNr + i;
DBNr            := vSourceDB.iDBNr;

// Dest-DBNr ermitteln
vDestDB.iDBNr := Dest_DBNr + i;

// Anzahl der Byte zum Übertragen
IF j < (iBlockanzahl - 1) THEN 
    vSourceDB.iAnz := iBlockgroesse;
ELSE
    vSourceDB.iAnz := Anzahl_Byte MOD iBlockgroesse; 
END_IF;            
vDestDB.iAnz := vSourceDB.iAnz;
        
// Startadresse ermitteln
iStartAdr := j * iBlockgroesse;
vSourceDB.dwPtr := SHL(in := INT_TO_DWORD(iStartAdr), n := 3) OR 16#84000000; // Zeiger auf Startadresse
vDestDB.dwPtr := vSourceDB.dwPtr;
        
// Daten von Partnersteuerung anfordern
fbGET(REQ     := bReq
      ,ID     := id
      ,ADDR_1 := anySourceDB
      ,RD_1   := anyDestDB
      );
              
// Anforderung reseten
bReq := false;

// Zeitüberwachung für Datenanforderung
fbTimeout(IN := Aktiv, PT:= t#45s); 
        
// Anforderung erfolgreich      
IF fbGET.NDR AND NOT fbGET.Error AND NOT fbTimeout.Q THEN
    
    j:= j+1; // Blockzähler erhöhen
    
    // Abfrage alle Blöcke eines DB übertragen
    IF j < iBlockanzahl THEN 
        // Nicht fertig -> Nächsten Block anfordern    
        bReq := true; // Neue Anforderung
    ELSE    
        // Alle Blöcke des DB übertragen
        j := 0; 
        
        // Abfrage alle DB übertragen
        IF i < (Anzahl_DB-1) THEN
            // Nicht fertig -> nächsten DB holen
            i    := i+1;  // Schleifenzähler erhöhen
            bReq := true; // Neue Anforderung
        ELSE
            // Fertig -> Alle DB übertragen
            bReq    := false;
            Aktiv   := false;
            iO      := true;
            NiO     := false;
            Status  := W#16#0;
        END_IF;    
    END_IF;            
END_IF;

// Anforderung nicht erfolgreich
IF fbGET.Error OR fbTimeout.Q THEN
    Aktiv   := false;
    iO      := false;
    NiO     := true;
    Status  := fbGET.Status;
END_IF;
        
END_FUNCTION_BLOCK

Vielleicht kannst du was davon gebrauchen


Gruß
Blockmove
 
"P#DB0.DBX0.0 Byte 160"
Den Server stellt das "Betriebssystem" der CPU automatisch zur Verfügung.

Okay top, ich probiers mal so. Danke schonmal


300er haben sehr wohl Put und Get-Anweisungen:
PUT/GET gibt es sowohl für 300er, 400er als auch 1500er.

Hab mich da etwas unglücklich ausgedrückt. Ich meinte, dass man PUT/GET im Simatic Manager nicht aktivieren muss. Stimmt doch, oder? Hab jedenfalls keinen Button gefunden wie im TIA Portal

Ich hab da mal vor einiger Zeit einen Baustein geschrieben mit dem mehrere gleichgroße DBs angefordert werden können.

Das schaut sehr interessant aus. Das werde ich mir genauer anschauen. Danke
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Auf beiden Seiten musst Du auf einen nicht optimierten Datenbaustein verweisen, z.B. DB0.

Muss im Simatic Manager auch den Datenbausteinen gesagt werden, dass sie nicht optimiert sein sollen oder sind sie das automatisch (habe keine Einstellung dazu gefunden)? Am Datenbaustein der Partner CPU, welche ich im Simatic Manager programmiere, kommt nämlich nichts an...
 
Muss im Simatic Manager auch den Datenbausteinen gesagt werden, dass sie nicht optimiert sein sollen oder sind sie das automatisch (habe keine Einstellung dazu gefunden)? Am Datenbaustein der Partner CPU, welche ich im Simatic Manager programmiere, kommt nämlich nichts an...

Und um Dir nun helfen zu können: Den Aufruf (Netzwerk) hier mittels Screenshot einfügen und optimalerweise auch gleich die Hardwareadressen, da ich vermute das hier der Fehler liegen könnte.
 
Bei der 300/400er gibt es noch nichts mit optimiert/nicht optimiert. Da ist es immer optimal, d.h. es funktioniert ;-)

Danke für die schnelle Antwort! Okay, dann liegt es daran nicht. Wird in der Partner CPU ein GET Baustein überhaupt benötigt. Also für das Schreiben auf z.B. Merker hat es ohne GET geklappt. Ist das bei Datenbausteinen anders?
 
Danke für die schnelle Antwort! Okay, dann liegt es daran nicht. Wird in der Partner CPU ein GET Baustein überhaupt benötigt. Also für das Schreiben auf z.B. Merker hat es ohne GET geklappt. Ist das bei Datenbausteinen anders?

Entweder schreibt (PUT) eine CPU etwas in eine andere oder eine holt (GET) sich Daten aus einer anderen. Nur eine Anweisung ist nötig, weshalb PUT/GET eine "geschmierte", unsichere Übertragung ist, aber möglich.
 
Und um Dir nun helfen zu können: Den Aufruf (Netzwerk) hier mittels Screenshot einfügen und optimalerweise auch gleich die Hardwareadressen, da ich vermute das hier der Fehler liegen könnte.

habe in TIA einen DB11 mit einem einer Testvariable (Bool), die durch einen Taktmerker gesteuert (SR Glied) kontinuierlich den Wert von 0 auf 1 ändert. Im Simatic Manager habe ich auch einen DB11, in dem genau eine Variable drinsteht (natürlich auch Bool). Theoretisch müsste die Variable im Simatic Manager ja jetzt auch ständig den Wert ändern, richtig? Tut sie aber nicht.
Die S7 Verbindung steht und wenn ich nur Variablen übertrage und keine ganzen DBs, dann klappt das auch...

K3PlegrI09AAAAAASUVORK5CYII=
 
Das sieht soweit erst einmal nicht schlecht aus. An REQ wird eine Flanke erwartet, das ist dir klar? Dann bin ich mir nicht sicher, ob es mit dem Datentyp "Bool" funktioniert, denke aber doch. Probiere vielleicht mal mit "Byte".



Aus der Onlinehilfe:
.. Zulässig sind nur die Datentypen BOOL (bei einem Bitfeld muss als Adresse "0" und als Länge ein ganzzahlig Vielfaches von Byte verwendet werden) ..
Wie muss man das verstehen? Sind in Verbindung mit BOOL nur Längen von 8, 16, etc. möglich? Einzelne Bits werden wahrscheinlich nur höchst selten übertragen. Ich zumindest hatte so etwas noch nicht.
 
Zuletzt bearbeitet:
Zurück
Oben