C#上位机与欧姆龙PLC的通信06---- HostLink协议(FINS版)

1、介绍

 对于上位机开发来说,欧姆龙PLC支持的主要的协议有Hostlink协议,FinsTcp/Udp协议,EtherNetIP协议,本项目使用Hostlink协议。 

Hostlink协议是欧姆龙PLC与上位机链接的公开协议。上位机通过发送Hostlink命令,可以对PLC进行I/O读写、可以对PLC进行I/O读写、改变操作模式、强制置位/复位等操作。由于是公开协议,即便是非欧姆龙的上位设备(软件),都可以通过该协议和欧姆龙PLC实现通信链接,

Hostlink通讯协议有两种模式:C-mode和FINS

上个文章采用C-mode方式,本篇采用FINS方式

1.Cmode:专用于hostlink通讯指令,采用的是ASCII码,适用于所有OMRON的PLC通讯。只能上位机发出指令给CPU,CPU无法主动发数据给上位机,只可以通过串口进行通讯

2.FINS:采用的二进制码,适用于新开发的PLC,可用在多种网络设备(Controller  Link,  Ethernet,  etc),可被 CPU、IO模块、上位机主动发出,不同的指令分别适用于不同的信息接受单元。有两种链接协议:CMND和hostlink,当上位机是做发送源时,必须采用hostlink协议,既可以通过串口通讯也可以通过各类网络通讯(适应性较强)。 

欧姆龙PLC与上位机连接时一般采用的是Hoslink协议,它是一种简易经济的通讯方式,比较适合一台上位机和一台PLC或者多台PLC进行通讯。上位机可对PLC进行程序传送和读写等操作。HOSTLINK系统允许一台上位机通过上位机链接命令向HOSTLINK系统的PLC发送命令,PLC处理来自上位机的每条指令,并把结果传回上位机。

2、欧姆龙Fins协议

欧姆龙FINS协议:现代工业自动化领域的通信利器,欧姆龙FINS协议,全称为”Factory Interface Network Service",是日本欧姆龙(Omron)公司开发的一套高效的工业自动化通信协议。它作为欧姆龙工业设备之间的通信接日,被广泛应用于全球范围内的工业自动化领域。

支持以太网的欧姆龙PLC CPU、以太网通信模块根据型号的不同,一般都会支持FINS(Factory Interface Network Service)协议,一些模块也会支持EtherNet/IP协议。Fins协议封装在TCP/UDP之上。

下图表述了FINS会话开始几个数据帧的作用。FINS协议的会话有一次请求帧,请求帧中附带着发起方的节点参数。PLC端(Server端)会确认并将自己的节点参数放回给请求方。

1、Fins协议和我们常用的ModbusTCP协议不同,首先体现在有握手验证命令,就是说在正常的三次握手的基础上,还需要进行一次握手,如果能正常握手,方可通信,这样做的目的也是为了PLC通信安全。

命令均为十六进制 字节数据流

 2、Fins握手命令

发送报文格式:

返回报文格式:

3、Fins通信命令

Fins通信协议的整体命令如下所示

4、Fins读取数据

Fins读取数据的报文会在通用命令的基础上,将 Parameter替换为 Area+Address+Length,因此读取数据命令如下所示:

读取数据返回命令如下所示:

5、Fins写入数据

Fins写入数据会在通用命令的基础上,将 Parameter替换为 Area+Address+Length+Value,因此写入数据命令如下所示:

写入数据返回命令如下所示:

 3、开搞Fins协议

1、确认环境

确认你的cx-simulator的串口设置已经设置好虚拟串口工具软件的com2

 2、运行网络调试工具NetAssist.exe

3、发送握手报文

首先要有握手验证命令,就是说在正常的三次握手的基础上,还需要进行一次握手,如果能正常握手,方可通信,这样做的目的也是为了PLC通信安全。

 发送:46 49 4E 53 00 00 00 0C 00 00 00 00 00 00 00 00 00 00 00 04
 接收:46 49 4E 53 00 00 00 10 00 00 00 01 00 00 00 00 00 00 00 04 00 00 00 0A

发送报文格式:

1)发送报文分析:

发送:46 49 4E 53 00 00 00 0C 00 00 00 00 00 00 00 00 00 00 00 04
接收:46 49 4E 53 00 00 00 10 00 00 00 01 00 00 00 00 00 00 00 04 00 00 00 0A

46494E53:转换成ASCII编码就是FINS;

