4、主流通信协议(上):BACnet协议详解(对象、服务、网络层)、BACnet IP与BACnet MS/TP
好,咱们今天聊聊BACnet。说实话,在楼宇自控这个圈子里混,BACnet是绕不开的一座山。你想想看,一个项目里可能有霍尼韦尔的DDC、西门子的控制器、还有国产的第三方设备,怎么让它们“说同一种语言”?BACnet就是答案。
我个人习惯把BACnet理解成“楼宇界的通用语”。它不是某个厂家的私有协议,而是ASHRAE(美国暖通空调工程师学会)搞出来的开放标准。嗯,这里要注意,开放不等于简单,它的设计其实挺精巧的。
4.1 BACnet的核心三要素:对象、服务、网络层
BACnet的架构,说白了就是三个东西:对象(Object)、服务(Service)、网络层(Network Layer)。我刚开始学的时候也觉得抽象,后来在项目里调设备多了,发现这其实就是“数据是什么、能干什么、怎么传过去”的问题。
4.1.1 对象(Object)—— 数据长什么样
BACnet里的“对象”不是面向对象编程里的那个对象,它更像一个数据容器。每个对象都有固定的属性(Property),用来描述一个物理点或逻辑点。
举个例子,一个温度传感器,在BACnet里就是一个模拟输入对象(Analog Input Object)。它有哪些属性?
- 对象标识符(Object_Identifier):唯一编号,比如“AI:101”
- 对象名称(Object_Name):给人看的,比如“Zone1_Temp”
- 当前值(Present_Value):实时温度,比如25.3℃
- 单位(Units):摄氏度还是华氏度
- 状态标志(Status_Flags):有没有报警、是否失效等
我在项目中遇到过最头疼的事,就是厂家把对象名称起得乱七八糟。有的叫“TEMP1”,有的叫“AI_01”,调试时根本对不上号。所以我建议,项目一开始就定好命名规范,比如“楼层_设备类型_序号”,能省很多事。
BACnet标准定义了50多种标准对象类型,常用的有:
| 对象类型 | 用途 | 常见例子 |
|---|---|---|
| Analog Input (AI) | 模拟量输入 | 温度、湿度、压力 |
| Analog Output (AO) | 模拟量输出 | 阀门开度、变频器频率 |
| Binary Input (BI) | 数字量输入 | 风机状态、门磁信号 |
| Binary Output (BO) | 数字量输出 | 启停命令、开关控制 |
| Device (DEV) | 设备自身信息 | 设备型号、固件版本 |
| Schedule | 时间表控制 | 工作日/节假日模式切换 |
| Trend Log | 历史数据记录 | 过去24小时温度曲线 |
4.1.2 服务(Service)—— 能干什么事
对象是“数据”,服务就是“操作”。BACnet定义了一组标准服务,让设备之间可以互相读写数据、执行命令、甚至同步时间。
常用的服务分几类:
- 读属性服务(ReadProperty):最常用,比如上位机读一个AI对象的当前值。
- 写属性服务(WriteProperty):用来控制,比如把AO对象的当前值写成50%,阀门就开到一半。
- 原子写文件服务(AtomicWriteFile):用来上传固件或配置文件。
- 设备通信控制服务(DeviceCommunicationControl):可以远程禁用某个设备,调试时很有用。
- 时间同步服务(TimeSynchronization):让所有设备时间一致,日志记录才靠谱。
你想想看,如果没有这些标准服务,每个厂家都自己定义一套读写指令,那系统集成就是一场噩梦。BACnet把这些操作统一了,上层软件不用关心底层是哪个牌子的设备。
4.1.3 网络层(Network Layer)—— 怎么传过去
网络层解决的是“数据包怎么路由”的问题。BACnet支持多种物理层和数据链路层,比如以太网、RS-485、甚至LonTalk。网络层的作用就是屏蔽这些差异,让上层应用感觉不到底层换了。
BACnet网络层有几个关键概念:
- 网络号(Network Number):每个子网一个唯一编号,类似IP网络里的网段。
- MAC地址:在MS/TP总线上是1-254的设备地址,在IP网络上就是IP地址+端口号。
- 路由器(Router):连接不同BACnet网络的设备,负责转发数据包。
我记得有一次调试一个大型园区项目,有3栋楼,每栋楼一个MS/TP总线,通过BACnet路由器连到中央以太网。结果发现A楼的设备能读到B楼的数据,但C楼的不行。查了半天,原来是路由器的网络号配置重复了。嗯,网络号必须全局唯一,这个坑我踩过。
4.2 BACnet IP 与 BACnet MS/TP
这两种是BACnet最主流的物理层实现。一个跑在以太网上,一个跑在RS-485串行总线上。选哪个?看场景。
4.2.1 BACnet IP —— 高速、大容量、适合主干网
BACnet IP就是把BACnet数据包封装在UDP/IP里传输。它使用端口号0xBAC0(十进制47808),这个数字我记了十年都没忘。
特点:
- 速度快:100Mbps甚至千兆,适合大量数据交换。
- 距离远:通过交换机可以覆盖整个园区。
- 设备多:理论上一个IP子网可以挂几百个设备。
- 支持广播:设备自动发现(Who-Is / I-Am服务)非常方便。
但BACnet IP也有缺点。它依赖网络基础设施,如果交换机配置不当(比如禁用了UDP广播),设备就发现不了。我曾经在一个项目中,IT部门为了安全把广播封了,结果BACnet设备全成了“孤岛”。最后协调了半天才开了例外规则。
4.2.2 BACnet MS/TP —— 低成本、抗干扰、适合现场总线
MS/TP(Master-Slave/Token-Passing)跑在RS-485物理层上。它用令牌传递的方式决定哪个设备可以发送数据。
特点:
- 成本低:RS-485芯片便宜,线缆用双绞线就行。
- 抗干扰强:差分信号,适合空调机房、配电间等电磁环境复杂的地方。
- 距离远:不加中继器可以到1200米,加中继器能更远。
- 速度慢:典型波特率9600~76800 bps,不适合传大量历史数据。
- 设备数量有限:一条总线上最多32个设备(不加中继器)。
4.2.3 两者的对比
| 对比项 | BACnet IP | BACnet MS/TP |
|---|---|---|
| 物理层 | 以太网 (RJ45) | RS-485 (双绞线) |
| 典型速率 | 100 Mbps | 9.6 ~ 76.8 kbps |
| 最大距离 | 100米/段(交换机级联可延长) | 1200米(不加中继器) |
| 最大设备数 | 取决于IP子网 | 32个/段(加中继器可扩展) |
| 典型应用 | 中央监控、服务器、工作站 | DDC控制器、传感器、执行器 |
| 成本 | 较高(需交换机、网线) | 较低(线缆便宜、无需交换机) |
| 调试难度 | 需懂IP网络知识 | 需注意终端电阻、极性、接地 |
4.3 一个小例子:用BACnet读一个温度值
光说不练假把式。咱们模拟一下,上位机通过BACnet IP读一个AI对象的当前值。
假设:
- 设备IP:192.168.1.100
- 设备实例号:1234
- 对象:AI:101
- 属性:Present_Value(属性ID=85)
BACnet协议栈会构造这样一个请求(简化版):
BACnet APDU:
PDU Type: Confirmed Request (0x00)
Service Choice: ReadProperty (0x0C)
Object Identifier: Analog Input, Instance 101
Property Identifier: Present_Value (85)
然后封装成UDP包,发到192.168.1.100:47808。设备收到后,返回一个响应包,里面包含当前值,比如25.3℃。
你看,整个过程就这么简单。但实际项目中,你不需要自己拼这些字节,BACnet协议栈库(比如BACnet Stack、BACpypes)都帮你封装好了。你只需要调用API,比如readProperty(device, objectType, instance, propertyId)。
嗯,说到这,我想起一个经验:调试BACnet IP时,先用Wireshark抓个包看看。如果能看到UDP包发出去但没回应,八成是防火墙或交换机ACL把端口封了。如果能看到回应但解析不出来,可能是设备实现的BACnet版本不一致(比如BIBB不同)。
好了,这一章咱们把BACnet的对象、服务、网络层,以及两种主流物理层实现都过了一遍。下一章咱们聊聊另一个重要协议——Modbus,它在工业控制和楼宇自控里也占着半壁江山。到时候咱们对比着看,你会发现各有各的脾气。