IRC5 to B&R CPU - TCP IP data transfer

JVDK_DBM
JVDK_DBM Netherlands
I have a question regarding the TCP IP communication between a IRC5 (Client) and a B&R CPU (Server). 

The B&R Server is sending an UDINT array containing some cordinates and status bits. This being my first TCP IP and kind of my first real Robotstudio program, I'm having a hard time working out the details. 

Is receiving an UDINT array in Robotstudio as simple as just converting the rawdata to udint array?

Following code is what I have setup right now regarding the TCP Client.
//-------------------------------------------------------------

MODULE TCP_Client

PERS dnum TransferData_ToRobot {24};
PERS dnum TransferData_FromRobot {47};
VAR socketdev ClientSocket;
VAR socketstatus SocketStat;
VAR rawbytes raw_send;
VAR rawbytes raw_receive;
VAR bool diComms_Alive;
VAR num diForceStop;
VAR num doCommsError;

PROC Main()
VAR signaldi PLCAlive;
AliasIO diComms_Alive, PLCAlive;
!wait for plc to run
WHILE PLCAlive = 0 DO
WaitTime 5;
set doCommsError;
IF (diForceStop = 1) Stop; !force stop prog execution from pendant. diforcestop is on virtual_1 unit
ENDWHILE
!reset error
Reset doCommsError;
!clear raw data
ClearRawBytes raw_send;
ClearRawBytes raw_receive;
SocketClose ClientSocket;
!get client socket status
SocketStat := SocketGetStatus(ClientSocket);
WHILE NOT (SocketStat = SOCKET_CONNECTED) DO
WaitTime 2; !wait time before closing socket
SocketClose ClientSocket;
WaitTime 2; ! wait time before opening socket
IF (PLCAlive = 0) ExitCycle; !plc not running - wait for plc to come online
ConnectToServer "10.30.1.11", 1025; !connect to server addr and port no
SocketStat := SocketGetStatus(ClientSocket); !update client socket status
ENDWHILE
WHILE (SocketStat = SOCKET_CONNECTED) DO
IF (PLCAlive = 0) ExitCycle; !plc not running - wait for plc to come online
SendData;
ReceiveData;
ENDWHILE
ENDPROC

PROC ConnectToServer(string IPAddress, num PortNo)
VAR num RetryNo := 0;
SocketCreate ClientSocket; !create client socket
SocketConnect ClientSocket, IPAddress, PortNo; !connect to server with ip addr and portno supplied
TPErase;
TPWrite "Connection succesfull";
ERROR
IF ERRNO = ERR_SOCK_TIMEOUT THEN
WaitTime 1;
RetryNo := RetryNo + 1;
IF RetryNo >= 3 THEN
ErrWrite\I, "Connection failed", "Trying to connect to server failed. " \RL2 := "PP Goed to Main to check if PLC Alive. " \RL3 := "Retries is reset.";
TPWrite "Socket connection failed after 3 retries";
RetryNo := 0;
WaitTime 5;
ExitCycle;
ELSE
RETRY;
ENDIF
ELSEIF ERRNO = ERR_SOCK_CLOSED THEN
WaitTime 5;
ExitCycle;
ELSE
TPWrite "ERRNO = " \Num:=ERRNO;
Stop;
ENDIF
ENDPROC

PROC SendData()
ClearRawBytes raw_send; !clear raw data
!prep data to send
packet_send.x := packet_receive.x;
packet_send.y := packet_receive.y;
packet_send.z := packet_receive.z;
!etc etc
!pack pieces of data in the packet into raw_send
PackRawBytes packet_send.x, raw_send, (RawBytesLen(raw_send)+1)\Float4;
PackRawBytes packet_send.y, raw_send, (RawBytesLen(raw_send)+1)\Float4;
PackRawBytes packet_send.z, raw_send, (RawBytesLen(raw_send)+1)\Float4;
SocketSend ClientSocket \RawData := raw_send;
ERROR
IF ERRNO = ERR_SOCK_CLOSED THEN
TPWrite "Socket closed during sending data";
ExitCycle;
ENDIF
ENDPROC
PROC ReceiveData()
ClearRawBytes raw_receive; !clear raw data
SocketReceive ClientSocket \RawData := raw_receive\Time := 10;
!unpack raw_receive and save individual values in packet_receive
UnpackRawBytes raw_receive, 1, packet_receive.x \Float4;
UnpackRawBytes raw_receive, 5, packet_receive.y \Float4;
UnpackRawBytes raw_receive, 9, packet_receive.z \Float4;
SocketStat := SocketGetStatus(ClientSocket); !update status of client socket
ERROR
IF ERRNO = ERR_SOCK_TIMEOUT OR ERRNO = ERR_SOCK_CLOSED THEN
WaitTime 5; !wait to make sure server is started first
TPWrite "Comms time out during receiving data";
ExitCycle;
ENDIF
ENDPROC