0000000C:指后面跟的字节长度;12个字节,不包括自己的字节长度,也就是后面的 000000000000000000000004,它有12个字节

00000000:固定命令;

00000000:错误代码;

00000004:PC节点IP,当设置为0时,会自动获取节点IP

当前我的机器IP地址是:

格式中的clientnode就是指PC的IP地址中的最后一位,也就是4,转换成16进制就是4,它占4个字节,所以是 00000004,每2位算一个字节。其实这个地址写什么都可以,PLC并不会去校验客户端的IP地址,只是一个表示占位格式而已。

发送报文共占20个字节。

2)接收报文分析如下:

报文格式:

 发送:46 49 4E 53 00 00 00 0C 00 00 00 00 00 00 00 00 00 00 00 04
 接收:46 49 4E 53 00 00 00 10 00 00 00 01 00 00 00 00 00 00 00 04 00 00 00 0A

46494E53:ASCII编码就是FINS;

00000010:指后面跟的字节长度;16个字节,不包括自己的长度

00000001:固定命令;

00000000:错误代码;

00000004:本机电脑节点IP;

0000000A:PLC节点IP

servernode就是PLC的IP地址的最后一位,其实clientnode和servernode写什么都可以,也只是表示一个占位。

接收报文共24个字节,比发送多了servernode(4个字节)

4、读取和写入CIO区的2进制数据

  设置CIO0.0到0.5的6个数据,分别是111101

 1、读取指令,读取CIO区0.0开始的6个bool数据

发送:46 49 4E 53 00 00 00 1A 00 00 00 02 00 00 00 00 80 00 02 00 0A 00 00 04 00 00 01 01 30 00 00 00 00 06 
接收:46 49 4E 53 00 00 00 1C 00 00 00 02 00 00 00 00 C0 00 02 00 0A 00 00 04 00 00 01 01 00 00 01 01 01 01 00 01   

1)发送:46 49 4E 53 00 00 00 1A 00 00 00 02 00 00 00 00 80 00 02 00 0A 00 00 04 00 00 01 01 30 00 00 00 00 06 

发送报文格式

发送报文分析如下:

46 49 4E 53 00 00 00 1A 00 00 00 02 00 00 00 00 80 00 02 00 0A 00 00 04 00 00 01 01 30 00 00 00 00 06

46494E53:ASCII编码:FINS;

0000001A:指后面跟的字节长度;26个字节,不包括自己的长度

00000002:固定命令;

00000000:错误代码,00000000表示没有错误

80:ICF,固定值0x80;

00:RSV,固定值;

02:GCT,固定值;

00:PLC网络地址;

0A:PLC节点地址,PLC的IP地址最后一位

00:PLC单元地址;

00:PC网络地址;

04:PC节点地址,客户端IP地址最后一位

00:PC单元地址;

00:SID,固定值;

0101:读指令;

30:读地址区(D位:02,D字:82,W位:31,C位:30,W字:B1,C字:B0);

000000:起始地址,占3个字节

0006:读个数,占2个字节

--------------------------------------------------------------------------------------------------------------------------------

2)接收:46 49 4E 53 00 00 00 1C 00 00 00 02 00 00 00 00 C0 00 02 00 0A 00 00 04 00 00 01 01 00 00 01 01 01 01 00 01

接收报文格式

接收报文分析如下:

46 49 4E 53 00 00 00 1C 00 00 00 02 00 00 00 00 C0 00 02 00 0A 00 00 04 00 00 01 01 00 00 01 01 01 01 00 01

46494E53:ASCII编码:FINS;

0000001C:指后面跟的字节长度,1C转换成10进制就是28,就是指后面的字节长度是28个(56个字符,每2个字符为1个字节)

00000002:固定命令;

00000000:错误代码,全是0表示没有错误;

C0:ICF,固定值;

00:RSV,固定值;

02:GCT,固定值;

00:PLC网络地址;

0A:PLC节点地址;

00:PLC单元地址;

00:PC网络地址;

04:PC节点地址;

00:PC单元地址;

00:SID;

0101:读指令;

0000:读取成功标识;

01 01 01 01 00 01:读到的数据,这是2进制的数据,也就是C#中的bool类型,表示true,true,true,true,false,true,与内存存储区的数据一致。

2、写入指令,写入CIO区0.0开始的6个bool数据true, true, false, false, true,true

