本文由艺捷自动化编写,艺捷自动化旗下产品有艺捷自动化网站和易为二维码说明书小程序(微信)
前言,先来说一下为什么会有这么一个奇怪的应用。在一个自动化系统改造升级项目中,甲方要求把消防的画面加到他们的后台上。他们的后台用的亚控的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 火警或反馈 0x40 故障 0x24 模块的启动或停止 0x50 主机状态 |
⑧ | 02 | 主类型 | 0x02 火警和反馈数据 0x05 故障数据 0x04 启动或停止 |
⑨ | 01 | 从类型 | 0x01 火警<反馈>发生 0x81 火警<反馈>消失 详细参考《系统SOH 命令号列表》 |
⑩ | 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 第一包数据 0x02 第二包数据 |
⑥ | 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段。
如何用PLC监听消防系统485总线通讯获取火灾报警数据_艺捷自动化