3. PLC通信协议解析:西门子S7、三菱MC、欧姆龙FINS

各位同学,今天我们来聊聊PLC通信协议。说实话,刚入行那会儿,我面对这些协议也是一头雾水。西门子、三菱、欧姆龙,每家都有自己的“方言”。但搞自动化,不懂协议怎么行?

这一章,我会把三种主流协议掰开揉碎了讲。还会带你们用Python库实际跑一跑。嗯,都是实战经验,你们拿笔记好。

3.1 西门子S7通信协议

S7协议是西门子的看家本领。它用在S7-200、300、400、1200、1500全系列上。说白了,就是西门子PLC的“官方语言”。

协议特点:

  • 基于ISO/OSI模型,走TCP/IP或MPI/Profibus
  • 端口号:102(没错,就是Telnet那个端口)
  • 支持PG/OP通信、S7通信、S5兼容通信

我记得有一次调试S7-1200,死活连不上。查了半天,发现是PLC的“允许远程PUT/GET”没勾上。嗯,这个坑我替你们踩过了。

注意:S7-1200/1500默认禁止外部读写。必须先在组态里勾选“允许远程通信”。不然你代码写得再好也白搭。

3.2 三菱MC协议

三菱的MC协议,全称MELSEC Communication Protocol。它分两种:A系列用的旧版,和Q/L/FX系列用的新版。我建议你们直接学新版,因为老设备越来越少了。

协议特点:

  • 支持串口(RS-232/422/485)和以太网
  • 以太网端口号:5000(默认)
  • 报文格式:帧头+命令+数据+校验

三菱的报文结构很有意思。它用ASCII码还是二进制,取决于你选“A”还是“B”格式。我个人习惯用二进制,效率高,解析也简单。

核心要点:MC协议的报文长度是固定的。读寄存器时,一次最多读960个字。超过这个数,你得拆包。

3.3 欧姆龙FINS协议

FINS是欧姆龙的招牌协议。全称Factory Interface Network Service。它支持CJ、CS、NJ、NX全系列。你想想看,一个协议能通吃所有系列,这设计思路就很棒。

协议特点:

  • 基于UDP或TCP,端口号:9600
  • 报文结构:ICF+RSV+GCT+DNA+DA1+DA2+SNA+SA1+SA2+SID+命令+数据
  • 支持广播通信

我曾经在一条产线上同时用FINS控制8台欧姆龙PLC。广播指令一发,所有设备同时响应。那感觉,确实爽。

小技巧:FINS的SID字段可以当“消息ID”用。多线程通信时,用SID区分不同请求,能避免数据错乱。

3.4 Python库初步使用

理论讲完了,咱们来点实际的。Python有几个好用的库,能直接跟PLC通信。

3.4.1 python-snap7(西门子)

这个库是专门给西门子S7系列用的。安装很简单:

pip install python-snap7

来个最简单的读数据例子:

import snap7

# 连接PLC
plc = snap7.client.Client()
plc.connect('192.168.0.1', 0, 1)  # IP, 机架号, 槽号

# 读取DB1.DBW0(一个字)
data = plc.db_read(1, 0, 2)  # DB号, 起始地址, 长度
value = snap7.util.get_int(data, 0)
print(f"DB1.DBW0的值是: {value}")

# 别忘了断开
plc.disconnect()

这里要注意:snap7的地址是从0开始的。DB1.DBW0对应起始地址0,长度2字节。我刚开始用的时候,老是把地址搞错一位。

3.4.2 三菱MC协议库

三菱没有官方Python库。但有个叫pymcprotocol的开源库,挺好用:

pip install pymcprotocol

读寄存器的例子:

from pymcprotocol import Type3E

# 创建连接
mc = Type3E()
mc.connect("192.168.0.10", 5000)

# 读取D100开始的10个字
data = mc.batchread("D", 100, 10)
print(f"D100~D109的值: {data}")

# 写单个位
mc.set_bit("M0", 1)  # 把M0置1

mc.close()
注意:pymcprotocol默认用二进制格式。如果你PLC设的是ASCII格式,记得加参数format=1

3.4.3 欧姆龙FINS库

欧姆龙有pyfins库,不过功能有限。我推荐用omron-fins

pip install omron-fins

读数据示例:

from omron_fins import FinsConnection

# 连接PLC
conn = FinsConnection()
conn.connect('192.168.0.100', 9600)

# 读取D100(一个字)
value = conn.read_word('D100')
print(f"D100的值: {value}")

# 写数据
conn.write_word('D200', 1234)

conn.close()

FINS的地址写法很直观。D区就是D100,W区就是W0。不用记偏移量,这点比西门子友好。

3.5 协议对比与选型建议

特性 西门子S7 三菱MC 欧姆龙FINS
端口号 102 5000 9600
传输层 TCP TCP/UDP TCP/UDP
最大数据包 240字节 960字 1980字节
Python库 python-snap7 pymcprotocol omron-fins
学习难度 中等 简单 简单

选哪个协议?我个人建议:

  • 如果你用西门子,没得选,就是S7
  • 三菱和欧姆龙,看现场设备。混用也没问题,反正Python都能搞定
  • 新手建议从三菱MC入手,报文结构最清晰
我的经验:实际项目中,我经常同时用两三种协议。一台工控机,同时连西门子、三菱、欧姆龙。Python的多线程一开,各跑各的,互不干扰。

好了,这一章的内容就到这里。协议这东西,光看没用,得动手试。你们回去把三个库都装一下,连上自己的PLC跑一跑。遇到问题,翻翻报错信息,八成能解决。

下一章,我们讲OPC UA。那玩意儿比这些协议更高级,能跨平台、跨厂家。到时候你们就知道,什么叫“一统江湖”了。