Sonstiges Offene TCP Kommunikation mit S7-300 + S7-1200

Matze001

Level-3
Beiträge
2.814
Reaktionspunkte
573
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo Zusammen,

in letzter Zeit habe ich immer mehr mit offener TCP-Kommunikation zu tun.
Im Forum gibt es immer mal wieder Codeschnipsel und Ideen, und ich wurde bereits
von einigen Leuten per PM angeschrieben ob ich ihnen weiterhelfen kann.
Damit sich das auch für alle lohnt, will ich hier zwei Beispiele einbringen.

Beispiel 1: TCP-Kommunikation am Beispiel eines HTTP-Requests für eine S7-300 in Step7
Beispiel 2: TCP-Kommunikation am Beispiel eines HTTP-Requests für eine S7-1200 in TIAP

Vorschläge für weitere Beispiele sind erwünscht. Ich werde ggf. kleine Beispielprojekte erstellen.


Achtung: Der Beitrag ist noch nicht vollständig, und Beispiel 1 ist bisher mangels 300er CPU
nur aus dem Kopf / aus einem alten Projekt runtergetippt. Ich denke ich werde ein Beispiel
im Step7 erstellen, dann sind alle deklarationen etc deutlich ersichtlich. Ich bin nämlich
etwas unzufrieden mit den Codeschnipseln die ich hier Poste. Da ich gerade "nur" eine
1200er auf dem Schreibtisch habe, werde ich mit dem Beispiel für diese weitermachen
und meinen Beitrag aktualisieren.



Beispiel1 TCP-Kommunikation am Beispiel eines HTTP-Requests für eine S7-300

Für die Kommunikation via TCP-IP werden folgende Bausteine benötigt:

TCON
TSEND
TRECV
*TDISCON

* TDISCON verwende ich nicht, da meine Verbindung immer bestehen bleiben soll
** Ich habe gerade beim Testen festgestellt, dass die Verbindung nur bei CPU-Stopp abgebaut wird (was ja auch gut ist),
das kann einem beim Testen aber ärgern, da die Bausteine ggf. intialisiert wurden beim Übertragen. Also nach jeder großen
Änderung CPU Stopp - oder T_DISCON verwenden!



Code:
FUNCTION_BLOCK FB100
TITLE ='HTTP_REQUEST'
AUTHOR : 'Matze001'
VERSION : '0.1'

// ==========================================================================
// = Versionshistorie                                                       =
// =                                                                        =
// = V0.1 22.11.2015 Matze001                                               =
// = -----------------------                                                =
// = Baustein erstellt, ungetestet                                          =
// =                                                                        =

// ==========================================================================

// ==========================================================================
// = Bausteinbeschreibung                                                   =
// =                                                                        =
// ==========================================================================

VAR_TEMP


END_VAR
VAR

            
T_SEND:         TSEND;
T_RCV:          TRCV;
T_CONN:         TCON;
T_PARAM:        TCON_PAR;    

CONNECT:        BOOL;
CONNECTED:      BOOL;
SENDEN:         BOOL;
TIMEOUT_SEND:   TON;

SEND: ARRAY[0..511] OF CHAR;
RECV: ARRAY[0..511] OF CHAR;
 
END_VAR

VAR_INPUT
INIT:           BOOL;
CONNECTION_ID:  WORD;
IP_ADDR1:       INT;
IP_ADDR2:       INT;
IP_ADDR3:       INT;
IP_ADDR4:       INT;
END_VAR


VAR_OUTPUT

END_VAR

VAR_IN_OUT

END_VAR;

// Init Sequenz
// ####################################################################################################
IF Init THEN
    CONNECT :=       FALSE;
    CONNECTED:=      FALSE;
    SENDEN:=         FALSE;
END_IF;

// Kommunikation
// ####################################################################################################
// ####################################################################################################

// Wenn noch keine Verbindung besteht Verbindung herstellen
// ####################################################################################################
IF NOT CONNECTED THEN

    // Verbindungseinstellungen schreiben        
    T_PARAM.id:= CONNECTION_ID;
    T_PARAM.CONNECTION_TYPE:= 17; // TCP
    T_PARAM.LOCAL_DEVICE_ID:= b#16#1; // Für IM151-8 PN/DP - ggf. anzupassen
    T_PARAM.LOCAL_TSAP_ID_LEN:= 0;
    T_PARAM.LOCAL_TSAP_ID[1]:= 0;
    T_PARAM.LOCAL_TSAP_ID[2]:= 0;
    T_PARAM.REM_TSAP_ID_LEN:= 0;
    T_PARAM.REM_TSAP_ID[1]:= 0;            
    T_PARAM.REM_TSAP_ID[2]:= 0;
    T_PARAM.ACTIVE_EST:= TRUE;
    T_PARAM.REM_TSAP_ID[2]:= 80; // Port eintragen
    T_PARAM.REM_TSAP_ID[1]:=0;
    T_PARAM.REM_TSAP_ID_LEN:= 2;
    T_PARAM.REM_STADDR_LEN:= 4;
    T_PARAM.REM_STADDR[1]:= INT_TO_BYTE(IP_ADDR1);
    T_PARAM.REM_STADDR[2]:= INT_TO_BYTE(IP_ADDR2);
    T_PARAM.REM_STADDR[3]:= INT_TO_BYTE(IP_ADDR3);
    T_PARAM.REM_STADDR[4]:= INT_TO_BYTE(IP_ADDR4);
            
    // Verbindung herstellen
    T_CONN(REQ :=               CONNECT 
               ,ID :=           CONNECTION_ID 
               ,CONNECT :=      T_PARAM
               ); 

    // Wenn T_CONN Done ausgibt, Verbunden melden
    IF T_CONN.DONE THEN
        CONNECTED := TRUE;
    END_IF;


    // T_CONN braucht eine Flanke am eingang REQ, daher erst 
    // nach dem ersten Zyklus auf True setzen 
    CONNECT:=TRUE;
 
         
