1.报文的基本格式
1.1 第1和第2个字节是:固定报文头03 00,这里我们就用到三种报文: a.初始化 b. 读 c.写,都是这种格式;
1.2 第3和第4个字节是:整个报文的长度;
其它部分就是各种报文的个性化处理了;
下面分析大量报文的案例进行规律分析,为了便于对照,每种都用1200 和300 两种对照demo显示:
2.初始化报文
初始化报文分两个交互:
2.1 交互一
西门子1200:
PC发出报文 ( [A18]=0x01 =CPUSlot)
03 00 00 16 11 E0 00 00 00 01 00 C1 02 01 00 C2 02 01 01(cpuslot) C0 01 09
PLC回复报文( B[10]=0x06 可能 是西门子的小型号 B[22]=0x01=CPUSlot)
03 00 00 16 11 D0 00 01 00 06 00 C0 01 09 C1 02 01 00 C2 02 01 01 (cpuslot)
西门子300:
PC发出报文 ( A[18]=0x02 =CPUSlot)
03 00 00 16 11 E0 00 00 00 01 00 C1 02 01 00 C2 02 01 02(cpuslot) C0 01 09
PLC回复报文 (B[10]=0x04 可能 是西门子的小型号 B[22]=0x0=CPUSlot)
03 00 00 16 11 D0 00 01 00 04 00 C0 01 09 C1 02 01 00 C2 02 01 02
opc 对 1200 和 300 不用配置的不同点,就一个地方:前者 CPUSlot = 1 ,后者CPUSlot = 2;
所以可以摸索规律是:
a.pc发起第一个初始化报文的时候,第18个字节标识了CPUSlot ;
b.plc回复报文和读取报文长度一样都是22个字节长度;
c.plc回复报文的最后一个字节也是CPUSlot ,这个可以用来校验;
d. plc回复的第10个字节一个是06,一个是04,这个好像是小型号的区别;
细节摸索下来:1200该字节是06,314是04,315是03;咱写程序的时候,就不要考虑这个来校验了;
2.2交互二
PC发出报文
03 00 00 19 02 F0 80 32 01 00 00 FF FF 00 08 00 00 F0 00 00 01 00 01 07 80
PLC回复报文
03 00 00 1B 02 F0 80 32 03 00 00 FF FF 00 08 00 00 00 00 F0 00 00 01 00 01 00 F0
第二个初始化报文交互,通过1200 和314,315的对比,发现居然完全没有任何区别;
所以我们可以把这个交互完全固话;
到此,整个初始化处理就算结束了,正常在设计架构的时候,可以这么实现:
在ClentSocket的onConnect(即正常连接上)的瞬间,pc给plc发起第一个初始请求,得到回复后(为了简单,就仅仅判断长度为22即可);
立刻发起第二个固定的初始话请求,得到长度为24的报文后,就通过一个布尔变量通知整个系统可以正常读写;
3.读操作
读demo1:
西门子1200: 读取DB10, count=17 ,offset=19
PC发出报文
(A[3]~A[4]=0x001F=31=读取报文总长度, A[12]~A[13]=0x001C=序列号,A[24]~A[25]=0x0011=17=读取请求count;
A[26]~A[27]=0x000A=10=DB10, A[28]=0x84=读取的数据类型为DB块,A[29]~A[31]=0x000098=152=19*8=读取偏移量offset(bit为单位) )
03 00 00 1F 02 F0 80 32 01 00 00 00 1C 00 0E 00 00 04 01 12 0A 10 02 00 11 00 0A 84 00 00 98
PLC回复报文:
(B[3]~B[4]=0x002A=42=回复报文总长度, B[12]~B[13]=0x001C=序列号,B[16]~B[17]=0x0015=21=读取请求count(17)+4
B[24]~B[25]=0x0088=17*8=请求数据长度(bit为单位), B[26]~最后=数据值)
03 00 00 2A 02 F0 80 32 03 00 00 00 1C 00 02 00 15 00 00 04 01 FF 04 00 88 13 14 15 16 17 00 00 00 00 00 00 00 00 00 00 00 00
读demo2:
西门子1200: 读取DB11, count=17 ,offset=19
<