IP_CONTROL Paket nur einmal senden

Begonnen von BOBmoraine, 25. Januar 2017, 15:51:33

Vorheriges Thema - Nächstes Thema

0 Mitglieder und 1 Gast betrachten dieses Thema.

BOBmoraine

Moin,
ersteinmal danke für die tolle Bibliothek!

Ich habe mir mit Hilfe von der Forumsuche folgenden Baustein zusammengesucht da das Beispielprogramm in der PDF der Bibliothek nicht ganz korrekt war.
PROGRAM POU_TCP4
VAR
IP_Control_Step: INT; //Schritt
j: INT; //FOR-i Zähler

IP_C_0 : OSCAT_NETWORK.IP_C;
S_BUF_0: OSCAT_NETWORK.NETWORK_BUFFER;
R_BUF_0: OSCAT_NETWORK.NETWORK_BUFFER;
T_BUF:  OSCAT_NETWORK.NETWORK_BUFFER;
IP_CONTROL_0: OSCAT_NETWORK.IP_CONTROL;

Taster_Start: BOOL; //Taster WebVisu
RTRIG_StartIN : R_TRIG; //Flanke

UID: UDINT; //UID as uint32 (4 byte)
PacketLength: USINT; //Packet length as uint8 (1 byte)
FunctionID: USINT; //Function ID as uint8 (1 bytes)
SequenceOptions: USINT; //Sequence number and Options as uint8 (1 byte)
Flags: USINT; //Flags as uint8 (1 byte)
TCP4_Address: STRING; //IP-Adresse
TCP_Port: UINT; //Port
TCP_Mode: BYTE; //C_Mode
TCP_Running: BOOL; //Hilfsmerker für Visu
TCP_LastError: DWORD; //Hilfsmerker für Visu
TCP_Timeout: TIME; //Timeout-Zeit der Verbindung
ii: INT; //FOR-i Zähler
ii_max: INT; //FOR-i Max-Wert
GetValue: BOOL; //Hilfsmerker Paketauswertung
WordValue: UINT; //WordValue Paketauswertung
RealValue: REAL; //RealValue Paketauswertung
END_VAR

// Passiert in einem anderen Baustein:
//(* blinkmerker *)
//genBlinkmerker_60s( PT:= T#60S, Q=>GVL.blinkMerker_60_s );
//(* GVL.SendedatenVorhanden *)
//RTRIG_SendedatenVorhanden(CLK:= GVL.blinkMerker_60_s);
//IF RTRIG_SendedatenVorhanden.Q THEN
// GVL.SendedatenVorhanden := TRUE;
//END_IF
//OSCAT_NETWORK v 1.2.1.0
//OSCAT_BASIC v 3.3.3.0
//CODESYS V3.5 SP10
//CODESYS Control for Raspberry pi V3.5.10.0


//Start-Flanke
RTRIG_StartIN(CLK:= Taster_Start);

//Tinkerforge
//6JKUg4 -> 3765642289
//dDY -> 42570
UID := 42570; //UID as uint32 (4 byte)
PacketLength := 8; //Packet length as uint8 (1 byte)
FunctionID := 1; //Function ID as uint8 (1 bytes) - get_temperature
SequenceOptions := OSCAT_BASIC.BYTE_OF_BIT(B0:=0, (* Seq. *)
B1:=0, (* Seq. *)
B2:=0, (* Seq. *)
B3:=1, (* Seq. *)
B4:=1, (* Response *)
B5:=0, (* Opt. *)
B6:=0, (* Opt. *)
B7:=0 (* Opt. *)); //Sequence number and Options as uint8 (1 byte) SSSSROOO
Flags := 0; //Flags as uint8 (1 byte)
//Verbindung
TCP4_Address := '192.168.0.13';
TCP_Port := 4223;
TCP_Mode := 0; //0==TCP aktiv, 1==UDP aktiv, 2==TCP passiv , 3==UDP passiv, 4==TCP passiv anonym, 5==UDP passiv anonym
TCP_Timeout := T#2S500MS;