发送:46 49 4E 53 00 00 00 20 00 00 00 02 00 00 00 00 80 00 02 00 0A 00 00 04 00 00 01 02 30 00 00 00 00 06 01 01 00 00 01 01 
接收:46 49 4E 53 00 00 00 16 00 00 00 02 00 00 00 00 C0 00 02 00 0A 00 00 04 00 00 01 02 00 00

1)发送报文分析如下:

写入命令格式:

发送:46 49 4E 53 00 00 00 20 00 00 00 02 00 00 00 00 80 00 02 00 0A 00 00 04 00 00 01 02 30 00 00 00 00 06 01 01 00 00 01 01 

46494E53:ASCII编码:FINS;

00000020:指后面跟的字节长度,20转换成10进制就是32,表示后面有32个字节(64个字符);

00000002:固定命令;

00000000:错误代码,全0表示没有错误;

80:ICF,固定值;

00:RSV,固定值;

02:GCT,固定值;

00:PLC网络地址;

0A:PLC节点地址;

00:PLC单元地址;

00:PC网络地址;

04:PC节点地址;

00:PC单元地址;

00:SID;

0102:写指令;

30:写地址区(D位:02,D字:82,W位:31,C位:30,W字:B1,C字:B0);

000000:起始地址,即0.0开始的地址

0006:写入个数,占2个字节

01 01 00 00 01 01 :写入数据,具体来说表示true, true, false, false, true,true

2)接收报文分析如下:

返回命令如下

46 49 4E 53 00 00 00 16 00 00 00 02 00 00 00 00 C0 00 02 00 0A 00 00 04 00 00 01 02 00 00

46494E53:ASCII编码:FINS;

00000016:指后面跟的字节长度,表示后面的字节有22个字节

00000002:固定命令;

00000000:错误代码;

C0:ICF;

00:RSV;

02:GCT;

00:PLC网络地址;

0A:PLC节点地址;

00:PLC单元地址;

00:PC网络地址;

04:PC节点地址;

00:PC单元地址;

00:SID;

0102:写指令;

0000:写入成功标识,也就是说写入成功啦,没有错误。

以上读取或写入命令之前都必须先发送握手报文命令,而且只能发一次握手报文

5、读取和写入D区的ushort类型数据

首先设置内存区D区100的4个数据,注意D区设置的数据类型为10进制无符号的整数,对应C#中就是ushort类型。

1、读取D区100开始的4个数据

发送:46 49 4E 53 00 00 00 1A 00 00 00 02 00 00 00 00 80 00 02 00 0A 00 00 04 00 00 01 01 82 00 64 00 00 04
接收:46 49 4E 53 00 00 00 1E 00 00 00 02 00 00 00 00 C0 00 02 00 0A 00 00 04 00 00 01 01 00 00 00 7B 00 87 00 92 03 84

1)发送报文分析如下:

46 49 4E 53 00 00 00 1A 00 00 00 02 00 00 00 00 80 00 02 00 0A 00 00 04 00 00 01 01 82 00 64 00 00 04

46494E53:ASCII编码:FINS;

0000001A:指后面跟的字节长度;26个字节,不包括自己的长度

00000002:固定命令;

00000000:错误代码,表示没有错误

80:ICF;

00:RSV;

02:GCT;

00:PLC网络地址;

0A:PLC节点地址,PLC的IP地址最后一位

00:PLC单元地址;

00:PC网络地址;

04:PC节点地址,客户端IP地址最后一位

00:PC单元地址;

00:SID;

0101:读指令;

82:读地址区(D位:02,D字:82,W位:31,C位:30,W字:B1,C字:B0);

006400:起始地址,100转成16进制就是64,占3个字节,就是006400

0004:读取的个数,占2个字节

2)接收报文分析如下:

46 49 4E 53 00 00 00 1E 00 00 00 02 00 00 00 00 C0 00 02 00 0A 00 00 04 00 00 01 01 00 00 00 7B 00 87 00 92 03 84

46494E53:ASCII编码:FINS;

0000001E:指后面跟的字节度 

00000002:固定命令;

00000000:错误代码,全是0表示没有错误;

C0:ICF,固定值;

00:RSV,固定值;

02:GCT,固定值;

00:PLC网络地址;

0A:PLC节点地址;

00:PLC单元地址;

00:PC网络地址;

04:PC节点地址;

00:PC单元地址;

00:SID;

0101:读指令;

0000:读取成功标识;

00 7B 00 87 00 92 03 84:读到的数据,00 7B转换成10进制就是12300 87就是135,00 92就是146,03 84就是900

