Rockwell EtherNet/IP

通过 EtherNet/IP 连接 Allen-Bradley 控制器:ControlLogix、CompactLogix、PLC-5、SLC 500、MicroLogix 和 Micro800,它们的点位地址、数据类型和网络设备发现。

以 Markdown 查看

Rockwell EtherNet/IP 驱动通过 EtherNet/IP 和 Allen-Bradley / Rockwell 的控制器对话。ControlLogix 和 CompactLogix 控制器按 Logix 项目里声明的控制器标签名寻址,Micro800 按它的全局变量名寻址,PLC-5、SLC 500 和 MicroLogix 按数据文件地址寻址,完全不涉及寄存器映射。在 Connector 里的 Rockwell EtherNet/IP 驱动下面添加一台设备,并选好它的控制器系列;面板只显示这个系列用得到的那些字段。

控制器系列

设备的控制器系列决定怎样够到控制器,以及它的点位怎样寻址:

控制器系列 控制器 点位寻址方式 槽位
ControlLogix / CompactLogix ControlLogix、CompactLogix 控制器标签,即标签名 有
PLC-5 带以太网口的 PLC-5(PLC-5/20E、/40E、/80E) 数据文件地址,例如 N7:0 无
SLC 500 SLC 5/05 数据文件地址 无
MicroLogix MicroLogix 1100 和 1400,其他型号经 1761-NET-ENI 数据文件地址 无
Micro800 Micro820、Micro850、Micro870 控制器标签,即全局变量名 无

默认是 ControlLogix / CompactLogix,在这个字段出现之前建的设备也属于它,所以读取方式和以前完全一样。只有 ControlLogix 或 CompactLogix 控制器经背板在某个槽位上够到;其他系列都在自己的以太网口上应答,所以它们的设备没有槽位字段。设备发现从控制器的身份里读出系列,所以找到的控制器到达时系列已经选好。

连接

字段 含义 默认值
主机 控制器以太网口的 IP 地址或主机名。 空
控制器系列 控制器所属的系列;它决定下面的字段以及点位怎样寻址。 ControlLogix / CompactLogix
槽位 仅限 ControlLogix / CompactLogix:控制器插在机箱的第几位,从 0 数起。 0
轮询间隔(ms) 整台设备的读取周期,供没有自己另作规定的点位使用。 1000

没有端口字段:EtherNet/IP 用它标准的 TCP 端口 44818。CIP 路由是背板加上槽位,所以控制器插在机箱哪一位都够得着;发现出来的控制器从槽位 0 开始,那个字段就是你改正它的地方。没有机架字段:CIP 路由里不带机架号。请求 10 秒之后超时。设备标题栏显示拼好的 endpoint,例如 eip://192.168.0.10:0,地址后面那个数字就是槽位。

其他系列的控制器不带槽位,标题栏改为写出系列,例如 eip://192.168.0.20?family=slc500。

每个点位都可以设自己的轮询间隔(ms);点位填 0 就退回设备的间隔。

寻址

Rockwell 的点位靠点位“信号源”卡片里的两个字段寻址:

字段 含义 接受的取值 默认值
控制器标签 控制器里声明的那个标签名。必填。 自由文本 空
标签内偏移量(字节,BOOL 为位) 这个值落在那个标签数据里的什么位置:一个字节偏移,或者对布尔点位来说是一个位偏移。 0–255 0

驱动按名字打开那个控制器标签,再从它的数据缓冲区里按偏移把值挑出来。对一个普通的原子标签,偏移保持 0。正是这个偏移让一个控制器标签能服务好几个通道:一个结构开头的 DINT 是偏移 0,四个字节之后的 REAL 是偏移 4,而对布尔点位来说,偏移数的是位而不是字节。

要读的东西 控制器标签 偏移 数据类型
控制器作用域的 DINT Counter Counter 0 Int32
Main 里程序作用域的一个 DINT Program:Main.Counter 0 Int32
REAL 数组的一个元素 Temps[2] Temps[2] 0 Float
BOOL 数组的一个元素 Flags[5] Flags[5] 0 Boolean
结构 Recipe 里的第二个 DINT Recipe 4 Int32
Flags 数据里的第 3 位 Flags 3 Boolean

在 BOOL 数组里,索引指的是那个 BOOL,而不是控制器的 32 位字:Flags[5] 就是编号为 5 的 BOOL;按位的偏移从所指的 BOOL 往后数,所以 Flags[5] 加偏移 2 就是编号为 7 的 BOOL。

