4. 节点角色与功能:中继节点、代理节点、朋友节点、低功耗节点

蓝牙Mesh网络里,不是所有设备都干一样的活。我刚开始接触Mesh时,以为所有节点都是对等的,后来才发现——角色不同,职责天差地别。

说白了,蓝牙Mesh定义了四种节点角色:中继节点、代理节点、朋友节点和低功耗节点。一个物理设备可以同时扮演多个角色,也可以只承担一种。选对了角色,网络就稳;选错了,要么功耗爆炸,要么消息传不过去。

核心要点:节点角色不是硬件决定的,而是软件配置决定的。同一个芯片,今天当中继,明天当朋友,完全看你怎么配。

4.1 中继节点(Relay Node)

中继节点是Mesh网络的"传话筒"。它的工作很简单:收到一条消息,看看是不是发给自己的,如果不是,就转发出去。

我做过一个智能照明项目,灯和开关分布在三层楼。如果没有中继节点,一楼的开关永远叫不亮三楼的灯。中继节点就是干这个的——让消息能跳着走。

中继的工作原理

中继节点使用TTL(生存时间)机制来控制消息的传播范围。每转发一次,TTL减1。TTL降到0,消息就死了。

// 中继节点处理逻辑(伪代码)
void relay_handler(mesh_message_t *msg) {
    if (msg->ttl <= 1) {
        return; // 不再转发
    }
    msg->ttl--;
    // 检查是否已经转发过(防环路)
    if (!is_duplicate(msg)) {
        broadcast(msg);
    }
}

我的经验:TTL别设太大。默认值一般是7,覆盖几百平米绰绰有余。设成127反而会让消息在网络里乱窜,浪费带宽。我曾经在一个仓库项目里把TTL设成63,结果消息延迟飙升,排查了半天才发现是TTL太大导致的。

中继节点的配置

参数 说明 建议值
TTL默认值 消息最大跳数 7
中继重传次数 每条消息重复发送次数 2~3
中继缓存大小 存储已转发消息的队列长度 100~200条

注意:中继节点会持续监听射频,功耗较高。电池供电的设备不建议开启中继功能。我见过有人把门磁传感器设成中继,结果电池三天就耗光了。

4.2 代理节点(Proxy Node)

代理节点是Mesh网络和外部世界的"翻译官"。它的核心作用:让不支持Mesh协议的设备(比如手机、平板)也能和Mesh网络通信。

你想想看,手机蓝牙芯片只支持GATT协议,不认识Mesh的广播包。代理节点就充当桥梁——手机通过GATT连上代理节点,代理节点把GATT消息转成Mesh消息,再扔进网络里。

代理协议的工作流程

  1. 手机通过GATT连接代理节点
  2. 代理节点在GATT层提供Mesh Proxy Service
  3. 手机发送Mesh协议数据包(封装在GATT包里)
  4. 代理节点解包,转发到Mesh网络
  5. 反向同理——Mesh网络的消息通过代理节点推送给手机

关键点:代理节点必须同时支持GATT和Mesh两种协议栈。这意味着它的资源消耗比普通节点高。我建议至少选择有256KB Flash的芯片来做代理节点。

什么时候必须用代理节点?

  • 手机App需要配置或控制Mesh网络
  • 网关需要把Mesh数据上传到云端
  • 调试工具需要通过GATT抓取Mesh网络数据

嗯,这里要注意:一个Mesh网络里可以有多个代理节点。但手机同一时间只会连一个。如果代理节点挂了,手机会自动切换到另一个。

4.3 朋友节点(Friend Node)

朋友节点是低功耗节点的"保姆"。它的存在只有一个目的:帮低功耗节点省电。

怎么省?低功耗节点可以睡觉,朋友节点替它收消息。等低功耗节点醒了,朋友节点再把攒了一堆的消息一股脑丢给它。

朋友关系的建立过程

  1. 低功耗节点广播"找朋友"请求
  2. 愿意当朋友的中继节点回复"我可以"
  3. 双方协商参数:窗口大小、订阅地址等
  4. 建立朋友关系,开始工作