这里注意10进制的无符号整数占2个字节,也就是PLC中的一个寄存器,PLC中的word,占一个寄存器,在C#占2个字节,用来表示整数(不用带小数)

2、向D区30的地址写入4个ushort数据110, 120, 130, 140

发送:46 49 4E 53 00 00 00 22 00 00 00 02 00 00 00 00 80 00 02 00 0A 00 00 04 00 00 01 02 82 00 1E 00 00 04 00 6E 00 78 00 82 00 8C 
接收:46 49 4E 53 00 00 00 16 00 00 00 02 00 00 00 00 C0 00 02 00 0A 00 00 04 00 00 01 02 00 00

写入成功

发送报文分析

46 49 4E 53 00 00 00 22 00 00 00 02 00 00 00 00 80 00 02 00 0A 00 00 04 00 00 01 02 82 00 1E 00 00 04 00 6E 00 78 00 82 00 8C 

46494E53:ASCII编码:FINS;

00000022:指后面跟的字节长度 ;

00000002:固定命令;

00000000:错误代码,全0表示没有错误;

80:ICF,固定值;

00:RSV,固定值;

02:GCT,固定值;

00:PLC网络地址;

0A:PLC节点地址;

00:PLC单元地址;

00:PC网络地址;

04:PC节点地址;

00:PC单元地址;

00:SID;

0102:写指令;

82:写地址区(D位:02,D字:82,W位:31,C位:30,W字:B1,C字:B0);

001E00:起始地址,即0.0开始的地址

0004:写入个数,占2个字节

00 6E 00 78 00 82 00 8C:写入数据,具体来说表示00 6E=》110, 00 78=》120, 00 82=》130, 00 8C=》140


接收报文分析

46 49 4E 53 00 00 00 16 00 00 00 02 00 00 00 00 C0 00 02 00 0A 00 00 04 00 00 01 02 00 00

46494E53:ASCII编码:FINS;

00000016:指后面跟的字节长度,表示后面的字节有22个字节

00000002:固定命令;

00000000:错误代码;

C0:ICF;

00:RSV;

02:GCT;

00:PLC网络地址;

0A:PLC节点地址;

00:PLC单元地址;

00:PC网络地址;

04:PC节点地址;

00:PC单元地址;

00:SID;

0102:写指令;

0000:写入成功标识,也就是说写入成功啦,没有错误。

以上读取或写入命令之前都必须先发送握手报文命令,而且只能发一次握手报文

6、读取和写入H区的short类型数据

 设置H区的4个数据

1、读取H区100开始的4个short类型的数据

发送:46 49 4E 53 00 00 00 1A 00 00 00 02 00 00 00 00 80 00 02 00 0A 00 00 04 00 00 01 01 B2 00 64 00 00 04
接收:46 49 4E 53 00 00 00 1E 00 00 00 02 00 00 00 00 C0 00 02 00 0A 00 00 04 00 00 01 01 00 00 00 6E 00 6F FF 90 FF 8F 

1)发送报文分析如下:

46 49 4E 53 00 00 00 1A 00 00 00 02 00 00 00 00 80 00 02 00 0A 00 00 04 00 00 01 01 B2 00 64 00 00 04

46494E53:ASCII编码:FINS;

0000001A:指后面跟的字节长度;26个字节,不包括自己的长度

00000002:固定命令;

00000000:错误代码,表示没有错误

80:ICF;

00:RSV;

02:GCT;

00:PLC网络地址;

0A:PLC节点地址,PLC的IP地址最后一位

00:PLC单元地址;

00:PC网络地址;

04:PC节点地址,客户端IP地址最后一位

00:PC单元地址;

00:SID;

0101:读指令;

B2:读地址区(D位:02,D字:82,W位:31,C位:30,W字:B1,C字:B0,H字:B2);

006400:起始地址,100转成16进制就是64,占3个字节,就是006400

0004:读取的个数,占2个字节

2)接收报文分析如下:

46 49 4E 53 00 00 00 1E 00 00 00 02 00 00 00 00 C0 00 02 00 0A 00 00 04 00 00 01 01 00 00 00 6E 00 6F FF 90 FF 8F

46494E53:ASCII编码:FINS;

0000001E:指后面跟的字节度 

00000002:固定命令;

00000000:错误代码,全是0表示没有错误;

C0:ICF,固定值;

00:RSV,固定值;

02:GCT,固定值;

00:PLC网络地址;

0A:PLC节点地址;

00:PLC单元地址;