名字是整个送到控制器那里的,中间的点也在内,而同一个标签的读和写落在同一个地方。正因如此,Program:Main.Counter 这种程序作用域的名字才管用。带点的成员路径(MyUdt.Member)在控制器按名字发布那个成员时由控制器解析;控制器不发布时,就点名基础的控制器作用域标签,再用字节偏移伸进去,这条路永远走得通。“信号源”卡片里那行只读的源地址(总线)会随着你编辑显示拼好的地址。

Micro800 也这样寻址,用 Level 这样的全局变量名:它没有程序范围的标签可写。

数据文件地址

PLC-5、SLC 500 或 MicroLogix 的点位只靠一个字段寻址,即数据文件地址:依次写文件字母和编号、冒号和元素,然后在点号后写成员,或在斜杠后写位。没有偏移量字段,因为地址自己写明了元素、成员和位;驱动读不了的地址,这个字段在你输入时就会拒绝,并说明原因。

文件 示例 读取 数据类型
整数(N) N7:0、N7:0/15 一个 16 位字,或它的某一位 Int16 或 UInt16;位为 Boolean
位(B) B3:0、B3:0/2 一个 16 位字,或它的某一位 Int16 或 UInt16;位为 Boolean
浮点(F) F8:1 一个 32 位浮点值 Float
长整数(L) L9:0 一个 32 位整数 Int32 或 UInt32
定时器(T) T4:0.ACC、T4:0.PRE、T4:0.DN ACC 或 PRE,或者 EN、TT、DN 位 Int16 或 UInt16;位为 Boolean
计数器(C) C5:0.ACC、C5:0.PRE、C5:0.DN ACC 或 PRE,或者 CU、CD、DN、OV、UN 位 Int16 或 UInt16;位为 Boolean
控制(R) R6:0.LEN、R6:0.POS LEN 或 POS Int16 或 UInt16
状态(S) S:1、S:1/15 状态文件的一个字,或它的某一位 Int16 或 UInt16;位为 Boolean
输入(I)、输出(O) I:0、I:0/1、O:0/1 输入或输出映像的一个字,或它的某一位 Int16 或 UInt16;位为 Boolean

可选的数据类型跟随文件;输入一个地址,如果它的文件不存放点位当前的类型,类型就会改成该文件的类型。状态、输入和输出文件可以像编程软件那样省略编号来写;驱动会把它们作为 S2:1、I1:0/1 和 O0:0/1 发送,源地址(总线)那一行会显示出来。在输入或输出地址里,元素是该字在映像中的位置:MicroLogix 的内置输入从 I:0/0 开始。定时器、计数器或控制元素通过它的某个成员读取,从不整体读取;字符串、ASCII、BCD、消息和 PID 文件不读取。PLC-5 用八进制为输入和输出编号,驱动不读取这种编号,所以它的 I 和 O 文件会被拒绝:请让程序把这样的值复制到一个数据文件里,再通过该数据文件读取。文件是否存在要读了才知道:控制器没有的文件(没有 N9 时的 N9:0)从该点位第一次读取起就读作错误,设备的其他点位照常读取。

数据类型

每一种 CIP 原子类型都能作为点位的数据类型:

数据类型 CIP 类型 大小
Boolean BOOL 位偏移处的 1 个位
SByte SINT 1 字节
Byte USINT 1 字节
Int16 INT 2 字节
UInt16 UINT 2 字节
Int32 DINT 4 字节
UInt32 UDINT 4 字节
Int64 LINT 8 字节
UInt64 ULINT 8 字节
Float REAL 4 字节
Double LREAL 8 字节

不支持结构和 UDT:只有上面那些原子类型能读能写,而字节偏移的存在,正是为了伸进它们里面去够成员。选择器里刻意没有 String:Logix 的 STRING 不是原子类型,而是一个由长度和一个 82 字节数组组成的结构,驱动既读不了也写不了。总线上的字节序就是 CIP 自己的小端序,由驱动自动处理;没有字节序选项。

在 PLC-5、SLC 500 或 MicroLogix 上,类型改为跟随数据文件,见上面的数据文件地址表。

写入

访问为读写或只写的点位可以被写。一次写入只送出要写的那个值,旁边的东西一概不带,所以同一瞬间在控制器里变了的某个位或某个成员,绝不会被改回片刻之前的样子:

