ABB socket通讯指南

2022-05-22 10:56:26 浏览数 (1)

一、

在工业自动化中,最常用的其实是profinet,工业设备通过配置,一根网线便可以实现数据可靠的实时发送或接受(1ms或者更短),profinet类似于profibus ethernet。但对于普通计算机,则不能与ABB机器人实现profinet通讯,只能用socket通信。

那么,tcp/ip与socket怎么理解呢?

TCP和UDP同属于传输层,共同架设在IP层(网络层)之上。IP层主要负责的是在节点,或者叫网络设备,或者叫电脑之间(End to End)的数据包传送,不区分应用。所以TCP和UDP协议在其基础上加入了端口,端口标识的是一个节点上的一个应用程序。

UPD协议除了增加端口信息,基本就没有对IP层的数据进行任何的处理了。而TCP协议还加入了更加复杂的传输控制,比如滑动的数据发送窗口(Slice Window),以及接收确认和重发机制,以达到数据的可靠传送。

socket跟TCP/IP并没有必然的联系。socket编程接口在设计的时候,就希望也能适应其他的网络协议。所以,socket的出现只是可以更方便的使用TCP/IP协议栈,其对TCP/IP进行了抽象,形成了几个最基本的函数接口,例如socketcreate,socketlisten,socketaccept等等。

如果一个程序创建了一个socket,并监听4002端口,其实是向TCP/IP协议栈声明了其对4002端口的占有,之后,所有目标是4002端口的TCP数据包都会转发至socket层传至该程序。

另外,TCP/IP协议不仅仅指的是TCP 和IP两个协议,而是指一个由FTP、SMTP、TCP、UDP、IP等协议构成的协议簇, 只是因为在TCP/IP协议中TCP协议和IP协议最具代表性,所以被称为TCP/IP协议。

二、

理解了基本的通讯知识,再看ABB机器人socket。

通过上面这张图可以看到socket的基本用法,socket的声明、服务端与客户端的建立等等,使用SocketGetStatus(server_socket)还可以查看socket的状态。

然后重点讲一下socket发送接收的三种数据类型:Str、Data、RawData。

三、

字符串类型的发送接收是简单的,不过有80个字符的限制

声明变量

代码语言:javascript复制
VAR socketdev sockte1;
VAR string sendStr;
VAR string receiveStr;
VAR num receiveStrNum;
VAR string strPart;
VAR string strVar;
VAR string Data{20};
VAR bool OK;
PERS num putX;
PERS num putY;
PERS num putZ;

接收指令

代码语言:javascript复制
SocketReceive sockte1 str:=receiveStrNoRecBytes:=receiveStrNum;

解析程序

代码语言:javascript复制
j:=1;
strVar:="";  
FOR i FROM 1 TO receiveStrNum DO
      strPart:=StrPart(receiveStr,i,1);
      IF strPart<>";" THEN
            strVar:=strVar strPart;
            strPart:="";
      ELSEIF strPart=";" THEN
            Data{j}:=strVar;
            strVar:="";
            strPart:="";
            j:=j 1;                 
      ENDIF           
ENDFOR
OK:=StrToVal(Data{1},pickX);
OK:=StrToVal(Data{2},pickY);
OK:=StrToVal(Data{3},pickZ);

发送指令

代码语言:javascript复制
sendStr:="1";
SocketSend sockte1str:=sendStr

四、

字节类型的发送接受,与字符串类似,只不过是建了一个byte类型的数组,用于存放数据。因最多发送接收为1024个byte,那就声明一个byte类型的1024长度的一维数组。

声明变量

代码语言:javascript复制
VAR socketdev sockte2;
VAR byte receiveByte{1024};
VAR string sendStr;
VAR num receiveByteNum;
VAR string strPart{1024};
VAR string strVar:="";
VAR string Data{512};
VAR bool OK;

接收指令

代码语言:javascript复制
SocketReceive sockte2Data:=receiveByteNoRecBytes:=receiveByteNum;

解析程序

代码语言:javascript复制
j:=1;
strVar := "";
FOR strP FROM 1 TO 1024 DO
      strPart{strP} := "";
ENDFOR
FOR i FROM 1 TO receiveByteNum DO
      strPart{i}:=ByteToStr(receiveByte{i}Char);
      IF strPart{i}<>";" THEN
            strVar:=strVar strPart{i};
      ELSEIF strPart{i}=";" THEN
            Data{j}:=strVar;
            strVar:="";
            j:=j 1;
      ENDIF
ENDFOR

发送指令

代码语言:javascript复制
sendStr:="1";
SocketSend sockte1str:=sendStr

五、

二进制字节的发送接收,ABB提供了丰富的解析指令,UnpackRawBytes解二进制字节、CopyRawBytes复制二进制字节、PackRawBytes把变量转为二进制字节等等。

但有个非常要注意点,ABB为了数据能可靠的得到接收内容,有一个“分包”发送机制:先发4个字节,再发剩余字节。

此处在ABB机器人端表现为2个receive指令。我们在开发上位机程序时,肯定想方设法满足这个“分包”,那就掉到“坑”里了,其实在实际测试中发现,上位机1包发所有的也可以,只要有4个字节的包头就行。

声明变量

代码语言:javascript复制
VAR socketdev sockte3;
VAR rawbytes receiveRawData;
VAR rawbytes sendRawData;
VAR num bytes_rcvd;
VAR num msg_length;
VAR num pickX;
VAR return_value

接收指令

代码语言:javascript复制
SocketReceive sockte3, RawData:=receiveRawData, ReadNoOfBytes:=4;
UnpackRawBytes receiveRawData,1,msg_length,IntX:=UDINT;
SocketReceive sockte3,RawData:receiveRawData,ReadNoOfBytes:=msg_length,NoRecBytes:=bytes_rcvd;
IF (bytes_rcvd<>msg_length) THEN
    ErrWriteW,"ROS Socket Recv Failed","Did not receive expected # of bytes.",
                 RL2:="Expected: " ValToStr(msg_length),
                 RL3:="Received: " ValToStr(bytes_rcvd);
    RETURN ;
ENDIF
UnpackRawBytes receiveRawData,1,pickX,IntX:=DINT;

发送指令

代码语言:javascript复制
PackRawBytes return_value,sendRawData,1,IntX:=DINT;
SocketSend sockte3,RawData:=sendRawData;

六、

此文献给对ABB socket有技术需求的朋友。

0 人点赞