ENDMODULE

//-------------------------------------------------------------
Any help would be appreciated!

Answers

  • graemepaulin
    graemepaulin New Zealand mod
    So you have the TCP-IP communications established between between the controller and the B&R?

    From there you can send individual bytes for the X, Y, Z values - these are setup at the controller end a a group input (or output) of the appropriate length.
    This is setup in the EIO configuration file - the system parameters help in RobotStudio will give all the details you need.
    The status bits are setup as individual signals.

    This way the values are updated automatically with no send and receive code required at the robot end....
  • JVDK_DBM
    JVDK_DBM Netherlands
    Thanks for your reply @graemepaulin

    I have a working connection with the B&R CPU. 

    The datatypes still aren't completly clear to me;
    Are the X,Y,Z send individually or as packets combined with the status bits?
    Also, do I need to reprogram the send packets (B&R end) to the individual bytes as well or can I unpack the UDINT array in the rapid code?

    By "updated automatically with no send and receive code" do you mean I only have to open the socket connection and the values will be collected automatically by the controller it self?

    Thanks in advance!
  • graemepaulin
    graemepaulin New Zealand mod
    If the B&R updates the byte or bit of information it is 'sent' directly to the controller and the new value is immediately available for use in the controller.
    You setup individual bytes (8, 16, 32, etc bits long to suit the data being sent) for the x, y, z.
    The status bits are just single bits.

    Yes you will need to change your B&R program to update the individual bytes & bits.
    It should be more flexible code as you only update the information required when required...
  • JVDK_DBM
    JVDK_DBM Netherlands
    If the B&R updates the byte or bit of information it is 'sent' directly to the controller and the new value is immediately available for use in the controller.
    You setup individual bytes (8, 16, 32, etc bits long to suit the data being sent) for the x, y, z.
    The status bits are just single bits.

    Yes you will need to change your B&R program to update the individual bytes & bits.
    It should be more flexible code as you only update the information required when required...
    The B&R updates the internal values everytime there is new data sent to it from one of the clients. If I'm understanding you correctly, the following code won't be necessary as the controller will retrieve the values automatically; PackRawBytes FromRobot1.ActualPos.X, raw_send, (RawBytesLen(raw_send)+1)\Float4;


  • JVDK_DBM
    JVDK_DBM Netherlands
    It's still quite unclear to me how this whole structure and code would need to be set up. It's kind of my first robotstudio program so bear with me please :smile:

    Preferably I would like to just send and receive whole packets like the records I've made seeing they are quite big;
    RECORD ToRob
    num AliveCounter;
    num FoundPiece;
    ResultPointType ResultPoint1; !-----x,y,z,alpha,beta,gamma
    ResultPointType ResultPoint2;
    CommandType Command; !----- 16 booleans
    SpareInt9Type SpareInt; !----- 9 int's
    ENDRECORD

    RECORD FromRob
    num AliveCounter;
    Rob_ActivePosType Rob1_ActivePos; !----- x,y,z
    Rob_ActivePosType Rob2_ActivePos;
    Rob_StatusType Rob1_Status; !----- 1 num & 31 error booleans
    Rob_StatusType Rob2_Status; 
    StatusType Status; !----- 2 int's
    SpareInt8Type SpareInt; !----- 8 int's
    ENDRECORD
  • graemepaulin
    graemepaulin New Zealand mod
    Correct if you setup a byte for each no code necessary for the data transmission, only to use the data.
  • JVDK_DBM
    JVDK_DBM Netherlands
    Correct if you setup a byte for each no code necessary for the data transmission, only to use the data.
    Could you show me an example of a correctly setup byte. I reckon it should be connected to a TCP IP IO Device??
  • graemepaulin
    graemepaulin New Zealand mod

    This is for a Fronius welder.
    You do not need to have the Category.