点位寻址的是 写入送出的是
一个完整的原子标签(偏移 0,大小就是标签本身的大小),或一个 BOOL 标签 这个值,写到那个标签
整数标签里的一个位(Flags,偏移 3,Boolean) 只有这个位,写成 Flags.3:控制器就地改掉它,其他位原样不动
BOOL 数组的一个元素(Flags[5],Boolean) 只有这个 BOOL,作为数组第一个字的第 5 位(Flags[0].5):控制器就地改掉它,这个字里其他的 BOOL 原样不动
结构里的一个值(Recipe,偏移 4) 只有这个成员,按名字写(Recipe.Speed),名字是从控制器发布的结构定义里找到的

只能把标签其余部分一起写回才能完成的写入会被拒绝,拒绝理由会点出这个地址:原子标签的一部分(DINT 偏移 2 处的一个 Int16)、REAL 的一个位,或者结构里没有哪个成员以这个值的大小从该偏移开始。这时请按值自己的名字寻址,例如 Recipe.Speed,偏移 0。驱动在一个点位第一次写入时弄清它的写入落在哪里,并在设备保持连接期间记住这个结果。新点位一开始是只读。

数据文件地址按它所写的样子写入:字、浮点值或成员整体写入,位(B3:0/2、T4:0.DN)只写这一位,控制器在原处修改它,字里的其他位保持不变。

设备发现

Connector 的“发现设备”按钮会在本机所在的每一个网络上广播一个 CIP List Identity 请求,并一直听下去,直到有 10 秒没有新的回答为止。扫描期间它会把那些网络点出来,所以结果为零时你知道这个问题究竟发到哪里去了:一台装着给虚拟机、WSL 或 VPN 用的虚拟网卡的工作站,网络往往比操作员以为的多,候选项也可能是从其中某一个上来的。

承载不了这个请求的接口会被跳过:任何没有起来的接口、回环和隧道适配器,以及接口在没人应答 DHCP 时自己给自己取的那种地址(169.254.x.x)。只有确实是控制器自身身份回答的应答才成为候选设备,名字是 eip:// 加上它的地址;在 EtherNet/IP 端口上应答的其他任何东西都被忽略,并在诊断日志里说明。Omron 控制器也会应答同一个请求,同样被排除,并在诊断日志里单独记一行:NJ、NX 或 NY 控制器改由 Omron 驱动的扫描提供。随后,扫描为每一个候选项读取控制器作用域的标签列表,把它的那些原子标签作为候选通道提供出来,每一个的偏移都是 0。原子类型的数组以它的第一个元素、按那个类型提供(Temps[0],两维时是 Grid[0,0]),BOOL 数组则以它第一个 BOOL 上的一个 Boolean 提供(Flags[0])。

设备发现会把驱动轮询不了的东西丢掉:结构和 UDT 标签(含 Logix 的 STRING)被丢掉,Program:、Task: 和 Map: 这几类条目被跳过。一台不在本机所在网络上的控制器不会应答广播;请手工添加它。其他任何类型的标签,比如系统类型,也不会提供出来,并在诊断日志里说明。

控制器应答的身份里带有它的目录号,目录号写明了它的系列:PLC-5、SLC 500、MicroLogix 或 Micro800 到达时系列已经选好,地址里也写着它(eip://192.168.0.20?family=micrologix)。PLC-5、SLC 500 和 MicroLogix 不公布点位清单,所以到达时没有候选通道,它们的点位按数据文件地址填写;Micro800 的点位清单和 Logix 的一样读取。

已经有的 Logix 或 Micro800 控制器可以在自己的页面上重新读它的标签列表:“点位”卡片标题栏里的发现点位只列出它还没有点位的控制器标签,按名称比较,不区分大小写。数据文件型控制器没有可读的列表,也没有“发现点位”(见发现一台设备的点位)。

需要知道的事

  • 发往控制器的每一个请求都在 10 秒之后超时,而设备发现的监听窗口在沉默 10 秒之后关闭。
  • 驱动把每一个控制器标签只打开一次,并在设备保持连接期间一直开着,所以带着几十个标签的控制器是在它已经有的会话上读的,而不是每读一次就开一次、关一次。读失败的那一次会放掉自己的标签,下一次读再按名字把它打开。
  • 在 Logix 项目里给标签重命名会悄悄把这个通道弄断;在配置的名字重新对上之前,这个点位读作质量不可用。