2. 蓝牙Mesh核心概念与网络架构

蓝牙Mesh不是那种“一个主设备带一堆从设备”的老套路。它更像一个群——每个人都能发消息,每个人都能帮忙转发。我第一次接触这个概念时,脑子里全是“那谁负责干活?谁可以睡觉?”的疑问。嗯,今天我们就来拆解这五个角色。

一句话总结:蓝牙Mesh里所有设备都是“节点”,但不同节点可以承担不同“角色”。一个节点可以身兼多职,也可以只干一件事。

1. 节点(Node)——Mesh世界的公民

任何加入了Mesh网络的设备,都叫节点。说白了,只要你的灯、开关、传感器成功入网,它就是一个Node。

节点是网络的最小单元。它必须能收发Mesh消息,至少支持一种承载层(Advertising Bearer或GATT Bearer)。我个人习惯把节点比作“有身份证的居民”——你可以不说话,但你必须能听懂别人在说什么。

  • 必备能力:至少一个Element(元素),至少一个Model(模型)
  • 可选能力:中继、代理、朋友、低功耗等角色
  • 我遇到过的情况:有一次客户说“我的灯入网了但收不到开关指令”,查了半天发现那个节点只配了Config Client Model,没配Light Lightness Server Model——它根本不知道自己要处理亮度消息。

小提示:节点入网时,Provisioner会给它分配一个单播地址。这个地址就像门牌号,后续所有消息都靠它定位。

2. 中继节点(Relay)——消息的二传手

Relay节点是Mesh网络的脊梁。它收到一条消息后,会重新广播出去,让消息跳得更远。

你想想看,如果每个灯只能跟隔壁的灯说话,那一个100平米的客厅都覆盖不了。Relay的作用就是“接力跑”——消息每经过一个Relay,就多跳一步。

特性 说明
承载层 只使用Advertising Bearer(广播)
TTL控制 消息每转发一次TTL减1,TTL=0时不再转发
功耗 较高,需要持续监听广播信道
典型设备 常供电的灯、网关、中控面板

注意:Relay不是越多越好。我曾经在一个项目里把50个灯全配成Relay,结果广播风暴直接把网络干瘫痪了。一般建议Relay数量控制在总节点数的20%~30%。

3. 代理节点(Proxy)——让手机也能玩Mesh

手机、平板、PC这些设备没有蓝牙Mesh协议栈,它们只懂经典蓝牙的GATT。Proxy节点就是那个“翻译官”——它一边用GATT跟手机通信,一边用Advertising Bearer跟Mesh网络通信。

我记得第一次调试Proxy功能时,手机APP死活连不上灯。后来发现是Proxy节点的GATT Service没有正确广播——说白了,手机找不到那个“翻译官”在哪。

  • 核心协议:Mesh Proxy Service(UUID: 1828)
  • 数据通道:通过GATT的Proxy Protocol传输Mesh PDUs
  • 典型场景:手机APP配网、调试、单灯控制

关键点:Proxy节点必须同时支持Advertising Bearer和GATT Bearer。如果你只开了GATT,那它只能跟手机说话,没法跟Mesh里的其他节点通信。

4. 朋友节点(Friend)与低功耗节点(LPN)——省电搭档

这两个角色必须成对出现。LPN想省电,Friend帮它“代收消息”。

LPN平时可以睡觉,Friend把发给LPN的消息缓存起来。等LPN醒来问“有我的消息吗?”,Friend再一次性转发给它。

角色 功耗 缓存 典型设备
Friend 较高(持续监听) 最多可缓存64条消息 常供电的灯、网关
LPN 极低(大部分时间休眠) 无 电池供电的传感器、开关

我做过一个项目,用纽扣电池供电的温湿度传感器当LPN,配合一个常供电的灯当Friend。传感器每10秒醒来一次,发完数据就睡。电池撑了两年多——嗯,这才是物联网该有的样子。

避坑指南:一个Friend最多可以服务多少个LPN?规范说最多100个,但我建议别超过20个。我曾经试过挂30个LPN到一个Friend上,结果Friend的缓存溢出,消息丢得一塌糊涂。

5. 角色组合与网络拓扑

一个节点可以同时扮演多个角色。比如一个常供电的灯,可以同时是Relay、Proxy、Friend。但LPN不能同时是Relay——你都在睡觉了,怎么帮别人转发消息?

下面这张图展示了典型的Mesh网络拓扑:

蓝牙Mesh网络拓扑与节点角色 手机APP Proxy节点 Relay节点 Friend节点 LPN节点 普通节点 GATT 广播 广播 广播 Friend缓存 图例说明 手机APP:通过GATT连接Proxy Proxy节点:GATT ↔ 广播翻译 Relay节点:转发广播消息 Friend节点:为LPN缓存消息 LPN节点:大部分时间休眠 普通节点:只收不发,不中继

6. 实际项目中的角色分配建议

做智能照明系统时,我一般这样分配角色:

  1. 吸顶灯、筒灯(常供电):开启Relay + Friend。它们24小时有电,最适合当网络骨干。
  2. 墙壁开关(电池供电):只做LPN。用户按一下开关,发一条消息就继续睡。
  3. 网关/中控屏(常供电+需要手机控制):开启Proxy + Relay。手机配网和日常控制都靠它。
  4. 传感器(电池供电):只做LPN。定期上报数据,其他时间休眠。

曾经踩过的坑:有一次我把所有灯都配成了Relay,结果网络里消息满天飞,TTL设成5都挡不住。后来强制要求:只有吸顶灯才能当Relay,射灯和灯带一律只做普通节点。网络瞬间安静了。

7. 角色配置的底层逻辑

每个角色对应一个或多个比特位,存在节点的Configuration Model里。Provisioner通过Config Relay Set、Config Proxy Set等命令来开关这些能力。

嗯,这里要注意:即使节点硬件支持Relay,如果Provisioner没给它开,它也不会转发消息。我见过有人把Relay功能写死在固件里,结果想关都关不掉——只能重新烧录。

// 伪代码示例:配置节点角色
// 开启Relay功能
config_relay_set(node_address, relay_state=ENABLE, relay_retransmit_count=2, relay_retransmit_interval=20ms);

// 开启Proxy功能
config_proxy_set(node_address, proxy_state=ENABLE);

// 建立Friend关系
friend_poll(lpn_address, friend_address, poll_interval=100ms);

个人习惯:我会在Provisioning完成后,统一做一次角色配置。先把所有常供电节点配成Relay+Friend,再给电池设备配LPN,最后给网关开Proxy。顺序别搞反,否则LPN配好了但Friend还没就位,它会一直等。

好了,这五个角色就是蓝牙Mesh网络的基石。你不需要让每个节点都身兼数职——有时候,一个只会收消息的普通节点,反而是最稳定的选择。