00:PC网络地址;

04:PC节点地址;

00:PC单元地址;

00:SID;

0101:读指令;

0000:读取成功标识;

00 6E 00 6F FF 90 FF 8F:读到的数据,00 6E转换成10进制就是110。00 6F就是111,FF 90就是65424,FF 8F就是65423,这里要将65424-65536=-112,同样65423-65536=-113,short的表示范围是 -32,768 到 32,767,表示有符号 16 位整数,ushort:代表有符号的16位整数,范围从0 到 65,535,这就也说明了,我们需要对返回的数据进行有效的处理,这个留着在后面的通讯库封装代码中去处理。

 

 2、向H区30的地址写入4个short数据,分别是-98,654,-800,327

发送:46 49 4E 53 00 00 00 22 00 00 00 02 00 00 00 00 80 00 02 00 0A 00 00 04 00 00 01 02 B2 00 1E 00 00 04 FF 9E 02 8E FC E0 01 47 
接收:46 49 4E 53 00 00 00 16 00 00 00 02 00 00 00 00 C0 00 02 00 0A 00 00 04 00 00 01 02 00 00

发送报文分析

46 49 4E 53 00 00 00 22 00 00 00 02 00 00 00 00 80 00 02 00 0A 00 00 04 00 00 01 02 B2 00 1E 00 00 04 FF 9E 02 8E FC E0 01 47  

46494E53:ASCII编码:FINS;

00000022:指后面跟的字节长度 ;

00000002:固定命令;

00000000:错误代码,全0表示没有错误;

80:ICF,固定值;

00:RSV,固定值;

02:GCT,固定值;

00:PLC网络地址;

0A:PLC节点地址;

00:PLC单元地址;

00:PC网络地址;

04:PC节点地址;

00:PC单元地址;

00:SID;

0102:写指令;

82:写地址区(D位:02,D字:82,W位:31,C位:30,W字:B1,C字:B0);

001E00:起始地址,即0.0开始的地址

0004:写入个数,占2个字节

FF 9E 02 8E FC E0 01 47:写入数据,具体来说表示FF 9E=》-98, 02 8E=》654,FC E0 =》-800,01 47=》327

同样的可以看到写入的负数,前面的第一个是F,这是因为负数用补码表示。


接收报文分析

46 49 4E 53 00 00 00 16 00 00 00 02 00 00 00 00 C0 00 02 00 0A 00 00 04 00 00 01 02 00 00

46494E53:ASCII编码:FINS;

00000016:指后面跟的字节长度,表示后面的字节有22个字节

00000002:固定命令;

00000000:错误代码;

C0:ICF;

00:RSV;

02:GCT;

00:PLC网络地址;

0A:PLC节点地址;

00:PLC单元地址;

00:PC网络地址;

04:PC节点地址;

00:PC单元地址;

00:SID;

0102:写指令;

0000:写入成功标识,也就是说写入成功啦,没有错误。

以上读取或写入命令之前都必须先发送握手报文命令,而且只能发一次握手报文

7、读取和写入W区的float类型数据

float类型的数据是包括正负整数和正负小数,如40,-98,2.34,-89.53

设置W区的5个数据

1、读取W区100开始的5个float数据

发送:46 49 4E 53 00 00 00 1A 00 00 00 02 00 00 00 00 80 00 02 00 0A 00 00 04 00 00 01 01 B1 00 64 00 00 0A
接收:46 49 4E 53 00 00 00 2A 00 00 00 02 00 00 00 00 C0 00 02 00 0A 00 00 04 00 00 01 01 00 00 47 AE 3F 81 8F 5C BF 82 00 00 42 F6 00 00 C4 75 C0 00 44 02

1)发送报文分析如下:
46 49 4E 53 00 00 00 1A 00 00 00 02 00 00 00 00 80 00 02 00 0A 00 00 04 00 00 01 01 B1 00 64 00 00 0A
46494E53:ASCII编码:FINS;
0000001A:指后面跟的字节长度;26个字节,不包括自己的长度
00000002:固定命令;
00000000:错误代码,表示没有错误
80:ICF;
00:RSV;
02:GCT;
00:PLC网络地址;
0A:PLC节点地址,PLC的IP地址最后一位
00:PLC单元地址;
00:PC网络地址;
04:PC节点地址,客户端IP地址最后一位
00:PC单元地址;
00:SID;
0101:读指令;
B1:读地址区(D位:02,D字:82,W位:31,C位:30,W字:B1,C字:B0,H字:B2);
006400:起始地址,100转成16进制就是64,占3个字节,就是006400
000A:读取的个数,占2个字节,这里为什么是A,即10个,因为一个float类型是占2个寄存器的,那么5个float就是10个寄存器,所以是A,需要注意这个不同的地方。

