一.软硬件环境
西门子PLC:1200、1500
欧姆龙PLC:支持FINS TCP协议的PLC,案例中使用CP1H系列
软件:博途V15.1,CX-Programmer V9.78,Wireshark
操作系统:Windows 10 企业版 22H2
虚拟串口:Virtual Serial Port Driver
串口转TCP:朝夕教育开发的转换软件
二.开发思路
西门子PLC与欧姆龙PLC并不能直接通讯,但可以通过其他开放协议通讯,比如MODBUS协议,也可以通过第三方软件或者上位机、触摸屏进行数据交换,比如kepware、组态王、威纶通HMI等方式。
在不便进行改造的工业现场,如何不经过第三方软硬件直接建立两个PLC的通讯呢?西门子1200/1500支持开放式以太网通讯,在欧姆龙FINS协议的框架下,通过编写一定的程序代码,是可以建立与欧姆龙PLC通讯的。
三.FINS TCP协议
FINS协议规定建立通讯需要满足一次握手成功的条件。此时,客户端PLC即西门子PLC需要向CP1H PLC发送固定帧格式的报文。
3.1 握手命令
客户端向服务器发送命令00000000:这个命令长20字节,分成5组4字节。分别是:头(FINS) + 长度(0000000C) + 命令(00000000)+ 错误码(00000000) + 客户机节点地址。
46494E53是FINS的ASCII码值,即命令头。
0000000C是命令长度20(这个是按长度后面的命令长度来算,这里即:命令+错误码+客户机节点地址)。
00000000是命令码。
00000000是错误码。
000000C8是客户节点地址,(电脑的IP尾数16进制)。
即: 46494E53 0000000C 00000000 00000000 000000C8
PLC回复命令00000001:这个命令的长度是24字节,分成6组4字节。分别是:头(FINS)+ 长度(00000010) + 命令(00000001) + 错误码 + 客户机节点地址 + 服务器地址。
46494E53是FINS的ASCII码值,即命令头。
00000010是命令长度24。
00000001是命令码。
00000000是错误码。
000000C8是客户节点地址,即电脑IP地址的末位(电脑的IP尾数16进制)。
00000001是服务器节点地址,即PLC IP地址的末位(电脑的IP尾数16进制)。
即: 46494E53 00000010 00000001 00000000 000000C8 00000001
上面的命令错误代码为0,客户端ip地址200已被服务器01(hex01)成功记录。
3.2 帧发送命令
命令分为读取与写入,写入是在读取命令报文的基础上,加上需写入的值。
如果向服务器发送FINS帧,就要用到这个命令。由于FINS帧长度是12-2012,因此命令长度可变,格式:头(FINS)+长度+命令(00000002)+错误码+FINS帧。
组成 | 字节数 | 说明 |
Header | 4 | 固定值 46494E53(FINS) |
Length | 4 | 从command命令开始到结束 |
command | 4 | 固定值 00000002 |
Error Code | 4 | 固定值 00000000 |
ICF | 1 | 固定值 80,其中bit0:0表示需要回复,1表示不需要回复;bit7:0表示命令,1表示响应 |
RSV | 1 | 固定值 00 |
GCT | 1 | 固定值 02 |
DNA | 1 | 目标网络号,固定值 00 |
DA1 | 1 | 目标节点号, IP地址最后一位而定 这里是01 |
DA2 | 1 | 目标单元号, 固定值 00 |
SNA | 1 | 源网络号,固定值 00 |
SA1 | 1 | 源节点号, IP地址最后一位而定 这里是C8 |
SA2 | 1 | 源单元号,固定值 00 |
SID | 1 | 固定值 00 |
MRC | 1 | 主请求码 |
SRC | 1 | 次请求码,主/次请求码组合:0101是读操作;0102是写操作代码;2301是强制操作代码 |
Parameter | N | N个字节 |
其中Parameter命令格式:
Fins读取数据是在通用命令基础上,将Parameter替换为Area+Address+Length
Fins写数据是在通用命令基础上,将Parameter替换为Area+Address+Length+Value
组成 | 字节数 | 说明 |
Area | 1 | 不同存储区值不一样,D区:82(DM存储区代码);W区:B1(W字代码),31(W位代码) |
Address | 3 | 起始地址(2bit)+位地址(1bit) |
Length | 2 | 读取或写入长度 |
value | 2 | 写入内容(针对写操作) |
具体可参考
<欧姆龙PLC的FinsTCP协议>
链接:https://blog.csdn.net/weixin_37700863/article/details/120536223
四.博途编程
主要程序已分组完成,需要移植到其他程序需要复制该分组,此外PLC变量、PLC数据类型菜单下的FINS分组也需要复制,见下图
![]()
图1 程序组 图2 变量组与数据类型组
1.程序调用
在OB1组织块中调用FC2功能即可。如有重复使用的功能、功能块、数据块编号,需手动修改。
2.块说明
2.1 "fins_productionData"
该程序是生产数据转化为可发送字节数据的功能块,在该块中可定义发送时间,按照读取与发送的示例程序编写发送程序。
在实际使用中,主要也是在该功能块中编写程序,其他程序块无需变动。
图3 生产数据转化成可发送数据功能块
2.2 "sendCycleFC"
该块主要是实现针对一台欧姆龙PLC的多条指令的循环发送,在 "fins_productionData"块中设置好满足条件时即可自动执行发送命令,日常使用时无需更改。
2.3 "tcp_FINS"
该程序块是与欧姆龙通讯的功能块,配置好IP等信息后无需更改。主要引脚参数定义见下表,可参数程序案例,见图4。
参数 | 声明 | 数据类型 | 说明 |
Enble | Input | Bool | 功能使能 |
nodeADDR | Input | Byte | 欧姆龙PLC节点地址 |
localPLC_IP | Input | IP_V4 | 西门子PLC IP地址 |
connectionSettings | Input | TCON_IP_v4 | 欧姆龙PLC连接参数,含PLCip、 端口号、节点地址等参数 |
executeCommand | Input | Bool | 执行一次发送,上升沿有效 |
sendDataInfo | Input | Struct | 待发送数据信息,固定使用command DB块中的公共接口 |
finsTelegramArray | InOut | Array[*] of Byte | 缓存字节数组 |
图4 tcp_FINS 接口通讯程序
3.参数DB块说明
主要需要修改的DB块已放置在FINS_TCP一级分组下,见下图。
Command DB块中,根据实际需求可增加发送语句的数量,仅需要更改commandByteData数组中Number_of_finCommands的值,该数据为常量,在PLC变量中修改。更改完成后在command结构变量中增加对应的发送指令,参考案列程序。
command结构变量中,data1为写入,data2为读取。
需要注意的是写入的data1变量中writeData,该结构变量目前支持整型int、浮点型real类型的数据,整型无需更改序列化后的字节顺序,浮点型数据需要转成DWORD类型数据,然后高低字交换,此点在写入wirteData缓存区时需要额外注意。可参考案例程序。
Tcp_FINS_config DB块是配置通讯参数的数据块,dev1为PLC1数据,可根据不同PLC配置不同参数。
LocalPLC为本地PLC地址,即1500PLC地址
ConnectionSettings为通讯参数
OmronNodeAddr为欧姆龙PLC的节点地址,与欧姆龙PLC的拨码需一致
EnableComm为通讯使能命令,true有效
ExcuteCommand为发送数据命令,上升沿有效
Diagnostics为通讯程序状态
4.程序实例
4.1 发送数据
案例中使用的是1秒触发一次发送,可根据需要设置条件触发。
"fins_sendDataSerialize" FC功能主要是用作序列化变量,把待发送数据转化成字节数组。参考案例填入相应引脚变量。
根据欧姆龙PLC的数据规则,浮点型数据需要提前转为DWORD类型,再把高低字交换后方可发送。
4.2 读取数据
案例中使用的是1秒触发一次读取,可根据需要设置条件触发。
"deserializeRevData" FC功能主要是用作反序列化字节数组,目前支持反序列化为整型INT和浮点型REAL的数据。参考案例填入相应引脚变量。
五.欧姆龙PLC编码
本例中欧姆龙PLC编程较为简单,只做了一个浮点型数据的自增,数据存储在D0~D1寄存器中。程序见下图。
六.软件配置
本例中欧姆龙PLC的仿真设置不是重点,故不做赘述,有兴趣的朋友可以自行研究如何通过虚拟串口,串口转TCP传输数据。具体配置截图见下面
七.仿真运行
以下两图为西门子1511PLC从欧姆龙CP1H的D0~D1寄存器地址读取浮点型数据。
由于截图有时间差,故两台PLC里的数据有些许偏差。
以下两图为西门子1511PLC写入数据到欧姆龙CP1H的D4~D7寄存器地址。
由于截图有时间差,故两台PLC里的数据有些许偏差