END_IF;


// Daten empfangen
// ####################################################################################################
    T_RCV(EN_R :=               CONNECTED 
           ,ID :=               CONNECTION_ID 
           ,LEN :=              0 // Laenge 0 = Sofort empfangen - ggf. muss > 0 eingetragen werden
           ,DATA :=             RECV 
           ); 

// Daten senden
// ####################################################################################################
    T_SEND(REQ :=               SENDEN
            ,ID :=              CONNECTION_ID 
            ,LEN :=             47 // Laenge 47 Zeichen - Muss angepasst werden
            ,DATA :=            SEND 
            ); 


// Daten senden wenn Verbunden ist, neue Daten empfangen wurden
// oder der Timeout angeschlagen hat
IF CONNECTED AND (T_RCV.NDR OR TIMEOUT_SEND.Q) THEN
  SENDEN := TRUE;
END_IF;

// Bei erfolgreichem senden oder im Fehlerfall
// die Sendeanfrage zurücksetzen
IF T_SEND.DONE OR T_SEND.ERROR THEN
  SENDEN := FALSE;
END_IF;

// Nach 5 Sek Send erneut antriggern 
TIMEOUT_SEND(IN:=SENDEN,PT:=t#5s);



// Sendedaten aufbereiten
// ####################################################################################################
// ####################################################################################################

// Beispiel als String : 'GET /BEISPIEL  HTTP/1.1$RHost: 192.168.001.010 $N$N';

// Als Array of Char:

SEND[000] := 'G';
SEND[001] := 'E';
SEND[002] := 'T';
SEND[003] := ' ';
SEND[004] := '/';
SEND[005] := 'B';
SEND[006] := 'E';
SEND[007] := 'I';
SEND[008] := 'S';
SEND[009] := 'P';
SEND[010] := 'I';
SEND[011] := 'E';
SEND[012] := 'L';
SEND[013] := ' ';
SEND[014] := 'H';
SEND[015] := 'T';
SEND[016] := 'T';
SEND[017] := 'P';
SEND[018] := '/';
SEND[019] := '1';
SEND[020] := '.';
SEND[021] := '1';
SEND[022] := '$R';
SEND[023] := 'H';
SEND[024] := 'o';
SEND[025] := 's';
SEND[026] := 't';
SEND[027] := ':';
SEND[028] := ' ';
SEND[029] := '1';
SEND[030] := '9';
SEND[031] := '2';
SEND[032] := '.';
SEND[033] := '1';
SEND[034] := '6';
SEND[035] := '8';
SEND[036] := '.';
SEND[037] := '0';
SEND[038] := '0';
SEND[039] := '1';
SEND[040] := '.';
SEND[041] := '0';
SEND[042] := '1';
SEND[043] := '0';
SEND[044] := ' ';
SEND[045] := '$R';
SEND[046] := '$R';

// Empfangsdaten auswerten
// ####################################################################################################
// ####################################################################################################

// Neue Daten angekommen
IF T_RCV.NDR THEN
    
    // Hier auswerten
    ;
    
END_IF;
    

END_FUNCTION_BLOCK


Mit diesem Code sollte es nun möglich sein, die Anfrage zu versenden.
Dies geschiet ständig, immer wenn eine neue Nachricht empfangen wird wird
eine neue Anfrage abgeschickt. Wer dies nicht wünscht kann das Senden
auch manuell antriggern.

Wichtig: Die LEN-Parameter von T_SEND und T_RECV.
Beim Senden ist die Länge des Strings (oder Array of Char) anzugeben.
Beim Empfangen wird bei LEN = 0 sofort etwas empfangen, wenn neue Daten kommen.
Ich habe aber leider einen Fall wo dies nicht funktioniert, da muss ich leider eine LEN angeben.
Dies ist im Einzelfall zu prüfen.







Grüße

Marcel



 

Anhänge

  • TCP_DEMO_2015_11_22.zip
    40,6 KB · Aufrufe: 212
Zuletzt bearbeitet:
Vielen Dank für deinen Beitrag.
Bin gearde dabei deinen Baustein zu Testen.

Beim Testen bin ich auf folgendes Problem gestossen.
Wenn ich eine Webseite öffnen möchte bekommen ich immer als Resposne einen Http 414 Request URL too Long Fehler, woran könnte das liegen??
Sind bei mir die $R zeichen richtig gesetzt ??

SEND[000] := 'G';
SEND[001] := 'E';
SEND[002] := 'T';
SEND[003] := ' ';
SEND[004] := '/';
SEND[005] := ' ';
SEND[006] := 'H';
SEND[007] := 'T';
SEND[008] := 'T';
SEND[009] := 'P';
SEND[010] := '/';
SEND[011] := '1';
SEND[012] := '.';
SEND[013] := '1';
SEND[014] := '$R';
SEND[015] := 'H';
SEND[016] := 'o';
SEND[017] := 's';
SEND[018] := 't';
SEND[019] := ':';
SEND[020] := ' ';
SEND[021] := '1';
SEND[022] := '9';
SEND[023] := '2';
SEND[024] := '.';
SEND[025] := '1';
SEND[026] := '6';
SEND[027] := '8';
SEND[028] := '.';
SEND[029] := '0';
SEND[030] := '0';
SEND[031] := '0';
SEND[032] := '.';
SEND[033] := '0';
SEND[034] := '9';
SEND[035] := '0';
SEND[036] := ' ';
SEND[037] := '$R';
SEND[038] := '$R';
SEND[039] := ' ';
SEND[040] := ' ';
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo,

sorry das ich so spät antworte! Danke für die Erinnerung per PM!

Zwei Dinge fallen mir dazu ein:

1. Du hast die Sendelänge nicht auf 39 Zeichen begrenzt, und der Baustein sendet noch das Ende
von meiner Zeichenkette (die länger ist) mit.

2. Die zwei $R$R am Ende müssen durch $N$N ersetzt werden. Bitte mal testen. In Step7 geht das, TIAP akzeptiert das nicht.

Grüße

Marcel
 
Guten Abend,

als erstes mal ein Lob am Forum da ich bis jetzt auf alle meiner Fragen eine Antwort gefunden habe.

Ich bin schon auf der längeren Suche nach dem 2ten Beispiel.
Jedoch kann ich den Download zu Beispiel 2 nicht finden!?

Ich bin nämlich gerade ein wenig am verzweifeln warum meine Verbindung S7-1214C -> FritzBox nicht klappt.
Bzw. ich möchte ein HTTP Request ausführen.

Das genannte 2te Beispiel wäre die Lösung meiner Probleme. Würde mich freuen wenn dies Online gestellt werden könnte.

Gruß

Andreas
 
Zuletzt bearbeitet:
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo,
ich versuche mich gerade auch zum ersten mal an einem TCP-Verbindungsaufbau und habe diese Vorlage genutzt um diesen zu realisieren.
Ich benutze das TIA Portal V14.
Ich dachte mit untem stehenden Code koennte ich einen Verbindungsaufbau realisieren. Jedoch wird mir immer der Status Code 7000 ausgegeben, was bedeutet, dass kein REQ anliegt, was den Baustein aktiviert.
Code:
IF #s_bInit THEN
    #s_bConnect := FALSE;
    #s_bConnected := FALSE;
    ;
END_IF;

#TCON_Instance(REQ:=#s_bConnect,
               CONNECT:="PLC_1_Connection_DB_1",
               ID := 2);
