在Rockwell产品中使用socket通讯(作为服务端)

支持环境

Rockwell产品中使用5000软件进行编程的控制器有以下系列支持socket通讯:

  • 1756-EN2T, 1756-EN2F, 1756-EN2TR, 1756-EN3TR ControlLogix® EtherNet/IP communication modules, 固件版本不低于 5.007
  • 1756-EN2TP ControlLogix EtherNet/IP 通讯模块
  • 1756-EWEB ControlLogix EtherNet/IP web server 模块, 固件版本不低于 4.006
  • 1768-EWEB CompactLogix EtherNet/IP web server 模块, 固件版本不低于 1.002
  • 5370 CompactLogix 1769-L3y Controllers : 1769-L30ER(M)(S), 1769-L30ER-NSE, 1769-L33ER(M)(S), 1769-L36ERM(S), 1769-L37ERM(S), 1769-L38ERM(S)
  • 5370 CompactLogix 1769-L2y Controllers : 1769-L24ER-QB1B, 1769-L24ER-QBFC1B, 1769-L27ERM-QBFC1B
  • 5370 CompactLogix 1769-L1y Controllers : 1769-L16ER, 1769-L18ER(M), 1769-L19ER
  • 5380 CompactLogix 5069-L3z : 5069-L306ER(M)(S2), 5069-L310ER(M)(S2), 5069-L310ER-NSE, 5069-320ER(M)(S2), 5069-330ER(M)(S2), 5069-340ER(M)(S2), 5069-350ER(M)(S2),5069-380ER(M)(S2), 5069-3100ER(M)(S2)
  • 5580 ControlLogix 控制器: 1756-L81E(S), 1756-L82E(S), 1756-L83E(S), 1756-L84E(S), 1756-L85E

编程

本文简单介绍socket通讯所涉及到的创建、连接、写入、读取、删除等过程。在以上所示的Rockwell产品中,使用message(MSG)指令进行编程。

数据类型

