Twincat TCPClient FB_SocketReceive

tomatensaft

Level-2
Beiträge
159
Reaktionspunkte
5
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo,

ich hab mit jetz eine TCP Verbindung zwischen einer S7 und einem CX5020 eingerichet. Als Vorlage hab ich jeweils die Beispiele von Siemens (Open-Tcp-Communication) und von Beckhoff (TcpIP_Client) verwendet und auf meine Bedürfnisse angepasst.

Auf der S7-Seite funktioniert das Empfangen der Daten auch, nur auf der Beckhoff-Seite wird der Empfangsbuffer nach einer Zeit verschoben ->
Ich übertrage 100 Bytes und bei den ersten 5 Bytes schreibt ein Zähler auf ser S7-Seite seine Werte rein und schickt diese mit T_SEND ab.
Nachdem ich im TwinCat einen Reset durchführe und danch die Runtime wieder starte, werden wie Werte an der Richtigen stelle im Receive-Buffer geschrieben.
Nach einiger Zeit Verschieben sich die Werte irgendwo im Receive-Buffer - Die Werte bleiben alle zusammen und werden auch noch gelesen - nud diese stehen an irgendeiner beleibigen Stelle und nicht mehr am Anfang der Buffer wo diese eigentlich stehen sollten.

Nachdem ich wieder im Twincat wieder "Online/Reset" drücke und neu starte funktioniert alles wieder einwandfrei - ca. 10min - danach verschieben sich die Werte wieder.
Es gibt da auch kein Muster für die Verschiebung.
Die länges der Sende/Empfangsbereiche sind auch gleich lang.