// Ablauf entnommen von:
// http://www.oscat.de/community/index.php/topic,2385.msg12443.html#msg12443
CASE IP_Control_Step OF
0: (* auf Freigabe warten *)
TCP_Running := FALSE;
IF RTRIG_StartIN.Q THEN
IP_Control_Step := 5;
END_IF
5: (* Ressourcen anfragen *)
TCP_Running := TRUE;
IF IP_C_0.C_STATE = 0 THEN
IP_C_0.C_STATE := 1;
IP_C_0.C_IP := OSCAT_NETWORK.IP4_DECODE(TCP4_Address);
IP_C_0.C_PORT := TCP_Port;
IP_C_0.C_MODE := TCP_Mode;
IP_C_0.C_ENABLE := FALSE;
IP_C_0.TIME_RESET := FALSE;
IP_C_0.R_OBSERVE := FALSE;
R_BUF_0.SIZE := 0;
FOR j := 0 TO 200 DO
R_BUF_0.BUFFER[j]:= 0;
END_FOR
IP_Control_Step := 10;
END_IF

10: (* Warte auf Freigabe *)
TCP_Running := TRUE;
IP_C_0.C_IP := OSCAT_NETWORK.IP4_DECODE(TCP4_Address);
IP_C_0.C_PORT := TCP_Port;
IP_C_0.C_MODE := TCP_Mode;
IP_C_0.C_ENABLE := TRUE;
IP_C_0.TIME_RESET := TRUE;
IP_C_0.R_OBSERVE := TRUE;
R_BUF_0.SIZE := 0;

(* Sendedaten einrichten *)
IF GVL.SendedatenVorhanden THEN
S_BUF_0.BUFFER[0] := OSCAT_BASIC.BYTE_OF_DWORD(in:=UID, N:= 0); //UID.0
S_BUF_0.BUFFER[1] := OSCAT_BASIC.BYTE_OF_DWORD(in:=UID, N:= 1); //UID.1
S_BUF_0.BUFFER[2] := OSCAT_BASIC.BYTE_OF_DWORD(in:=UID, N:= 2); //UID.2
S_BUF_0.BUFFER[3] := OSCAT_BASIC.BYTE_OF_DWORD(in:=UID, N:= 3); //UID.3
S_BUF_0.BUFFER[4] := PacketLength;
S_BUF_0.BUFFER[5] := FunctionID;
S_BUF_0.BUFFER[6] := SequenceOptions;
S_BUF_0.BUFFER[7] := Flags;
S_BUF_0.SIZE := 8;
ELSE
S_BUF_0.SIZE := 0;
END_IF

//OSCAT_NETWORK.SYSLIBSOCKETS_OPTION := BYTE#2#0000_0001; //nötig?

//C_STATE
//0 Verbindung ist abgebaut
//1 Verbindung wurde abgebaut (negative Flanke) Wert ist nur für einen Zyklus vorhanden, dann wird 0 ausgegeben
//254 Verbindung wurde aufgebaut (positive Flanke) Wert ist für einen Zyklus vorhanden, dann wird 255 ausgegeben 
//255 Verbindung ist aufgebaut
//<127 Abfrage ob Verbindung abgebaut ist
//>127 Abfrage ob Verbindung aufgebaut ist
IF IP_C_0.C_STATE = 255 THEN
IP_Control_Step := 15;
ELSIF (IP_C_0.ERROR <> 0) THEN
IP_Control_Step := 5;
END_IF

15: (* Fehler abfangen *)
TCP_Running := TRUE;
IF (IP_C_0.ERROR <> 0) THEN
(* Abmelden *)
TCP_LastError := IP_C_0.ERROR;
IP_C_0.C_ENABLE := FALSE;
IP_C_0.R_OBSERVE := FALSE;
IP_C_0.C_STATE := 0;
IP_Control_Step := 5;
ELSIF (R_BUF_0.SIZE > 0) AND (OSCAT_NETWORK.IP4_TO_STRING(IP_C_0.C_IP) = TCP4_Address) THEN
//paket auswerten
T_BUF.SIZE := R_BUF_0.SIZE;
ii_max := R_BUF_0.SIZE-1;
FOR ii := 0 TO ii_max BY 1 DO
T_BUF.BUFFER[ii] := R_BUF_0.BUFFER[ii];
END_FOR
GetValue := TRUE;
GVL.SendedatenVorhanden := FALSE;
END_IF
END_CASE