在编程之前,我们要先创建所需的数据类型,需要支持的数据类型包括REQUEST_PARAMETERS、AcceptConnection、WRT_DATA、READ_DATA_REQ、READ_RESP_STR。

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<RSLogix5000Content SchemaRevision="1.0" SoftwareRevision="32.00" TargetName="AcceptResponse" TargetType="DataType" CurrentLanguage="en-US" ContainsContext="true" ExportDate="Fri Sep 02 13:26:43 2022" ExportOptions="References NoRawData L5KData DecoratedData Context Dependencies ForceProtectedEncoding AllProjDocTrans">
<Controller Use="Context" Name="ModbusTCP_Slave_R102">
<DataTypes Use="Context">
<DataType Name="SockAddr" Family="NoFamily" Class="User">
<Members>
<Member Name="Family" DataType="INT" Dimension="0" Radix="Decimal" Hidden="false" ExternalAccess="Read/Write">
<Description>
<![CDATA[Address Family Must be 2]]>
<LocalizedDescription Lang="en-US">
<![CDATA[Address Family Must be 2]]>
</LocalizedDescription>
</Description>
</Member>
<Member Name="Port" DataType="INT" Dimension="0" Radix="Decimal" Hidden="false" ExternalAccess="Read/Write">
<Description>
<![CDATA[Port Number]]>
<LocalizedDescription Lang="en-US">
<![CDATA[Port Number]]>
</LocalizedDescription>
</Description>
</Member>
<Member Name="Addr" DataType="DINT" Dimension="0" Radix="Decimal" Hidden="false" ExternalAccess="Read/Write">
<Description>
<![CDATA[IP Address]]>
<LocalizedDescription Lang="en-US">
<![CDATA[IP Address]]>
</LocalizedDescription>
</Description>
</Member>
</Members>
</DataType>
<DataType Name="STR_4096" Family="StringFamily" Class="User">
<Members>
<Member Name="LEN" DataType="DINT" Dimension="0" Radix="Decimal" Hidden="false" ExternalAccess="Read/Write"/>
<Member Name="DATA" DataType="SINT" Dimension="4096" Radix="ASCII" Hidden="false" ExternalAccess="Read/Write"/>
</Members>
</DataType>
<DataType Name="STR_OUT" Family="NoFamily" Class="User">
<Members>
<Member Name="LEN" DataType="DINT" Dimension="0" Radix="Decimal" Hidden="false" ExternalAccess="Read/Write"/>
<Member Name="BUFF" DataType="SINT" Dimension="480" Radix="Decimal" Hidden="false" ExternalAccess="Read/Write"/>
</Members>
</DataType>
<DataType Use="Target" Name="AcceptResponse" Family="NoFamily" Class="User">
<Members>
<Member Name="Instance" DataType="DINT" Dimension="0" Radix="Decimal" Hidden="false" ExternalAccess="Read/Write"/>
<Member Name="Addr" DataType="SockAddr" Dimension="0" Radix="NullType" Hidden="false" ExternalAccess="Read/Write"/>
</Members>
<Dependencies>
<Dependency Type="DataType" Name="SockAddr"/>
</Dependencies>
</DataType>
<DataType Use="Target" Name="READ_DATA_REQ" Family="NoFamily" Class="User">
<Members>
<Member Name="Timeout" DataType="DINT" Dimension="0" Radix="Decimal" Hidden="false" ExternalAccess="Read/Write">
<Description>
<![CDATA[Timeout for operation.  For reads this should be kept to 0 to prevent affecting write operations.]]>
<LocalizedDescription Lang="en-US">
<![CDATA[Timeout for operation.  For reads this should be kept to 0 to prevent affecting write operations.]]>
</LocalizedDescription>
</Description>
</Member>
<Member Name="BufLen" DataType="DINT" Dimension="0" Radix="Decimal" Hidden="false" ExternalAccess="Read/Write">
<Description>
<![CDATA[Typically set to 484, the maximum non-extended modbus transaction size.]]>
<LocalizedDescription Lang="en-US">
<![CDATA[Typically set to 484, the maximum non-extended modbus transaction size.]]>
</LocalizedDescription>
</Description>
</Member>
</Members>
</DataType>
<DataType Use="Target" Name="READ_RESP_STR" Family="NoFamily" Class="User">
<Members>
<Member Name="FromAddr" DataType="SockAddr" Dimension="0" Radix="NullType" Hidden="false" ExternalAccess="Read/Write"/>
<Member Name="Buf" DataType="STR_4096" Dimension="0" Radix="NullType" Hidden="false" ExternalAccess="Read/Write"/>
</Members>
<Dependencies>
<Dependency Type="DataType" Name="SockAddr"/>
<Dependency Type="DataType" Name="STR_4096"/>
</Dependencies>
</DataType>
<DataType Use="Target" Name="REQUEST_PARAMETERS" Family="NoFamily" Class="User">
<Members>
<Member Name="Type" DataType="DINT" Dimension="0" Radix="Decimal" Hidden="false" ExternalAccess="Read/Write">
<Description>
<![CDATA[1 - TCP 2- UPD]]>
<LocalizedDescription Lang="en-US">
<![CDATA[1 - TCP 2- UPD]]>
</LocalizedDescription>
</Description>
</Member>
<Member Name="Addr" DataType="SockAddr" Dimension="0" Radix="NullType" Hidden="false" ExternalAccess="Read/Write"/>
</Members>
<Dependencies>
<Dependency Type="DataType" Name="SockAddr"/>
</Dependencies>
</DataType>
<DataType Use="Target" Name="WRT_DATA" Family="NoFamily" Class="User">
<Members>
<Member Name="Timeout" DataType="DINT" Dimension="0" Radix="Decimal" Hidden="false" ExternalAccess="Read/Write"/>
<Member Name="ToAddr" DataType="SockAddr" Dimension="0" Radix="NullType" Hidden="false" ExternalAccess="Read/Write"/>
<Member Name="Buffer" DataType="STR_OUT" Dimension="0" Radix="NullType" Hidden="false" ExternalAccess="Read/Write"/>
</Members>
<Dependencies>
<Dependency Type="DataType" Name="SockAddr"/>
<Dependency Type="DataType" Name="STR_OUT"/>
</Dependencies>
</DataType>
</DataTypes>
</Controller>
</RSLogix5000Content>

 

通讯路径

MSG指令的通讯路径都选择本地通讯的模块。

5570 和 5560 控制器

如果通过界面手动键入,输入 1,[以太网模块的插槽]

如果以编程方式加载到.PATH 字段,则应传入 $01$xx,其中 xx 是槽的十进制值的十六进制等效值(例如,十六进制中的插槽 12 将为 0C)。

5370 控制器

如果通过界面手动键入,输入 1,0

如果以编程方式加载到.PATH 字段,传入 $01$00

5380 控制器

线性/DLR模式

如果通过界面手动键入,输入 1,0

如果以编程方式加载到.PATH 字段,传入 $01$00

双 IP 模式

如果控制器处于双 IP 模式,则消息路径将与上述相同,但是 CREATE 消息的源需要具有套接字将要通信的端口的 IP

注意:’THIS’将不能用作 5380 控制器的路径,双 IP 模式应使用上面提供的路径

5580 控制器

如果通过界面手动键入,输入 1,[控制器的插槽] 或者 THIS。THIS是软件预设的指向控制器的路径。

