Skip to content

BLE 5.x 技术详解

BLE 5.0 长距离模式

BLE 5.0 引入编码 PHY,通过降低速率换取更长覆盖距离:

PHY 类型:
  1M PHY:1Mbps,标准模式(BLE 4.x 兼容)
  2M PHY:2Mbps,高速模式(BLE 5.0 新增)
  Coded PHY S=2:500kbps,覆盖增强 +6dB
  Coded PHY S=8:125kbps,覆盖增强 +20dB(最远)

覆盖距离对比(室外视线内):
  1M PHY:约 100m
  Coded PHY S=8:约 400m(理论可达 1km+)

应用场景:
  工厂大型仓库(无需密集部署 AP)
  农业大棚(覆盖范围大)
  建筑工地(临时部署)

BLE 5.1 方向查找(AoA/AoD)

BLE 5.1 引入到达角(AoA)和出发角(AoD)技术,实现厘米级室内定位:

AoA(Angle of Arrival):
  发射端:单天线发送 CTE(恒定音调扩展)信号
  接收端:天线阵列,通过相位差计算信号到达角
  精度:< 1m(典型),< 0.1m(高精度部署)
  
AoD(Angle of Departure):
  发射端:天线阵列,发送已知方向的信号
  接收端:单天线,计算信号出发角
  
应用场景:
  室内导航(医院、商场)
  资产追踪(医疗设备、工具)
  人员定位(工厂安全管理)

BLE Mesh 组网

BLE Mesh(Bluetooth Mesh)允许 BLE 设备构建多跳网状网络:

Mesh 网络角色:
  Node(节点):网络中的设备
  Relay(中继):转发消息,扩展覆盖
  Proxy(代理):连接手机等 GATT 设备
  Friend(朋友):为低功耗节点缓存消息
  Low Power Node(低功耗节点):依赖 Friend 节点

消息传播:
  发布/订阅模型
  消息通过 Relay 节点多跳传播
  TTL(Time to Live)控制跳数

典型应用:
  智能照明(一键控制整栋楼的灯)
  工业传感器网络
  楼宇自动化

BLE Mesh 开发示例

python
# 使用 PyBluez 实现简单的 BLE Mesh 节点
# 注意:完整 Mesh 实现需要专用库(如 nRF Mesh SDK)

import bluetooth
import struct
import time

class BLEMeshNode:
    """简化的 BLE Mesh 节点"""
    
    def __init__(self, node_id, group_address=0xC000):
        self.node_id = node_id
        self.group_address = group_address
        self.message_cache = set()  # 防止消息循环
    
    def publish(self, opcode, data):
        """发布消息到组地址"""
        # 构建 Mesh 消息
        msg = struct.pack('>HH', self.group_address, opcode) + data
        
        # 通过 BLE 广播发送
        self._advertise(msg)
    
    def _advertise(self, data):
        """通过 BLE 广播发送数据"""
        # 实际实现需要使用 BLE 广播 API
        print(f"Node {self.node_id} broadcasting: {data.hex()}")
    
    def on_message(self, src_addr, opcode, data):
        """处理接收到的消息"""
        msg_id = (src_addr, opcode, data)
        
        if msg_id in self.message_cache:
            return  # 已处理过,忽略
        
        self.message_cache.add(msg_id)
        
        # 处理消息
        if opcode == 0x8202:  # Generic OnOff Set
            state = data[0]
            print(f"Node {self.node_id}: OnOff = {state}")
            self.set_light(state)
        
        # 中继转发(如果是 Relay 节点)
        if self.is_relay:
            self._advertise(struct.pack('>HH', src_addr, opcode) + data)
    
    def set_light(self, state):
        """控制灯光"""
        print(f"Light {'ON' if state else 'OFF'}")

褚成志的笔记