2)接收报文分析如下:
46 49 4E 53 00 00 00 2A 00 00 00 02 00 00 00 00 C0 00 02 00 0A 00 00 04 00 00 01 01 00 00 47 AE 3F 81 8F 5C BF 82 00 00 42 F6 00 00 C4 75 C0 00 44 02
46494E53:ASCII编码:FINS;
0000001E:指后面跟的字节度 
00000002:固定命令;
00000000:错误代码,全是0表示没有错误;
C0:ICF,固定值;
00:RSV,固定值;
02:GCT,固定值;
00:PLC网络地址;
0A:PLC节点地址;
00:PLC单元地址;
00:PC网络地址;
04:PC节点地址;
00:PC单元地址;
00:SID;
0101:读指令;
0000:读取成功标识;
47 AE 3F 81 8F 5C BF 82 00 00 42 F6 00 00 C4 75 C0 00 44 02:读到的数据,47 AE 3F 81是第一个数据, 8F 5C BF 82是第二个数据,00 00 42 F6是第三个数据,00 00 C4 75是第四个数据,C0 00 44 02是第五个数据,这里为什么是这样的数据,如果转成10进制都不是当初设置的1.01,-1.02,123,-980,523,这是因为存在大小端,字节序的问题,这需要在程序后端进行处理,这里返回的数据是没有问题的,等后面在我的封装通讯库的进行处理,保证响当当的没有问题。

2、向W区30的地址写入5个数据120, -130, -140,15.6f,-89.4f

发送:46 49 4E 53 00 00 00 2E 00 00 00 02 00 00 00 00 80 00 02 00 0A 00 00 04 00 00 01 02 B1 00 1E 00 00 0A 00 00 42 F0 00 00 C3 02 00 00 C3 0C 99 9A 41 79 CC CD C2 B2
接收:46 49 4E 53 00 00 00 16 00 00 00 02 00 00 00 00 C0 00 02 00 0A 00 00 04 00 00 01 02 00 00

发送报文分析
46 49 4E 53 00 00 00 2E 00 00 00 02 00 00 00 00 80 00 02 00 0A 00 00 04 00 00 01 02 B1 00 1E 00 00 0A 00 00 42 F0 00 00 C3 02 00 00 C3 0C 99 9A 41 79 CC CD C2 B2  

46494E53:ASCII编码:FINS;
0000002E:指后面跟的字节长度 ;
00000002:固定命令;
00000000:错误代码,全0表示没有错误;
80:ICF,固定值;
00:RSV,固定值;
02:GCT,固定值;
00:PLC网络地址;
0A:PLC节点地址;
00:PLC单元地址;
00:PC网络地址;
04:PC节点地址;
00:PC单元地址;
00:SID;
0102:写指令;
B1:写地址区(D位:02,D字:82,W位:31,C位:30,W字:B1,C字:B0);
001E00:起始地址, 
000A:写入个数,占2个字节,要写入5个float的,每个float占2个寄存器,5个就是10个寄存器,所以是A;
00 00 42 F0 00 00 C3 02 00 00 C3 0C 99 9A 41 79 CC CD C2 B2:写入数据,具体来说00 00 42 F0是第一个, 00 00 C3 02是第二个, 00 00 C3 0C是第三个, 99 9A 41 79是第四个, CC CD C2 B2是第五个。但这5个数据都不是120, -130, -140,15.6f,-89.4f转换成16进制的表示,这也是因为存在大小端,字节序的问题,在后面的通讯库封装中来处理,发送的报文指令绝对没有错。
 

接收报文分析
46 49 4E 53 00 00 00 16 00 00 00 02 00 00 00 00 C0 00 02 00 0A 00 00 04 00 00 01 02 00 00

ASCII编码:FINS;
00000016:指后面跟的字节长度,表示后面的字节有22个字节
00000002:固定命令;
00000000:错误代码;
C0:ICF;
00:RSV;
02:GCT;
00:PLC网络地址;
0A:PLC节点地址;
00:PLC单元地址;
00:PC网络地址;
04:PC节点地址;
00:PC单元地址;
00:SID;
0102:写指令;
0000:写入成功标识,也就是说写入成功啦,没有错误。
以上读取或写入命令之前都必须先发送握手报文命令,而且只能发一次握手报文