// 朋友节点缓存消息(伪代码)
void friend_node_store(mesh_message_t *msg, uint16_t lpn_addr) {
    friend_cache_t *cache = get_friend_cache(lpn_addr);
    if (cache->count < cache->max_size) {
        cache->messages[cache->count++] = *msg;
    } else {
        // 缓存满了,丢弃最旧的消息
        drop_oldest(cache);
        cache->messages[cache->count++] = *msg;
    }
}

避坑指南:我曾经在一个智能家居项目里,把朋友节点的缓存设得太小。结果低功耗节点睡了一小时,醒来发现消息全被丢了。后来我把缓存加大到50条,才解决问题。记住:缓存大小要根据低功耗节点的睡眠周期来算。

朋友节点与低功耗节点的参数协商

参数 含义 典型值
ReceiveDelay 低功耗节点醒来后等待多久开始收消息 10ms
ReceiveWindow 低功耗节点打开接收窗口的时长 20ms
PollTimeout 低功耗节点两次轮询的最大间隔 10秒~10分钟
FriendCache 朋友节点能缓存多少条消息 10~100条

4.4 低功耗节点(Low Power Node, LPN)

低功耗节点是Mesh网络里的"节能标兵"。它大部分时间都在睡觉,只有需要收发消息时才醒来。

我做过一个温湿度传感器项目,用CR2032电池供电。如果不启用LPN模式,电池撑不过两周。开了LPN后,一节电池用了大半年。

低功耗节点的工作模式

  • 睡眠状态:射频关闭,电流微安级
  • 唤醒状态:打开射频,向朋友节点轮询消息
  • 收发状态:发送自己的数据,接收朋友节点的缓存

省电原理:低功耗节点不监听网络消息,只在自己醒来时主动问朋友节点"有没有我的消息?"。这样避免了持续监听射频的功耗。

低功耗节点的配置要点

  1. 轮询间隔:间隔越长越省电,但消息延迟越大。传感器数据可以设长一点(比如30秒),开关控制要设短一点(比如1秒)。
  2. 接收窗口:窗口太短可能收不到消息,太长又费电。我一般设20ms,够用。
  3. 朋友节点选择:尽量选信号好、位置固定的设备当朋友。移动设备当朋友?别闹了。

警告:低功耗节点不能当中继节点。这是协议规定的。原因很简单——你都在睡觉了,怎么帮别人传消息?

4.5 四种角色的关系与选择

这四种角色不是互斥的。一个设备可以同时是代理节点和朋友节点,也可以只当中继节点。但低功耗节点不能当中继,这是硬性限制。

我画了一张图,帮你理清它们之间的关系:

蓝牙Mesh节点角色关系图 中继节点 代理节点 朋友节点 低功耗节点 可兼任 可兼任 缓存消息 轮询请求 说明: 中继节点和代理节点可以兼任朋友节点。 低功耗节点不能兼任中继节点或代理节点。 一个设备可以同时承担多个角色,但需评估资源是否足够。

实际项目中的角色选择建议

设备类型 推荐角色 原因
智能灯泡(市电供电) 中继节点 + 朋友节点 不缺电,适合帮别人传消息
温湿度传感器(电池供电) 低功耗节点 必须省电,偶尔上报数据即可
手机App 代理节点(通过GATT) 手机不支持Mesh广播,必须走代理
智能开关(电池供电) 低功耗节点 用户按开关时才需要通信,平时睡觉
网关(市电供电) 中继 + 代理 + 朋友 资源充足,承担所有角色

我的习惯:项目初期,我会把所有设备都配成中继节点,先保证网络连通性。等调通了,再根据功耗需求逐个优化角色配置。别一上来就搞LPN,否则排查问题时会很痛苦。

四种角色各有各的用武之地。中继节点撑起网络的骨架,代理节点打通与外界的通道,朋友节点和低功耗节点配合实现超低功耗。理解了这些角色,你就能根据实际需求灵活设计Mesh网络了。