Kann mir da jemand sagen warum der nach einiger Zeit die Bytes verschiebt ?
Code:
RisingEdge( CLK := bExecute );
CASE eStep OF
 DATAEXCHA_STATE_IDLE:
  IF RisingEdge.Q THEN
   bBusy := TRUE;
   bError := FALSE;
   nErrid := 0;
   fbReceiveTON( IN := FALSE, PT := T#0s ); (* don't wait, read the first answer data immediately *)
   fbDisconnectTON( IN := FALSE, PT := T#0s );(* disable timeout check first *)
   eStep := DATAEXCHA_STATE_SEND_START;
  END_IF
 DATAEXCHA_STATE_SEND_START:
  fbSocketSend( bExecute := FALSE );
  fbSocketSend(  hSocket := hSocket,
      pSrc := ADR( txBuffer ),
      cbLen := SIZEOF(txBuffer) ,
      bExecute:= TRUE );
  eStep := DATAEXCHA_STATE_SEND_WAIT;
 DATAEXCHA_STATE_SEND_WAIT:
  fbSocketSend( bExecute := FALSE );
  IF NOT fbSocketSend.bBusy THEN
   IF NOT fbSocketSend.bError THEN
    eStep := DATAEXCHA_STATE_RECEIVE_START;
   ELSE
    LogError( 'FB_SocketSend (local client)', fbSocketSend.nErrId );
    nErrId := fbSocketSend.nErrId;
    eStep := DATAEXCHA_STATE_ERROR;
   END_IF
  END_IF
 DATAEXCHA_STATE_RECEIVE_START:
  fbDisconnectTON(  );
  fbReceiveTON( IN := TRUE );
  IF fbReceiveTON.Q THEN
   fbReceiveTON( IN := FALSE );
   fbSocketReceive( bExecute := FALSE );
   fbSocketReceive(  hSocket:= hSocket,
   pDest:= ADR( rxBuffer ),
   cbLen:= SIZEOF( rxBuffer),
(*
       pDest:= ADR( rxBuffer ) + cbReceived,
       cbLen:= SIZEOF( rxBuffer ) - cbReceived,
*)
       bExecute:= TRUE );
   eStep := DATAEXCHA_STATE_RECEIVE_WAIT;
  END_IF
 DATAEXCHA_STATE_RECEIVE_WAIT:
  fbSocketReceive( bExecute := FALSE );
  IF NOT fbSocketReceive.bBusy THEN
   IF NOT fbSocketReceive.bError THEN
    IF (fbSocketReceive.nRecBytes > 0) THEN(* bytes received *)
     startPos   := cbReceived;(* rxBuffer array index of first data byte *)
     endPos    := cbReceived + fbSocketReceive.nRecBytes  - 1;(* rxBuffer array index of last data byte *)
     cbReceived  := cbReceived + fbSocketReceive.nRecBytes;(* calculate the number of received data bytes *)
     cbFrame  := 0;(* reset frame length *)
(*
     IF cbReceived < SIZEOF( sFromServer ) THEN(* no overflow *)
*)
(*
  IF cbReceived < 101 THEN(* no overflow sttic 100 Bytes*)
*)
      fbReceiveTON( PT := T#0s ); (* bytes received => increase the read (polling) speed *)
      fbDisconnectTON( IN := FALSE );(* bytes received => disable timeout check *)
        bBusy := FALSE;
        eStep := DATAEXCHA_STATE_IDLE;
(*
     FOR idx := startPos TO endPos BY 1 DO
;
     END_FOR
*)
(*
      (* search for string end delimiter *)
      FOR idx := startPos TO endPos BY 1 DO
       IF rxBuffer[idx] = 0 THEN(* string end delimiter found *)
        cbFrame := idx + 1;(* calculate the length of the received string (inclusive the end delimiter) *)
        MEMCPY(  ADR( sFromServer ), ADR( rxBuffer ), cbFrame );(* copy the received string to the output variable (inclusive the end delimiter) *)
        MEMMOVE( ADR( rxBuffer ), ADR( rxBuffer[cbFrame] ),  cbReceived - cbFrame  );(* move the reamaining data bytes *)
        cbReceived := cbReceived - cbFrame;(* recalculate the reamaining data byte length *)
        bBusy := FALSE;
        eStep := DATAEXCHA_STATE_IDLE;
        EXIT;
       END_IF
      END_FOR
*)
(*
     ELSE(* there is no more free read buffer space => the answer string should be terminated *)
      LogError( 'FB_SocketReceive (local client)',  PLCPRJ_ERROR_RECEIVE_BUFFER_OVERFLOW );
      nErrId := PLCPRJ_ERROR_RECEIVE_BUFFER_OVERFLOW;(* buffer overflow !*)
      eStep := DATAEXCHA_STATE_ERROR;
     END_IF
*)
    ELSE(* no bytes received *)
     fbReceiveTON( PT := PLCPRJ_RECEIVE_POLLING_TIME );(* no bytes received => decrease the read (polling) speed *)
     fbDisconnectTON( IN := TRUE, PT := PLCPRJ_RECEIVE_TIMEOUT );(* no bytes received => enable timeout check*)
     IF fbDisconnectTON.Q THEN (* timeout error*)
      fbDisconnectTON( IN := FALSE );
      LogError( 'FB_SocketReceive (local client)',  PLCPRJ_ERROR_RECEIVE_TIMEOUT );
      nErrID := PLCPRJ_ERROR_RECEIVE_TIMEOUT;
      eStep := DATAEXCHA_STATE_ERROR;
     ELSE(* repeat reading *)
      eStep := DATAEXCHA_STATE_RECEIVE_START; (* repeat reading *)
     END_IF
    END_IF
   ELSE(* receive error *)
    LogError( 'FB_SocketReceive (local client)',  fbSocketReceive.nErrId );
    nErrId := fbSocketReceive.nErrId;
    eStep := DATAEXCHA_STATE_ERROR;
   END_IF
  END_IF
 DATAEXCHA_STATE_ERROR:(* error step *)
  bBusy := FALSE;
  bError := TRUE;
  cbReceived := 0;
  eStep := DATAEXCHA_STATE_IDLE;
END_CASE
 
Zuletzt bearbeitet:
Eh wirklich Tomatensaft, du bist seit 2006 im Forum angemeldet und hast 116 Einträge. Nun wird es Zeit, dass du die Codetags findest um Code halbwegs vernünftig formatiert anzuzeigen.
(Im erweiterten Editor die Raute #)
 
Zurück
Oben