如果以编程方式加载到.PATH 字段,传入 $1F$00$00$00

程序编写

设置通讯模块属性

设置连接的属性。(可选)通讯模块的事件记录功能,默认此功能是关闭的,建议先判断是否修改了参数,如果修改了参数则写入一次该属性。

MSG指令的服务类型选择:Set Attribute Single

源元素数据类型:DINT 更改是否记录通讯连接的相关事件,置一则进行记录

.0 记录通讯连接的创建

.1 记录通讯连接的打开

.2 记录通讯连接的响应

.3 记录通讯连接的读取

.4 记录通讯连接的写入

.5 记录通讯连接的删除

.6 记录通讯连接的属性修改

.7 记录通讯连接的错误

类编号:0x342

属性编号:0x8

实例[MSG.Instance]:0

删除所有的Socket

可以在初始化时进行此操作。

MSG指令的服务类型选择:Custom

服务代码:0x51

类编号:0x342

属性编号:0x0

实例[MSG.Instance]:0

获取所有的Socket数量

MSG指令的服务类型选择:Get Attribute Single

类编号:0x342

属性编号:0x3

实例[MSG.Instance]:0

连接Socket创建

该指令创建一个Socket实例,并将实例号保存到目标元素内。该实例号用于后面所有针对该Socket实例的连接、写入、读取、删除等操作。

MSG指令的服务类型选择:Socket Create

源元素数据类型:REQUEST_PARAMETERS

.Type 1=TCP 2=UPD

.Addr.Family 必须设置为2

.Addr.Port 指定本地监听的端口号

.Addr.Addr 只用于5380控制器的双IP模式,其他情况为0。输入需要作为通讯用的IP地址,该IP地址以16进制形式转换后写入此DINT内。如下图所示

Port A1: 192.168.1.200(选择此IP进行通讯)

Port A2: 10.10.10.44


目标元素数据类型:DINT 如果创建成功,返回Socket实例号

连接Socket属性

设置Socket连接的属性。修改无活动连接判断时长,超过此时间则认为该socket无活动连接。

MSG指令的服务类型选择:Set Attribute Single

源元素数据类型:DINT 更改无活动连接的判断时长,可选60000

类编号:0x342

属性编号:0x7

实例[MSG.Instance]:创建Socket的实例号

客户端请求Socket响应

本指令会等待客户发送过来的连接请求,当接受到连接请求后,会额外创建一个连接Socket实例号,用于后续的数据传送等功能。

MSG指令的服务类型选择:AcceptConnection

源元素数据类型:DINT 接受超时时间,可选10000

目标元素数据类型:AcceptResponse

.Instance 响应连接请求的Socket实例号

.Addr.Family 反馈的Family

.Addr.Port 反馈的对方端口号

.Addr.Addr 反馈的对方IP地址

实例[MSG.Instance]:创建Socke的实例号

响应客户端请求的Socket属性

设置Socket连接的属性。修改无活动连接判断时长,超过此时间则认为该socket无活动连接。

MSG指令的服务类型选择:Set Attribute Single

源元素数据类型:DINT 更改无活动连接的判断时长,可选3000

类编号:0x342

属性编号:0x7

实例[MSG.Instance]:响应 Socket 的实例号

响应客户端请求的Socket读取

用于读取客户端发来的命令

MSG指令的服务类型选择:ReadSocket

源元素数据类型:READ_DATA_REQ

.Timeout 超时时间,无需修改,0即可

.BufLen 缓冲区大小,对应目标元素数据类型的长度,本例为484

目标元素数据类型:READ_RESP_STR

.FromAddr.Family

.FromAddr.Port 来源端口

.FromAddr.Addr 来源地址

.Buf 读取的数据缓存区

实例[MSG.Instance]:响应 Socket 的实例号

读取错误则认为此连接断开

响应客户端请求的Socket写入

用来给客户端返回数据

MSG指令的服务类型选择:WriteSocket

源元素数据类型:WRT_DATA

.Timeout 超时时间 ms,可选500

.ToAddr.Family 必须为2

.ToAddr.Port 无需修改,0即可

.ToAddr.Addr 无需修改,0即可

.Buffer.LEN 写入的数据长度

.Buffer.BUFF 写入数据的缓存区

可以使用COP指令,将STR_462类型的数据复制到.Buffer内。

源元素数据长度[MSG.REQ_LEN]:写入的数据长度 16

目标元素数据类型:DINT 如果写入成功,返回写入的数据长度

实例[MSG.Instance]:响应Socket的实例号

写入错误则认为此连接断开

版权声明:本文内容来源于网络搜集无法获知原创作者,仅供个人学习用途,若侵犯到您的权益请联系我们及时删除。邮箱:1370723259@qq.com

发表评论