本文由艺捷自动化编写,艺捷自动化旗下产品有艺捷自动化网站和易为二维码说明书小程序(微信)
前言,先来说一下为什么会有这么一个奇怪的应用。在一个自动化系统改造升级项目中,甲方要求把消防的画面加到他们的后台上。他们的后台用的亚控的KingSCADA组态软件。但是把消防的数据做到后台电脑上何其难也,因为这是一个跨行业的应用了,人家消防有消防的一套通讯系统,跟你工控自动化是不兼容的。我研究消防系统485总线通讯协议,确定了用西门子200 SMART PLC来监听消防系统485总线的方案。所能获取的数据也很有限,只能获取实时发生的火灾信息。具体来说,当消防主机的485总线上接有火灾显示盘的时候,有火灾报警的时候,消防主机会向火灾显示盘发送火灾报警信息,这时候PLC监听到这一部分数据,提取出来,最后反馈到后台电脑上。要搞懂这些程序要有熟练的西门子200 SMART编程技术。也许您也碰到了这样奇葩的要求,这些资料就有很大的参考价值。下面就具体讲解一下实现的步骤,并提供所有资料和完整的PLC程序。
首先,先讲一下接线吧。首先来看消防主机的485通讯接线:
看到485显示盘A/B端子了吗,这上面的两根线是485通讯线,接到火灾显示盘上。再来看看火灾显示盘的接线:
看到了吗,这就是火灾显示盘,本来这个是要装在走廊上的,我们只用它的通讯功能,所以就放到柜子里了。这个火灾显示盘是要根据消防主机的型号,来配套的,要联系消防厂家,看看配哪个型号的火灾显示盘。看到那两根并排的红线和两根蓝线了吗,就是485通讯线,一端去消防主机,一端去PLC的通讯。再来看看PLC那边的接线吧:
看到PLC上的SB COM01扩展板了吗,那上面接的红线和蓝线,就是从火灾显示盘过来的485通讯线。这样就构建了一个485通讯总线,接线完毕。下面来讲一下消防系统的485总线通讯协议吧。
那么,现在开始讲485总线通讯协议。这份通讯协议是公司花了大价钱从消防厂家买来的,由于人家说是绝密文档,我没法给大家发布出来。但是为了讲清楚后面的程序,则必须要讲这个协议要用的部分内容。我把所有要用到的协议内容,一次性的在这里讲出来,后面看程序的时候,可以返回来仔细看。这个协议是一个消防系统485总线通讯协议,适用于其9000消防系统。我不清楚各个消防厂家的协议是不是一样的,假设你要做类似的监听通讯,则必须要从消防厂家那里获得其通讯协议,没有协议一切白费。下面就是协议的部分内容。
概述,在我做的这个系统里,火灾报警控制器做为主机,火灾显示盘做为从机。而PLC呢,只是一个监听者。
物理链路协议,起始位1位,数据位8位,校验位1位偶校验,停止位1位,波特率9600.
数据包传输协议。在数据包传输协议中,需要使用几个特征字符,用于包的完整传输,具体如下:SYN(0XAA)同步字符,连续两个以上的同步字符,认为是一个数据包开始;EOT(0XAF)结束字符,出现结束字符认为数据包数据结束;DLE(0XA0)转义字符,当数据中出现同步字符,结束字符和转移字符时,为了让这些字符做为普通数据处理,就在前面加一个转义字符。我后面的程序中还真用到了转移字符,是在处理中文的报警地址的时候用到的。
连接层传输协议必须遵循以下通讯机制:
1. 对于发送方的每一个数据包,接收方根据接收的数据必须向发送方发送响应数据包(接收确认或接收非确认)。
2. 对于多包数据传输,其数据发送有效包号从1开始。数据包号为0的ACK将触发实际多包数据的发送传输过程。发送PKG_NO号SOH包数据,接收方响应PKG_NO号ACK,发送方收到PKG_NO号ACK,发送方发送PKG_NO+1号包数据。
3. 当接收方检测到数据出错时,向发送方发送非确认NAK数据包。
4. 发送方发送完一个数据包后,在20ms 后没有收到接收方的确认或非确认信号,重发此数据包,重发次数为3。
5. 为了启动数据发送过程,发送方首先发送ENQ 数据包,等待接收发方发送PGK_NO=0的ACK 确认包,发送方在收到PKG_NO=0的ACK 确认包后,进入SOH数据包发送状态。
下表为连接层所用特征字符以及相应的通讯帧格式。
通讯帧含义 |
特征字符 |
通讯帧格式 |
||||||
数据 |
0xE0 (SOH) |
SOH |
SRCADDR |
DESTADDR |
PKG_NO |
LEN |
TYPE |
DATA |
广播数据 |
0xBB (BCSOH) |
BCSOH |
SRCADDR =0 |
DESTADDR =0 |
CMD_NO |
DATA |
|
|
退出 |
0xE1 (EXT) |
EXT |
SRCADDR |
DESTADDR |
|
|
|
|
接收确认 |
0xE2 (ACK) |
ACK |
SRCADDR |
DESTADDR |
PKG_NO |
|
|
|
接收非确认 |
0xE4 (NAK) |
NAK |
SRCADDR |
DESTADDR |
|
|
|
|
结束 |
0xE8 (NUL) |
NUL |
SRCADDR |
DESTADDR |
|
|
|
|
结束确认 |
0xE9 (NULACK) |
NULACK |
SRCADDR |
DESTADDR |
|
|
|
|
查询 |
0xE7 (ENQ) |
ENQ |
SRCADDR |
DESTADDR |
|
|
|
|
握手 |
0xD0 (SAK) |
SAK |
SRCADDR |
DESTADDR |
|
|
|
|
握手确认 |
0xDF (SAKED) |
SAKED |
SRCADDR |
DESTADDR |
TYPE |
|
|
|
连接 |
0xF1 (LINK) |
LINK |
SRCADDR |
DESTADDR |
|
|
|
|
连接确认 |
0xF4 (LINKED) |
LINKED |
SRCADDR |
DESTADDR |
|
|
|
|
终止连接 |
0xF2 (UNLINK) |
UNLINK |
SRCADDR |
DESTADDR |
|
|
|
|
终止连接确认 |
0xF8 (UNLINKED) |
UNLINKED |
SRCADDR |
DESTADDR |
|
|
|
|
大家看到了吗,主机和从机之间的通讯要经过一套发送,应答机制。
连接层通讯状态描述,地址:主机地址为00,从机地址为1-99.
握手信号和从机在线检测机制,当主机向从机发送握手数据包后,在规定的时间间隔内没有收到从机的应答信号就认为此次连接失败,不再进行重发,直接对下一个从机发送握手信号。
应用数据的传输,应用数据的传输需要依靠SOH和BCSOH通讯帧来完成。BCSOH用于广播、复位和消声等系统消息。SOH用于传输火警/反馈信息,配置信息等实际数据。
握手和握手确认,报警主机为了判断火灾显示盘和火灾显示盘扩容箱否在线,通讯是否畅通。报警主机会向从机轮询逐个握手,从机收到本地址的握手命令后,在40ms内向主机发送握手确认命令,否则报警主机会报该地址从机通讯故障。后面的程序中,以前用到过这个数据,后来不用了,用处不大。
【实例说明】
主机发送握手命令:AA AA AA AA D0 00 1E AF CE
从机响应握手确认:AA AA AA AA DF 1E 00 TYPE AF C1
握手命令解析
编号 |
数据 |
说明 |
备注 |
① |
AA AA AA AA |
同步字符 |
D0 握手命令/DF 握手确认 |
② |
D0 |
特征字符 |
|
③ |
00 |
发送源地址 |
报警主机地址号00,例子中从机为0x1E 即30。 |
④ |
1E |
发送目的地址 |
|
⑤ |
AF |
结束字符 |
|
⑥ |
CE |
数据校验 |
校验和 |
广播命令,广播命令有三条:复位命令、消音命令和时间同步命令。从机收到广播命令后不用向主机发送应答数据。复位命令:控制器复位时,控制器在485 总线上发送复位命令。消音命令:控制器进入本机消音状态,向485 从机设备发送消音命令。时间同步:控制器每10分钟向从机广播时间数据。后面的程序用到了这部分内容,具体是用到了广播时间同步命令。
【实例说明】
主机发送广播复位命令:AA AA AA AA BB 00 00 00 AF BB
主机发送广播消音命令:AA AA AA AA BB 00 00 01 AF BA
主机发送广播时间同步命令:AA AA AA AA BB 00 00 0E 11 01 25 15 02 13 AF 84
广播命令解析
编号 |
数据 |
说明 |
备注 |
① |
AA AA AA AA |
同步字符 |
|
② |
BB |
特征字符 |
广播命令 |
③ |
00 |
发送源地址 |
|
④ |
00 |
发送目的地址 |
广播命令目的地址为00 |
⑤ |
00 |
数据类型 |
00 复位/01 消音/0E 时间同步 |
⑥ |
11 01 25 15 02 13 |
时间数据11 年01 月25 日15 时02 分13 秒 |
日期和时间数据为BCD 码;复位和消音命令时,位置⑥无时间数据。 |
⑦ |
AF |
结束字符 |
|
⑧ |
84 |
数据校验 |
|
火警等信息传输流程,主机向从机下发一条火警信息,需要连续发送7帧数据(配置列别发送最多需要20帧,其它类型信息传递一般小于7帧),从机需要对每帧数据应答,共14帧数据。
火警信息传输实例说明:
步骤1)主—>从(主机向从机发送连接命令):AA AA AA AA F1 00 1E AF EF 。
步骤2)从—>主(从机发给主机发送连接确认命令): AA AA AA AA F4 1E 00 00 AF EA 。
步骤3)主—>从(主机向从机发送查询命令):AA AA AA AA E7 00 1E AF F9 。
步骤4)从—>主(从机发给主机接收确认命令):AA AA AA AA E2 1E 00 00 AF FC
步骤5)主—>从(主机向从机发送第一包火警数据):
AA AA AA AA E0 00 1E 01 23 20 02 01 01 00 39 39 0B 01 01 01 39 30 31 C7 F8 30 31 B2 E3 30 35 37 BA C5 00 00 00 00 00 00 00 00 00 00 00 AF EF 。
第1包火警数据解析(这里是后面程序要用的,只不过实际的数据比这个多,第1包数据扩大到年月日数据处):
编号 |
数据 |
说明 |
备注 |
① |
AA AA AA AA |
同步字符 |
|
② |
E0 |
特征字符 |
0xE0 发送数据 |
③ |
00 |
发送源地址 |
|
④ |
1E |
发送目的地址 |
|
⑤ |
01 |
包号 |
0x01 第一包数据 0x02 第二包数据 |
⑥ |
23 |
数据长度 |
0x23 即35 个字节 |
⑦ |
20 |
数据类型 |
0x20 火警或反馈 |
⑧ |
02 |
主类型 |
0x02 火警和反馈数据 |
⑨ |
01 |
从类型 |
0x01 火警<反馈>发生 |
⑩ |
01 |
主机号 |
|
11 |
00 |
接口板和回路号 |
0x00 表示第一个回路 |
12 |
39 |
设备地址号 |
回路中0x39 号地址报火警扩展到2 字节 |
13 |
39 |
设备的生产类型 |
|
14 |
0B |
设备类型 |
|
15 |
01 |
区号 |
|
16 |
01 |
栋号 |
|
17 |
01 |
层号 |
|
18 |
39 |
房号 |
|
19 |
|
位置描述 |
|
20 |
AF |
结束字符 |
|
21 |
EF |
数据校验 |
|
步骤6)从—>主(从机发给主机接收确认命令):AA AA AA AA E2 1E 00 01 AF FD 。
步骤7)主—>从(主机向从机发送第二包火警数据):AA AA AA AA E0 00 1E 02 23 20 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 11 01 25 15 02 00 00 CA D6 B1 A8 00 00 00 00 00 00 AF D8 。
第2包数据解析(这是后面程序要用到的,实际数据比这个少,只有时分秒及后面的数据):
编号 |
数据 |
说明 |
备注 |
① |
AA AA AA AA |
同步字符 |
|
② |
E0 |
特征字符 |
0xE0 发送数据 |
③ |
00 |
发送源地址 |
|
④ |
1E |
发送目的地址 |
|
⑤ |
02 |
包号 |
0x01 第一包数据 |
⑥ |
23 |
数据长度 |
0x23 即35 个字节 |
⑦ |
20 |
数据类型 |
|
⑧ |
|
位置信息描述 |
|
⑨ |
11 |
年 |
|
⑩ |
01 |
月 |
|
11 |
25 |
日 |
|
12 |
15 |
时 |
|
13 |
02 |
分 |
|
14 |
00 |
秒 |
|
15 |
00 |
隔离标志 |
|
16 |
|
设备类型描述 |
|
17 |
AF |
结束字符 |
|
18 |
D8 |
数据校验 |
|
步骤8)从—>主(从机对第二包数据的应答):AA AA AA AA E2 1E 00 02 AF FE。
步骤9)主—>从(主机发送数据传输结束命令):AA AA AA AA E8 00 1E AF F6。
步骤10)从—>主(从机应答结束确认):AA AA AA AA E9 1E 00 00 AF F7。
步骤11)主—>从(主机发送接收确认):AA AA AA AA E2 00 1E AF FC。
步骤12)从—>主(从机发送退出):AA AA AA AA E1 1E 00 00 AF FF。
步骤13)主—>从(主机发送终止连接):AA AA AA AA F2 00 1E AF EC。
步骤14)从—>主(从机应答终止连接确认):AA AA AA AA F8 1E 00 00 AF E6。
有效数据详细描述,火警或反馈信息有效数据详细描述(把2个火警数据包的数据合起来就能得到这个数据,后面的程序用到了这里的资料)
命令号 |
字段域 |
|
字段含义描述 |
含义描述 |
0x20 |
ucLength |
1 |
长度(71) |
火警或反馈 |
下同 |
ucStruMasterType |
1 |
主类型(0x02) |
下同 |
|
ucStruSlaverType |
1 |
从类型(0x01:火警<反馈>发生0x81:火警<反馈>消失) |
|
|
ucHostNO |
1 |
主机号(从1 开始) |
|
|
ucIOB_LoopNO |
1 |
接口板和回路号(=(IOBNO-1)*2+LOOPNO) |
|
|
ucAddrNO |
2 |
设备地址号(高字节为地址的低位,低字节为地址的高位) |
|
|
ucMakeType |
1 |
生产类型 |
|
|
ucEquipmentType |
1 |
设备类型(用于联动,详细描述见后) |
|
|
ucZoneNO |
1 |
区号(从0 开始0-19) |
|
|
ucBuildingNO |
1 |
栋号(从0 开始0-19) |
|
|
ucFloorNO |
1 |
层号(0-199 为1-200 层)(0xFF-0xF6 为-1 至-10 层) |
|
|
ucRoomNO |
1 |
房号(0-255) |
|
|
aucPlaceDesc |
41 |
位置描述,长度为41,以0 结尾的字符串 |
|
|
ucYear |
1 |
年(两位BCD 码) |
|
|
ucMonth |
1 |
月(两位BCD 码) |
|
|
cDay |
1 |
日(两位BCD 码) |
|
|
ucHour |
1 |
时(两位BCD 码) |
|
|
ucMinute |
1 |
分(两位BCD 码) |
|
|
ucSecond |
1 |
秒(两位BCD 码) |
|
|
ucIsolateFlag |
1 |
隔离标志(0:未隔离,1 隔离) |
|
|
aucEqpDesc |
11 |
设备类型描述,长度为11,以0 结尾的字符串 |
|
怎么样,这个协议啰嗦吗。后面还有各种数据详细描述和有关火灾显示盘扩容箱的通讯协议,由于后面的程序没有用到,就不罗列出来了。通讯协议的讲解就到此为止。
看到协议的内容估计大家头都大了吧。没事下面我会结合实际的程序给大家分解开,一步步讲解。要搞懂这个程序大家一定要投入一些时间,踏踏实实把程序看完。程序可能比较多,我没法一一在这里展示出来。我也不可能把每一条指令的作用给大家讲清楚,我只能说说这一段的程序执行的是什么功能。程序的基本逻辑就是监听485通讯线上的通讯帧,分析这些数据,获取对我们有用的数据。我打算按照程序的实际工作流程来讲解,而不是按照程序段的顺序来讲解,这样大家更容易理解。前面的指令我可能讲的仔细点,后面就讲主要的功能和特别需要注意的地方,因为内容实在太多,大家也不希望我长篇大论。
首先,在主程序中调用消防通讯子程序。
消防通讯子程序第1段:
这一段程序的功能是设置自由口通讯参数,连接中断处理程序,数据区清零,打开接收指令。SMB130设置为16#49的意思是,偶校验,每个字符8位,波特率9600,自由端口模式。SMB187设置为16#94的意思是,启用接收消息功能,忽略起始字符,忽略结束字符,使用空闲线,字符间定时器,使用定时器超时,忽略断开条件。SMW190设置为2意思是,空闲线时间2ms。设置SMW192为2意思是,定时器超时值2ms,由于主从机之间帧响应太快,所以减少时间为2ms.虽然设置的这么短,但还是可能会漏掉火警数据的第二个包。SMB194设置接收最大字符数99。将端口1接收消息完成(24)事件连接到中断处理24子程序上。开中断。中断计数为0。这个变量用来检测是否成功进入了中断处理程序。对接收区清零。启动第1次接收指令。
中断处理24子程序第5段和第8段:
首先来讲一个问题,由于消防主机和火灾显示盘之间的数据帧交互太快,火警数据需要由两个数据帧来完成,第2个火警数据帧有时会抓取不到。我这里使用了各种方法来缩短中断处理程序的时间,但效果不明显。即使用了跳转指令,也不能完全抓取第2包,10次里有1-2次抓不到。第5段程序,接收到确认命令后跳转。为什么这里要跳转呢,因为16#E2是接收确认的意思,是火灾显示盘发给消防主机的应答信息,对我们没用。我们只截取消防主机发给火灾显示盘的信息,所以为了减少中断处理时间,我们直接跳转,越过下面的程序段。虽然我采用了这种技巧,但是效果并不明显,还是前面说的有时候第2个火警数据包会抓取不到。后面我采用了,伪造第2个火警数据包的方法,到了那个地方我还会讲。第8段,就是跳转的标签,如果条件成立就跳转到这里,越过第6段和第7段。
获取完整资料,请点击获取完整资料链接。
获取完整资料