4、小结

这节,我们读取和写入了CIO区,D区,H区,W区的二进制数据,ushort数据,short数据,float数据,充分熟悉了fins指令的格式要求,都有固定的格式。

  FINS协议是一种基于TCP/IP网络通信的实时通信协议.能够实现欧姆龙工业设备之间的数据交换和控制指令传输。它采用了客户端/服务器模型,客户端发送请求,服务器返回响应,通过建立连接、传输数据包来实现设备之间的通信。
  FINS协议的核心是消息和指令的传输。消息格式包括消息头、命令和数据区。消息头定义了消息的类型、长度和地址等信息。命令部分包含了具体的指令内容,如读取数据、写入数据或执行其他操作。数据区则是存储实际的数据信息。

注意几点:

1)读取命令0101,写入命令0102,固定的,不能改

2)存储区代号:(D位:02,D字:82,W位:31,C位:30,W字:B1,C字:B0,H字:B2),固定的不能改

3)协议头部:46 49 4E 53,转换成ascii码就是fins

码字不易,截图不易,写作不易,共享不易,请多多点赞支持。



 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/228035.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

计算机组成原理复习7

内存管理 文章目录 内存管理存储器概述存储器的分类按在计算机中的作用(层次)分类按存储介质分类按存取方式分类按信息的可保存性分类 存储器的性能指标存储容量单位成本存储速度:数据传输率数据的宽度/存储周期 存储器的层次化结构多级存储系…

Java注解学习,一文掌握@Autowired 和 @Resource 注解区别

🏆作者简介,普修罗双战士,一直追求不断学习和成长,在技术的道路上持续探索和实践。 🏆多年互联网行业从业经验,历任核心研发工程师,项目技术负责人。 🎉欢迎 👍点赞✍评论…

Unity坦克大战开发全流程——开始场景——开始界面

开始场景——开始界面 step1:设置UI 反正按照这张图拼就行了 step2:写脚本 前面的拼UI都是些比较机械化的工作,直到这里写代码的时候才真正开始有点意思了,从这里开始,我们就要利用面向对象的思路来进行分析&#xff1…

【量化】蜘蛛网策略复现

文章目录 蜘蛛网策略研报概述持仓数据整理三大商品交易所的数据统一筛选共有会员清洗数据计算研报要求数据全部代码 策略结果分析无参数策略有参数策略正做反做 MSD技术指标化 蜘蛛网策略 策略来自《东方证券-股指期货趋势交易之蜘蛛网策略——从成交持仓表中捕捉知情投资者行为…

从实际工作情况,介绍嵌入式(MCU)软件开发常用(通用)工具

目录 前言 1、代码阅读及编辑工具(VSCode、Understand) 2、代码对比工具(Beyond Compare) 3、代码仓库相关工具(Git、SVN、Tortoise) 4、文本编辑器(Notepad) 5、电脑文件搜索工…

Springcloud Alibaba使用Canal将Mysql数据实时同步到Redis保证缓存的一致性

目录 1. 背景 2. Windows系统安装canal 3.Mysql准备工作 4. 公共依赖包 5. Redis缓存设计 6. mall-canal-service 1. 背景 canal [kənl] ,译意为水道/管道/沟渠,主要用途是基于 MySQL 数据库增量日志解析,提供增量数据订阅和消费。其诞…

【深度解析C++】const成员函数

系列文章目录 🌈座右铭🌈:人的一生这么长、你凭什么用短短的几年去衡量自己的一生! 💕个人主页:清灵白羽 漾情天殇_计算机底层原理,深度解析C,自顶向下看Java-CSDN博客 ❤️相关文章❤️:Cthis指针&#xf…

PostgreSQL | FunctionProcedure | 函数与存储过程的区别

文章目录 PostgreSQL | Function&Procedure | 函数与存储过程的区别1. 简述书面说法大白话讲 2. 函数(Function)2.1 定义2.2 用途2.3 执行2.4 事务处理2.5 说点例子1. 当参数都是IN类时2. 参数中出现OUT、INOUT参数时 3. 存储过程(Proced…

C语言之整型提升

文章目录 1 有可能出现的问题2 产生以上问题的原因&#xff08;整型提升&#xff09;3 整型提升的过程4 整型提升示例5 总结 1 有可能出现的问题 代码如下 #include <stdio.h>int main () {int a -1;unsigned int b 1;if (a < b) {printf("a < b");}…

【STM32】SPI通信

1 SPI通信 SPI&#xff08;Serial Peripheral Interface&#xff0c;串行外设接口&#xff09;是由Motorola公司开发的一种通用数据总线 四根通信线&#xff1a;SCK&#xff08;Serial Clock&#xff0c;串行时钟&#xff09;、MOSI&#xff08;Master Output Slave Input&am…

使用react+vite开发项目时候,部署上线后刷新页面无法访问解决办法

说一下我这边的环境和使用的路由模式&#xff1a;vitereactBrowserRouter路由模式&#xff0c;所以如果你和我一样的话&#xff0c;可以试试我的这种解决办法&#xff0c;我是将项目打包后直接丢到服务器上的目录里面&#xff0c;然后配置nginx直接访问根目录。 我的nginx配置…

React快速入门之交互性

响应事件 创建事件处理函数 处理函数名常以handle事件名命名 function handlePlayClick() {alert(Playing);}传递事件处理函数 函数名、匿名两种方式&#xff01; function PlayButton() {function handlePlayClick() {alert(Playing);}return (<Button handleClick{handl…

java虚拟机内存管理

文章目录 概要一、jdk7与jdk8内存结构的差异二、程序计数器三、虚拟机栈3.1 什么是虚拟机栈3.2 什么是栈帧3.3 栈帧的组成 四、本地方法栈五、堆5.1 堆的特点5.2 堆的结构5.3 堆的参数配置 六、方法区6.1 方法区结构6.2 运行时常量池 七、元空间 概要 根据 JVM 规范&#xff0…

探索小红书笔记API:挖掘数据背后的故事

随着数字化时代的到来&#xff0c;数据已经成为企业和个人决策的重要依据。小红书作为一个流行的社交电商平台&#xff0c;积累了大量的用户数据和内容。通过探索小红书笔记API&#xff0c;我们可以深入挖掘这些数据背后的故事&#xff0c;从而更好地理解用户需求和市场趋势。 …

弱电工程计算机网络系统基础知识

我们周围无时无刻不存在一张网&#xff0c;如电话网、电报网、电视网、计算机网络等&#xff1b;即使我们身体内部也存在许许多多的网络系统&#xff0c;如神经系统、消化系统等。最为典型的代表即计算机网络&#xff0c;它是计算机技术与通信技术两个领域的结合。 计算机网络的…

《Spring Cloud学习笔记:微服务保护Sentinel + JMeter快速入门》

Review 解决了服务拆分之后的服务治理问题&#xff1a;Nacos解决了服务治理问题OpenFeign解决了服务之间的远程调用问题网关与前端进行交互&#xff0c;基于网关的过滤器解决了登录校验的问题 流量控制&#xff1a;避免因为突发流量而导致的服务宕机。 隔离和降级&#xff1a…

八股文打卡day12——计算机网络(12)

面试题&#xff1a;HTTPS的工作原理&#xff1f;HTTPS是怎么建立连接的&#xff1f; 我的回答&#xff1a; 1.客户端向服务器发起请求&#xff0c;请求建立连接。 2.服务器收到请求之后&#xff0c;向客户端发送其SSL证书&#xff0c;这个证书包含服务器的公钥和一些其他信息…

LVS那点事

LVS 原理 IPVS LVS 的 IP 负载均衡技术是通过 IPVS 模块来实现的&#xff0c;IPVS 是 LVS 集群系统的核心软件&#xff0c;它的主要作用是&#xff1a;安装在 Director Server 上&#xff0c;同时在 Director Server 上虚拟出一个 IP 地址&#xff0c;用户必须通过这个虚拟的…

k8s的二进制部署: 源码包部署-----node节点部署

服务器IP软件包k8s--master0120.0.0.61kube-aplserver&#xff0c;kube-controer-manager&#xff0c;kube-scheduler&#xff0c;etcdk8s--master0220.0.0.62kube-controer-manager&#xff0c;kube-schedulernode节点0120.0.0.62kubelet&#xff0c;kube-proxy&#xff0c;et…

初识javaWeb

一、JavaWeb是什么&#xff1f; 1、概念 javaWeb指的是使用java语言进行互联网领域项目开发的技术栈——进行web项目开发所需的技术的集合。 -Web前端——在浏览器中用户可以看到的网页 -Web后端——为前端提供数据的程序 2、Web项目 java语言是可以进行多种类型的项目开发&a…