终于有人把欧姆龙PLC通信协议说清楚了
西门子、三菱、欧姆龙是我们自动化行业使用最多的三个PLC品牌。今天分享一下欧姆龙PLC的FinsTCP通信协议。
大家在学习FinsTCP通信协议时,建议先掌握ModbusTCP或三菱MC通信协议。
Fins通信协议是欧姆龙PLC专用协议,主要用于控制欧姆龙系列PLC,它是一个公开的协议,可以通过欧姆龙官方下载到协议文档。
一、握手协议
FinsTCP通信协议,与ModbusTCP和MC协议有一个不同地方在于,当我们完成TCP连接后,不能直接进行读取或写入,需要有一个握手过程,以保证通信安全。
这点与西门子S7协议类似,S7协议会有两次握手验证,FinsTCP只需要一次即可。
握手命令如下所示:
发送报文格式:

接收报文格式:

我们使用TCP助手测试一下:本机IP地址是192.168.2.77,PLC的IP地址是192.168.2.164,因此发送报文为:
46 49 4E 53 00 00 00 0C 00 00 00 00 00 00 00 00 00 00 00 4D

返回报文为:
46 49 4E 53 00 00 00 10 00 00 00 01 00 00 00 00 00 00 00 4D 00 00 00 A4
其中0x4D=77,对应ClientNode,PC的IP最后一位。
0xA4=164,对应ServerNode,PLC的IP最后一位。
二、Fins通用格式
我们学习通信,一般都会有个通用格式。
所谓通用格式,就是无论发送、接收的报文都会按照这个格式来,会将变化的部分封装成一个整体,一般叫做数据部分或者Parameter。
Fins通用报文格式如下:

三、读取协议帧
FinsTCP通信协议读取数据的请求帧报文是在通用格式的基础上,将 Parameter部分替换为 Area+Address+Length。读取请求帧格式如下所示:

响应帧报文是在通用格式的基础上,将 Parameter部分替换为 ErrorCode+Value。读取响应帧格式如下所示:


四、写入协议帧
FinsTCP通信协议写入数据的请求帧报文是在通用格式的基础上,将 Parameter部分替换为 Area+Address+Length+Value。写入请求帧格式如下所示:


响应帧报文是在通用格式的基础上,将 Parameter部分替换为 ErrorCode。写入响应帧报文如下所示:

五、通信测试
我们以读取D0开始的5个寄存器为例,结合协议文档,来进行报文拼接。
发送报文如下:
Header:0x46 0x49 0x4E 0x53
Length:0x00 0x00 0x00 0x1A
Command:0x00 0x00 0x00 0x02
ErrorCode:0x00 0x00 0x00 0x00
ICF:0x80
RSV:0x00
GCT:0x02
DNA:0x00
DA1:0xA4
DA2:0x00
SNA:0x00
SA1:0x4D
SA2:0x00
SID:0x00
MRC:0x01
SRC:0x01
Area:0x82
Address:0x00 0x00 0x00
Length:0x00 0x05
我们通过网络调试助手发送这个报文,观察一下返回的报文:

响应报文如下:
我们只需要关注最后的ErrorCode和Value即可。
ErrorCode:0x00 0x00
Value:0x00 0x0A 0x00 0x14 0x00 0x1E 0x00 0x28 0x00 0x32
其中0x00 0x0A 0x00 0x14 0x00 0x1E 0x00 0x28 0x00 0x32即表示D0-D4的值,进行数据解析处理后的值分别为10、20、30、40、50,与PLC数据一致。

六、代码实现
我们也可以编写C#程序来实现整个过程。
这里测试为主,代码相对简单,实际应用时可进一步封装,代码如下:
static void Main(string[] args)
{
// 连接
Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
socket.Connect("192.168.2.164", 9600);
//握手
byte[] handsend = new byte[] { 0x46, 0x49, 0x4E, 0x53,
0x00, 0x00, 0x00, 0x0C,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x4D };
socket.Send(handsend);
byte[] handrcv = new byte[1024];
int count = socket.Receive(handrcv);
//简单验证握手正确
if (count == 24 && handrcv[12] == 0x00 && handrcv[13] == 0x00 && handrcv[14] == 0x00 && handrcv[15] == 0x00)
{
//读取D0开始的5个字
byte[] readsend = new byte[] { 0x46, 0x49, 0x4E, 0x53,
0x00, 0x00, 0x00, 0x1A, 0x00, 0x00, 0x00, 0x02, 0x00,
0x00, 0x00, 0x00, 0x80, 0x00, 0x02, 0x00, 0xA4, 0x00,
0x00, 0x4D, 0x00, 0x00,0x01,0x01,0x82,0x00,0x00,
0x00,0x00,0x05};
socket.Send(readsend);
byte[] readrcv = new byte[1024];
int rcvCount = socket.Receive(readrcv);
if (rcvCount == 40)
{
for (int i = 30; i < rcvCount; i += 2)
{
// 每2个字节作为一个数据
byte[] dataBytes = new byte[2];
dataBytes[0] = readrcv[i + 1];
dataBytes[1] = readrcv[i];
Console.WriteLine(BitConverter.ToInt16(dataBytes, 0));
}
}
}
Console.ReadLine();
}
输出结果如下:

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐



所有评论(0)