#s_bConnect := TRUE;
IF #TCON_Instance.DONE THEN
    #s_bConnected := TRUE;
    ;
END_IF;
Ich habe den Baustein als Mulitinstanz eingefuegt und auf nachfolgendem Bild sind die Parameter dargestellt, die ich eingestellt habe.
ConfigTCON.JPG

Kann mir jemand sagen, warum mein TCON nicht aktiviert wird?
Vielen Dank fuer jegliche Antworten zu meinem Post!

Gruesse
Ludwig
 
Hallo zusammen,

ich bin komplett am Verzweifeln. Ich muss mit einer S7 300 folgende HTTP GET Anfrage absenden:

"http://192.168.50.20:8080/send?receiver=1960001&message=Test+Text"

Ich habe das mit dem Siemens Bausteinen FB63 und FB65 versucht, aber das Problem ist anscheinend, dass die Software die das Empfangen soll keine direkte S7 Verbindung aufbaut. Heißt also, ich muss im Grunde " nur " /send?receiver=1960001&message=Test+Text an die IP mit Port senden, bzw den kompletten GET Link raushauen. Ich weiß aber nicht wie ich das noch bewerkstelligen soll. Wenn ich eine Verbindung versuche aufzubauen passiert entweder nix ( Status bleibt bei 7000 und DONE auf False ) oder ich bekomme einen Fehler zurück mit 80b3. ( dessen Bedeutung kann ich niergends finden Allerdings benutze ich jeweils einen anderen Parameter DB. Der, bei dem der Fehler kommt ist der Originale vom Beispielprojekt Siemens und der ohne das sich was ändert habe ich aus dem Wizard von Siemens.

Kann mit jemand Helfen?
Vielen Dank im Voraus.
 
Zurück
Oben