在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。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 |
<?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的实例号
写入错误则认为此连接断开
坐等大佬D盘更新,祝大佬全家福寿安康
有公众号之类的吗,之前这个网站打不开了
[…] 关于使用Change…
[…] 关于使用Functi…
谢谢提醒,已删 :)