BLE系列文章及实际踩坑经验,第一篇主要是BLE入门:GATT服务与数据收发。欢迎大家在评论区交流看法、提出疑问或分享实践心得,一起探讨。

      低功耗蓝牙 BLE 是嵌入式 IoT 最常用无线方案,本文从 GATT 核心概念讲起,完成一次完整通信。


一、先搞懂:GATT 到底是什么?

GATT:蓝牙设备之间数据通信的统一规则

1. 层级关系(从上到下)

GATT
└── 服务(Service)
    └── 特征值(Characteristic)
        └── 描述符(Descriptor)
  • Service(服务):功能单元(如电池服务、串口服务、心率服务)
  • Characteristic(特征值):真正用于 读 / 写 / 通知 / 指示 的数据通道
  • Descriptor(描述符):配置通道属性,最关键:CCCD 0x2902(开关 Notify)

2. 关键角色

  • Server(从机 / 外设):发广播、存数据、提供服务(如 ESP32)
  • Client(主机 / 中心设备):扫描、连接、读写数据(如手机)

3. 最常用权限(决定能不能通信)

  • Read / Write / Write Without Response
  • Notify(无应答推送)
  • Indicate(带应答推送,更可靠)
  • Broadcast / Signed Write

4.  理解成一个文件结构

你可以把它理解成:一个文件目录结构手机(客户端)访问设备(服务端)的文件。

GATT 固定结构

设备 (Server)
└── 服务 (Service)     → 一个功能模块(UUID)
     └── 特征值 (Characteristic) → 真正收发数据的地方
          ├── 读 Read
          ├── 写 Write
          ├── 通知 Notify (设备主动发数据给手机)
          └── 描述符 (Descriptor 0x2902) → 开关通知

通俗理解

  • Service = 文件夹
  • Characteristic = 文件
  • Notify = 设备主动把文件推给手机
  • Write = 手机往文件里写数据

二、BLE 通信最核心的 4 件事

  1. 广播 → 让手机能搜到设备
  2. 连接 → 手机与设备建立通信链路
  3. 发现服务 → 手机找到服务与特征值
  4. 收发数据 → 读、写、通知、指示

三、数据收发完整流程(最关键)

设备 → 手机(Notify 主动推送)

  1. 设备启动广播
  2. 手机扫描并连接
  3. 手机打开 0x2902 描述符(通知开关)
  4. 设备调用 Notify 发送数据
  5. 手机成功接收

手机 → 设备(Write 写入)

  1. 手机连接设备
  2. 找到对应特征值
  3. 手机直接执行写操作
  4. 设备收到数据并触发回调

四、最容易踩的 3 个巨坑(99% 人中招)

坑 1:收不到数据

  • 未写 CCCD 0x2902(最常见)
  • 特征值未开启 Notify/Indicate 属性
  • 从机未调用发送函数
  • MTU 不匹配导致分包失败
  • 数据发送过快,队列溢出
  • 连接已断开但上层无感知
  • 主机未注册数据接收回调
  • 加密未完成就开始收发
  • 从机程序崩溃、死机

坑 2:搜不到设备

  • 广播未启动 / 设备未上电
  • 广播间隔过大,手机扫描不到
  • 扫描过滤条件错误(名称 / UUID 不匹配)
  • 设备已被连接,连接后默认停止广播
  • 硬件 PA 关闭、天线异常
  • 手机蓝牙缓存异常
  • 距离过远、遮挡严重
  • 从机进入睡眠,广播暂停
  • 手机未开启定位 / 蓝牙权限

坑 3:配对不上 / 连接失败 / 连接秒断

  • 设备已被其他主机连接
  • 安全参数不匹配(主机要求加密,从机不支持)
  • 绑定信息冲突(清除配对后重试)
  • 连接参数设置极端,导致协议栈崩溃
  • 内存溢出、栈溢出、看门狗复位
  • 供电不足(连接瞬间电流大导致掉电)
  • 配对方式不支持(如从机仅 Just Works,主机强制密码)
  • 服务发现过程中被中断
Logo

智能硬件社区聚焦AI智能硬件技术生态,汇聚嵌入式AI、物联网硬件开发者,打造交流分享平台,同步全国赛事资讯、开展 OPC 核心人才招募,助力技术落地与开发者成长。

更多推荐