-> 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!
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
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
Zuletzt bearbeitet: