资料说明
这是贝克斯消防控制板的开窗器 Modbus 通讯协议,版本 V1.0.10。一块主板能带最多 128 个开窗器,主板当从站,你的 PLC 或上位机当主机去轮询和控制。
这个协议本身不复杂,但手册写得比较绕——查询返回的数值和控制的数值是两套体系,而且 PDF 只写了最复杂的”群控”写法(0x10 写 130 字节),现场实际更常用的是”单路开出”写法(0x06 写 1 个寄存器)。下面我按”你怎么用”的顺序来讲,两种写法都给出,你按需选简单的。
先搞清楚:这是个什么系统
一个消防控制主板,下面挂最多 128 个电动开窗器。主板通过 RS-485 总线跟你的上位机通信。你可以做三件事:
① 查:问主板”你现在什么状态?下面 128 个窗都什么位置?”——一次全读回来。
② 控:让主板自己开合,或者让下面某个窗开合。可以一次只控一个,也可以一次控一片。
③ 配:改主板的从站地址或波特率——偶尔用一次。
就这三件事。下面一个一个说。
接线和对参数
RS-485 两根线,A 接 A、B 接 B,首尾各并一个 120Ω 电阻。打开串口软件填:
| 参数 | 值 |
|---|---|
| 波特率 | 9600(默认,也支持 2400) |
| 数据位 | 8 |
| 校验位 | 无 |
| 停止位 | 1 |
| 从站地址 | 1(默认,可改 1~200) |
填错波特率或校验位一个都连不上,这是最基本的。
第一步:先查一下,确认通不通
拿 1 号主板试,发这条:
01 03 00 00 00 45 84 39
拆开看:01(从站地址 1) 03(功能码=读) 00 00(从寄存器 0 开始) 00 45(读 69 个寄存器) 84 39(CRC 校验)。
如果主板正常,它会回一长串数据,143 个字节。别慌,拆开看就清楚了:
| 位置 | 是什么 | 怎么读 |
|---|---|---|
| 第 1 字节 | 从站地址 | 应该跟你问的一致,比如 01 |
| 第 2 字节 | 功能码 | 03 |
| 第 3~4 字节 | 主板地址 | 当前从站地址 |
| 第 5~6 字节 | 波特率 | 0 = 2400,1 = 9600 |
| 第 7~8 字节 | 主板工作状态 | 0=正常,1=消防触发,2=雨感触发,3=设备故障 |
| 第 9~10 字节 | 主板电机状态 | 0=初始,1=开启中,2=关闭中 |
| 第 11~12 字节 | 主板电机位置 | 0~100,直接就是百分比(0 全关,100 全开) |
| 第 13~140 字节 | 1~128 号窗户状态 | 每窗 1 字节,见下面 |
| 最后 2 字节 | CRC 校验 | – |
这里有个绕的地方要先说清楚:你读的是 69 个寄存器,标准 Modbus 每个寄存器 2 字节,所以数据区一共 138 字节。前 5 个寄存器(10 字节)是主板自己的信息,后面 64 个寄存器(128 字节)对应 128 个窗户——每窗占 1 字节,不是 2 字节。这是这个协议最容易搞混的地方,记住就好。
窗户那 128 个字节,每个字节的值含义:
| 值 | 意思 |
|---|---|
| 0 | 全关(0%) |
| 1~99 | 开了 1%~99% |
| 100 | 全开(100%) |
| 200 | 这个窗离线了(没接或者线断了) |
| 201 | 这个窗故障 |
所以你拿到返回帧后,第 13 个字节就是 1 号窗的位置,第 14 个字节是 2 号窗,依此类推。读到 200 说明那一路没接窗,读到 201 说明窗有问题。
第二步:控制窗户开合
控制有两种写法。现场实际最常用的是单路控制,只发 8 个字节;PDF 上写的是群控,要发 137 个字节。先讲简单的。
写法 A:单路控制(推荐,最常用)
用 0x06 功能码写寄存器 0,写入值就是目标开度。这种方式一次只控制主板自己接的那个输出,或者控制默认的第一路输出。
帧格式:
[地址] 06 00 00 [开度高字节] [开度低字节] [CRC低] [CRC高]
控制值:
| 你填的值(十进制) | 十六进制 | 意思 |
|---|---|---|
| 3 | 0x0003 | 停止 |
| 100 | 0x0064 | 全关(0%) |
| 130 | 0x0082 | 开 30% |
| 150 | 0x0096 | 开 50% |
| 200 | 0x00C8 | 全开(100%) |
规律:控制值 = 目标百分比 + 100。想开 50% 就填 150(0x0096),想全开就填 200(0x00C8)。
现场验证过的例子(从用户群聊截图中提取)
从站地址 17(0x11),控制开到 50%:
11 06 00 00 00 96 0B 34
| 字节 | 值 | 含义 |
|---|---|---|
| 11 | 0x11 | 从站地址 17 |
| 06 | 0x06 | 写单个寄存器 |
| 00 00 | 0x0000 | 寄存器 0 |
| 00 96 | 0x0096 = 150 | 50%(150 – 100 = 50) |
| 0B 34 | – | CRC 校验(已验证正确) |
同样地址,其他常用值:
| 动作 | 完整帧(地址 17) |
|---|---|
| 全开 | 11 06 00 00 00 C8 8A CC |
| 全关 | 11 06 00 00 00 64 8A B1 |
| 停止 | 11 06 00 00 00 03 CB 5B |
| 开 50% | 11 06 00 00 00 96 0B 34 |
如果你的从站地址不是 17,把第一个字节换成你的地址,重新算 CRC 就行。
写法 B:群控(PDF 官方写法)
如果你要一次控制主板 + 下面 128 个窗,用 0x10 功能码,写 130 字节数据。帧长这样:
[地址] 10 00 00 00 41 82 [D0] [D1] [D2] ... [D128] [00] [CRC低] [CRC高]
前面 7 个字节是帧头(地址 + 功能码 + 寄存器起始 + 数量 + 字节数),中间 130 个字节是你要下发的控制指令,最后 D129 + CRC 收尾。
130 字节里,D0 控制主板自己,D1~D128 控制对应的 1~128 号窗,每个字节填什么值:
| 你填的值(十进制) | 十六进制 | 意思 |
|---|---|---|
| 3 | 0x03 | 停止(让正在动的窗立刻停) |
| 100 | 0x64 | 全关(0%) |
| 130 | 0x82 | 开 30% |
| 150 | 0x96 | 开 50% |
| 200 | 0xC8 | 全开(100%) |
| 255 | 0xFF | 不动作(保持现在的状态不动) |
不想动的窗填 255(0xFF),表示”这扇窗我不管,保持原样”。注意 255 跟 3(停止)不是一回事:255 是”不动作”,3 是”停下来”,区别在于 3 会中断正在进行的动作,255 完全不理它。
手册里的群控示例
2 号主板自身开 100%,1 号窗开 30%,2 号窗开 50%,其余不动:
02 10 00 00 00 41 82 C8 82 96 FF FF ... FF FF 00 1A 88
| 字节 | 值 | 意思 |
|---|---|---|
| 02 | 0x02 | 2 号主板 |
| 10 | 0x10 | 写多个寄存器 |
| 00 00 | – | 寄存器起始地址 = 0 |
| 00 41 | – | 写 65 个寄存器 |
| 82 | 0x82 = 130 | 数据字节数 = 130 |
| D0 = C8 | 0xC8 = 200 | 主板 100%(200-100=100%) |
| D1 = 82 | 0x82 = 130 | 1 号窗 30%(130-100=30%) |
| D2 = 96 | 0x96 = 150 | 2 号窗 50%(150-100=50%) |
| D3~D128 | 0xFF = 255 | 3~128 号窗不动作 |
| D129 | 0x00 | 保留 |
| 1A 88 | – | CRC 校验 |
手册在这条示例下面有个笔误:注释写”D1: 0x1E”,但报文行写的是 0x82。按规则 30% = 130 = 0x82,报文行是对的,0x1E 是写错了。
常用控制帧速查表
单路控制(0x06,最常用)
假设你的从站地址是 17(0x11),改地址就换第一个字节:
| 动作 | 完整帧(含 CRC) |
|---|---|
| 全开 | 11 06 00 00 00 C8 8A CC |
| 全关 | 11 06 00 00 00 64 8A B1 |
| 停止 | 11 06 00 00 00 03 CB 5B |
| 开 50% | 11 06 00 00 00 96 0B 34 |
群控(0x10,控主板+128 窗)
... 表示中间没提到的字节全填 0xFF,最后 D129 填 0x00,再补 CRC:
| 想干啥 | 帧头 + 前 5 字节数据 |
|---|---|
| 1 号主板自己全开 | 01 10 00 00 00 41 82 C8 FF ... |
| 1 号主板自己全关 | 01 10 00 00 00 41 82 64 FF ... |
| 1 号主板自己停止 | 01 10 00 00 00 41 82 03 FF ... |
| 1 号主板自己开 50% | 01 10 00 00 00 41 82 96 FF ... |
| 1 号全部窗户全开 | 01 10 00 00 00 41 82 C8 C8 ... |
| 1 号全部窗户全关 | 01 10 00 00 00 41 82 64 64 ... |
| 1 号全部停止 | 01 10 00 00 00 41 82 03 03 ... |
广播(地址 0)
地址 0 是广播,总线上所有主板都会执行但不回应。消防联动的时候很有用:
| 想干啥 | 帧头 + 前 5 字节数据 |
|---|---|
| 全部全开 | 00 10 00 00 00 41 82 C8 C8 ... |
| 全部全关 | 00 10 00 00 00 41 82 64 64 ... |
| 全部停止 | 00 10 00 00 00 41 82 03 03 ... |
第三步:改地址和波特率(偶尔用)
用 0x06 功能码,一次写一个寄存器。改完立即生效,之后你得用新参数跟它通信,别改完发现连不上了。
| 想干啥 | 完整帧 | 说明 |
|---|---|---|
| 1 号 → 改地址为 8 | 01 06 01 2C 00 08 48 39 |
寄存器 300(0x012C) 写 8 |
| 1 号 → 改地址为 200 | 01 06 01 2C 00 C8 48 69 |
– |
| 2 号 → 改地址为 5 | 02 06 01 2C 00 05 89 CF |
– |
| 1 号 → 改 2400 | 01 06 01 2D 00 00 18 3F |
寄存器 301(0x012D) 写 0 |
| 1 号 → 改回 9600 | 01 06 01 2D 00 01 D9 FF |
写 1 |
查询其他主板
把帧首字节换成对应地址就行:
| 主板 | 查询帧 |
|---|---|
| 1 号 | 01 03 00 00 00 45 84 39 |
| 2 号 | 02 03 00 00 00 45 84 0A |
| 3 号 | 03 03 00 00 00 45 85 DB |
| 200 号 | C8 03 00 00 00 45 95 A0 |
寄存器地图(完整对照)
整个协议就三组寄存器操作:
| 操作 | 寄存器地址 | 功能码 | 说明 |
|---|---|---|---|
| 查询全部状态 | 0(0x0000) | 0x03 | 读 69 个寄存器,返回主板+128 窗状态 |
| 配置主板地址 | 300(0x012C) | 0x06 | 写 1~200 |
| 配置波特率 | 301(0x012D) | 0x06 | 0=2400,1=9600 |
| 单路/群控控制 | 0(0x0000) | 0x06 或 0x10 | 0x06 控单路,0x10 控主板+128 窗 |
两套数值对照表(贴在屏幕上)
| 场景 | 数值范围 | 含义 | 换算 |
|---|---|---|---|
| 查询返回(窗户状态) | 0~100 | 0=全关,100=全开 | 直接就是百分比,不用换算 |
| 控制写入(开窗指令) | 100~200 | 100=全关,200=全开 | 控制值 = 目标百分比 + 100 |
特殊值:控制帧里 3 = 停止,255 = 不动作(只用于群控);查询返回里 200 = 离线,201 = 故障。
调试检查清单
- 波特率 9600、8N1——出厂默认,改过的话用新值。
- 从站地址默认 1,范围 1~200,0 是广播。
- 控制一扇窗最简单的办法是 0x06 写寄存器 0,不是 0x10 群控。
- 控制值要加 100:开 30% 填 130,开 100% 填 200。查询值不加,30 就是 30%。
- 查询返回 143 字节,串口缓冲区要开够,别截断了。
- 128 个窗每窗 1 字节,不是 2 字节。解析返回帧时第 13 字节开始就是窗户数据。
- 改地址/波特率后立即生效,马上用新参数通信。
- 主板工作状态 4 种:正常 / 消防触发 / 雨感触发 / 设备故障——消防和雨感是自动触发,不是你控的。
文档勘误
PDF 第 5 节示例 3,报文行写 D1 = 0x82(= 130 → 30%),但下面注释写 D1: 0x1E(= 30)。按指令定义 100~200 = 0%~100%,30% 应该是 130(0x82)。报文行正确,注释的 0x1E 是笔误。
点位表 / 寄存器表
按地址、功能码、数据类型和倍率整理,适合调试、归档和项目交付。