IF GetValue THEN
WordValue := OSCAT_BASIC.WORD_OF_BYTE(B0:=T_BUF.BUFFER[8], B1:=T_BUF.BUFFER[9]);
RealValue := TO_REAL(WordValue) / 100;
GetValue := FALSE;
END_IF

IP_CONTROL_0(
IP:= IP_C_0.C_IP,
PORT:= IP_C_0.C_PORT,
TIME_OUT:= TCP_Timeout,
IP_C:= IP_C_0,
S_BUF:= S_BUF_0,
R_BUF:= R_BUF_0);

Ich möchte aber jedes Paket nur einmal abschicken.
So wie ich das Programm momentan habe werden aber zwei Pakete abgeschickt und auch wieder zwei Pakete empfangen bevor der Zyklus (Variable: GVL.SendedatenVorhanden) beendet wird.
Gibt es die Möglichkeit das Senden nach dem Absenden des ersten Paketes zu beenden und dann nurnoch die Antwort abzuwarten? Wobei das Antwortpaket keine Feste Größe hat.
Zusatzinfos:
- OSCAT_NETWORK v 1.2.1.0
- OSCAT_BASIC v 3.3.3.0
- CODESYS V3.5 SP10
- CODESYS Control for Raspberry pi V3.5.10.0
Ich hoffe ich habe nichts vergessen.

[EDIT]
P.S. Was macht denn der Parameter OSCAT_NETWORK.SYSLIBSOCKETS_OPTION := BYTE#2#0000_0001; ? Kann man das irgendwo nachlesen

peewit

hallo

1.
OSCAT_NETWORK.SYSLIBSOCKETS_OPTION

da es verschiedene codesys 2.x plattformen (SPS Runtimes) gibt die sich leider funktional etwas unterscheiden kann man mit dieser option zwischen diversen varianten umschalten.

2. die oscat network für codesys 3.x stammt mal nicht von mir und deswegen kann ich dir auch nicht sagen ob der IP_CONTROL Baustein darin auch sauber funktioniert bzw. auf deiner plattform richtig funktioniert !

3. der IP_CONTROL Baustein versendet bei richtiger anwendung auch nichts zweimal
    ob dein programm die ursache ist oder nicht ist immer schwer zu beurteilen

4. für die ersten tests solltest du etwas von den diversen demo-programmen im ordner "DEMO" ausprobieren
    solange diese nicht normal funktionieren wirst du mit deinen selbst geschriebene sachen sowieso kein glück haben

5. sobald eine verbindung aktiv ist und du bei S_BUF.SIZE eine sendelänge angibst wird das versenden aktiviert
    du solltest aber sicherstellen das du nur einmal für einen zyklus eine sendelänge einträgst
   

http://www.oscat.de/community/index.php/topic,1071.msg6404.html#msg6404

BOBmoraine

Moin,
wie lang ist denn ein Zyklus bei IP_Control?
Von S_BUF.SIZE:=nn bis IP_CONTROL_0.s_done, oder nur der Zyklus des Programms/Bausteins (in meinem Falle POU_TCP4)?
Da liegt dann wahrscheinlich mein Problem, weil der Rest funktioniert soweit.

peewit

als sps programmierer soltest du eigentlich den begriff  ein zyklus kennen

ein zyklus ist keine zeitangabe !



der code wird nur ein einziges mal aufgerufen bzw. abgearbeitet


ich habe dir doch auch einen link ins forum gegeben
dort ist ein einfacher baustein der etwas sendet


BOBmoraine

Moin,
das Zyklus keine Zeitangabe ist, war mir schon klar. Da war wohl die Wortwahl etwas unglücklich.
Aber ich hatte in meiner Ergänzung ja nicht nach einer Zeit gefragt sondern von welchen Anfangs- und Endpunkten man ausgeht  ;D

Und das mir der Link das Programm aufzeigen sollte hab ich erst später verstanden. Habs mir aber inzwischen schon angeschaut und den Unterschied gefunden, und wahrscheinlich meinen Fehler.

Danke für die Hilfe