python实现MC协议(SLMP 3E帧)的TCP服务端是一件稍微麻烦点的事情。它不像modbusTCP那样,可以使用现成的pymodbus模块去实现。但是,我们可以根据协议帧进行组包,自己去实现帧的格式,而这一切可以基于socket模块。本文为第一篇。
参考文档:三菱PLC之SLMP协议报文说明 - 知乎 (zhihu.com)
查阅三菱PLC官方文档,发现SLMP协议的3E帧,其实就是MC协议的3E帧,因此可通用。
查阅三菱PLC官方文档,发现3E/4E帧报文格式如下图所示
SLMP(Seamless Message Protocol)的3E帧和4E帧是两种不同的帧格式,用于在三菱PLC(Programmable Logic Controller)和外部设备之间进行通信。它们的主要区别在于帧头和帧体的格式。
(1)3E帧格式:
SLMP的3E帧格式由三个部分组成:帧头、命令数据和CRC校验。
帧头(Header):3个字节,包括起始字节(STX,0x02)和两个字节的长度信息(高字节在前)。
命令数据(Command Data):包含命令码和命令参数等信息。
CRC校验(Cyclic Redundancy Check):2个字节,用于数据完整性检查。
3E帧的格式相对简单,适用于一些基本的通信需求
(2)4E帧格式:
4E帧格式更加复杂,可以包含更多的信息,并支持更多的功能。它包含以下几个部分:帧头、信息头、数据区和CRC校验。
帧头(Header):1个字节,包括起始字节(0x80)。
信息头(Information Header):4个字节,包括命令码、子命令码和信息长度等。
数据区(Data Area):包含具体的命令数据,根据命令的不同而变化。
CRC校验(Cyclic Redundancy Check):2个字节,用于数据完整性检查。
4E帧的格式相对灵活,可以用于更复杂的通信场景,支持更多的命令和参数。
SLMP 3E帧:50 00 00 FF FF 03 00 0C 00 10 00 01 04 00 00 00 00 00 A8 05 00
(1)帧头(Header):不显示,因为是TCP/IP及UDP/IP用的帧头。帧头在外部设备侧进行添加及发送。此外,通常根据外部设备自动被添加。
(2)副帧头(Sub-Header):50 00
,固定值,占用4字节,没什么好说的。
(3)请求目标网络编号:00
,占用2字节,表示请求的目标网络编号。
(4)请求目标站号:FF
,占用2字节,表示请求的目标站号。
(5)请求目标模块T/0编号:FF 03,占用4字节,表示请求的目标模块T/0编号。
(6)请求目标多点站号:00
,占用2字节,表示请求的目标多点站号。
(7)请求数据长:0C 00
,占用4字节,表示请求数据的长度(16字节,即后续的数据部分的长度)。
(8)监视定时器:10 00
,占用4字节,表示监视定时器的值。
(9)请求数据:01 04 00 00 00 00 00 A8 05 00,这20个字节表示具体的请求数据,但没有数据本身。
01 04:命令码,占用4字节,表示读取请求。
00 00
:子命令码,占用4字节(通常为0)。
00 :固定值,占用2字节
00 00 A8 05 00:系统区域,占用10字节
(10)帧脚:不显示,因为是TCP/IP及UDP/IP用的页脚。页脚在外部设备侧进行添加及发送。此外,通常根据外部设备自动被添加。
SLMP 3E帧:D0 00 00 FF FF 03 00 0C 00 00 00 73 00 00 00 00 00 00 00 00 00
(1)帧头:不显示。
(2)副帧头:D0 00。
(3)请求目标网络编号:00。
(4)请求目标站号:FF。
(5)请求目标模块T/0编号:FF 03。
(6)请求目标多点站号:00。
(7)响应数据长:0C 00。
(8)结束代码:00 00 存储指令处理结果,正常结束时存储0。异常结束时存储访问目标的出错代码。
(9)响应数据:73 00 00 00 00 00 00 00 00 00,正常结束时,存储对于指令的读取数据等。 常结束时,存储出错响应站的信息、与请求报文相同的指令及子指令、异常结束时的响应数据(通过指令定义的情况下)
(10)帧脚:不显示。