ESP IoT Solution BLE Body Composition Service(BCS)GATT 服务示例完全指南 📅 发布时间:2026/9/20 8:44:24 👁 浏览次数: 物联网嵌入式驱动开发硬件开发【免费下载链接】esp-iot-solutionEspressif IoT Library. IoT Device Drivers, Documentations and Solutions.项目地址https://gitcode.com/GitHub_Trending/es/esp-iot-solution点击查看免费下载本文基于 ESP IoT Solution 仓库中的examples/bluetooth/ble_services/ble_bcs示例展开系统讲解如何基于 ESP-IDF 与乐鑫 BLE 连接管理组件ble_conn_mgr实现一个符合蓝牙标准 Body Composition ServiceBCS的 GATT 服务端涵盖服务特性位定义、测量数据结构、工程配置、核心代码流程与运行验证。读完本文你将掌握如何在 ESP32 系列芯片上以最小代码量注册 BCS 服务、下发体成分测量数据并配合任意 BLE 调试 App 完成端到端验证。一、示例概述一个可广播、可被连接的 GATT 服务端ble_bcs示例创建了一个基于 NimBLE 协议栈的 GATT 服务器启动后立即进入广播状态等待 GATT 客户端例如手机上的 BLE 扫描工具连接。当客户端连上后设备会通过 Body Composition Measurement 特征Indication主动向客户端推送一组体成分测量数据客户端也可以读取 Body Composition Feature 特征获取设备支持的测量能力位图。该示例的技术要点有二理解BLE Body Composition Service的协议结构服务 UUID0x181B、特征0x2A9B/0x2A9C掌握BLE 连接管理 APIesp_ble_conn_mgr组件的初始化、注册服务、事件回调与数据下发机制。示例目录结构如下examples/bluetooth/ble_services/ble_bcs/ ├── CMakeLists.txt ├── README.md ├── main/ │ ├── CMakeLists.txt │ ├── Kconfig.projbuild # 示例级配置项广播名、后续广播数据 │ ├── app_main.c # 主流程与连接事件处理 │ └── idf_component.yml # 组件依赖声明 ├── sdkconfig.defaults # 默认启用 BT / NimBLE / BCS └── sdkconfig.ci.nimble # CI 用 NimBLE 配置二、BCS 服务的协议骨架UUID、特征与标志位2.1 服务与特征 UUIDBCSBody Composition Service是蓝牙 SIG 定义的标准服务其 UUID 与特征定义位于组件头文件 components/bluetooth/ble_services/bcs/include/esp_bcs.h项目UUID说明Body Composition Service0x181B体成分服务Body Composition Feature 特征0x2A9B只读返回设备支持的体成分能力位图Body Composition Measurement 特征0x2A9CIndication主动向客户端上报体成分测量值其中特征值缓冲区的最大长度为BLE_BCS_MAX_VAL_LEN100 字节由 esp_bcs.h 中的宏#define BLE_BCS_MAX_VAL_LEN 100定义。2.2 Feature 特征能力位图位 017Feature 特征用于声明设备支持测量哪些体成分字段在头文件中以BLE_BCS_FEAT_*位掩码定义位宏含义bit0BLE_BCS_FEAT_TIME_STAMP支持时间戳bit1BLE_BCS_FEAT_MULTI_USER支持用户 ID多用户bit2BLE_BCS_FEAT_BASAL_METABOLISM支持基础代谢bit3BLE_BCS_FEAT_MUSCLE_PERCENTAGE支持肌肉百分比bit4BLE_BCS_FEAT_MUSCLE_MASS支持肌肉量bit5BLE_BCS_FEAT_FAT_FREE_MASS支持去脂体重bit6BLE_BCS_FEAT_SOFT_LEAN_MASS支持瘦体重bit7BLE_BCS_FEAT_BODY_WATER_MASS支持身体水分量bit8BLE_BCS_FEAT_IMPEDENCE支持阻抗bit9BLE_BCS_FEAT_WEIGHT支持体重bit10BLE_BCS_FEAT_HEIGHT支持身高bit11~14BLE_BCS_FEAT_MASS_MEASUREMENT_RESOLUTION体重分辨率000未定义0010.5kg/1lb0020.2kg/0.5lb0030.1kg/0.2lb0040.05kg/0.1lb0050.02kg/0.05lb0060.01kg/0.02lb0070.005kg/0.01lbbit15~17BLE_BCS_FEAT_HEIGHT_RESOLUTION身高分辨率000未定义0010.01m/1ft0020.005m/0.5ft0030.001m/0.1ft组件源码 esp_bcs.c 中默认将上述能力全部置位并在每次调用esp_ble_bcs_set_measurement()时根据传入的标志位动态重建该位图。2.3 Measurement 特征测量标志位位 012Measurement 特征以 Indication 方式上报其数据格式由一个 32 位的bcs_flag标志字段打头决定后续携带哪些字段。BLE_BCS_FLAG_*宏定义如下位宏对应字段bit0BLE_BCS_FLAG_MEASUREMENT_UNITS测量单位英制/公制bit1BLE_BCS_FLAG_TIME_STAMP时间戳bit2BLE_BCS_FLAG_MULTI_USER用户 IDbit3BLE_BCS_FLAG_BASAL_METABOLISM基础代谢uint16bit4BLE_BCS_FLAG_MUSCLE_PERCENTAGE肌肉百分比uint16bit5BLE_BCS_FLAG_MUSCLE_MASS肌肉量uint16bit6BLE_BCS_FLAG_FAT_FREE_MASS去脂体重uint16bit7BLE_BCS_FLAG_SOFT_LEAN_MASS瘦体重uint16bit8BLE_BCS_FLAG_BODY_WATER_MASS身体水分量uint16bit9BLE_BCS_FLAG_IMPEDENCE阻抗uint8bit10BLE_BCS_FLAG_WEIGHT体重uint16bit11BLE_BCS_FLAG_HEIGHT身高uint16bit12BLE_BCS_FLAG_MULTIPLE_PACKET多包传输三、测量数据结构esp_bcs_val_t所有可上报的体成分数据被封装为紧凑结构体esp_bcs_val_t见 esp_bcs.htypedef struct { uint32_t bcs_flag; /*! Body Composition flag field */ struct { uint16_t year; /*! 1582 ~ 9999 */ uint8_t month; /*! 1 ~ 12 */ uint8_t day; /*! 1 ~ 31 */ uint8_t hours; /*! 0 ~ 23 */ uint8_t minutes; /*! 0 ~ 59 */ uint8_t seconds; /*! 0 ~ 59 */ } __attribute__((packed)) timestamp; /*! 日期时间 */ uint8_t user_id; /*! 用户 ID */ uint16_t basal_metabolism; /*! 基础代谢 */ uint16_t muscle_percentage; /*! 肌肉百分比 */ uint16_t muscle_mass; /*! 肌肉量 */ uint16_t fat_free_mass; /*! 去脂体重 */ uint16_t soft_lean_mass; /*! 瘦体重 */ uint16_t body_water_mass; /*! 身体水分量 */ uint8_t impedance; /*! 阻抗 */ uint16_t weight; /*! 体重 */ uint16_t height; /*! 身高 */ } __attribute__((packed)) esp_bcs_val_t;结构体使用__attribute__((packed))紧凑排布保证字段在内存中连续存放便于后续按蓝牙规范逐字段打包进 ATT 报文。四、硬件要求与支持目标一块搭载ESP32 / ESP32-C3 / ESP32-C2 / ESP32-S3SoC 的开发板本项目源码同时在 CI 中覆盖 ESP32-H2一根 USB 数据线用于供电与程序烧录一台可运行 BLE 扫描工具如 nRF Connect、LightBlue的手机或 PC充当 GATT 客户端。五、快速开始构建、配置与烧录5.1 设置芯片目标构建前必须先用set-target指定目标芯片idf.py set-target chip_namechip_name需替换为实际芯片型号例如esp32c3、esp32s3等。5.2 工程配置打开配置菜单idf.py menuconfig需要关注两个菜单Example Configuration示例配置Advertisement name设备广播名默认BLE_BCSSubsequent advertisement data后续广播数据默认SUB_ADV。BLE Standard ServicesBLE 标准服务GATT Body Composition Service对应CONFIG_BLE_BCS是否使能 BCS 服务默认关闭需手动打开。在BLE Standard Services下使能 BCS 后还会出现子项Body Composition Feature IndicationCONFIG_BLE_BCS_FEATURE_INDICATE_ENABLE默认y用于决定 Feature 特征是否同时支持 Indication 属性。该配置项定义于组件级 Kconfig components/bluetooth/ble_services/bcs/Kconfig.in。示例自身的 Kconfig 位于 main/Kconfig.projbuild两个字符串配置项均提供了help说明前者是广播中携带的设备名后者是后续广播中携带的数据。5.3 默认使能的依赖项仓库已通过 sdkconfig.defaults 预置了以下关键配置保证开箱即用CONFIG_BT_ENABLEDy # 使能蓝牙控制器 CONFIG_BT_NIMBLE_ENABLEDy # 使用 NimBLE 主机协议栈 CONFIG_BLE_CONN_MGR_ROLE_PERIPHERALy # 连接管理组件以外设Peripheral角色运行 CONFIG_BLE_BCSy # 使能 BCS 服务另外 sdkconfig.ci.nimble 用于 CI 环境显式声明使用 NimBLE。组件依赖关系在 main/idf_component.yml 中声明需要ble_conn_mgr~1.*与ble_services~1.*两个组件并通过override_path指向仓库内本地的 components/bluetooth/ble_conn_mgr 与 components/bluetooth/ble_services 目录。5.4 编译、烧录与监视idf.py -p PORT flash monitor其中PORT为开发板的串口设备如/dev/ttyUSB0。烧录后串口监视器会实时打印日志按Ctrl-]退出监视器。首次编译时 ESP-IDF 会自动通过包管理器拉取ble_conn_mgr、ble_services两个依赖组件。六、代码剖析主流程与连接事件示例主程序 main/app_main.c 的启动流程可归纳为五步初始化 NVS调用nvs_flash_init()若返回ESP_ERR_NVS_NO_FREE_PAGES或ESP_ERR_NVS_NEW_VERSION_FOUND则先nvs_flash_erase()再重新初始化蓝牙地址等参数存储在 NVS。创建默认事件循环esp_event_loop_create_default()。注册连接事件回调在BLE_CONN_MGR_EVENTS事件基类上注册app_ble_conn_event_handler监听连接管理组件广播的事件。初始化并注册服务esp_ble_conn_init(config)以广播名CONFIG_EXAMPLE_BLE_ADV_NAME与后续广播数据CONFIG_EXAMPLE_BLE_SUB_ADV初始化连接管理esp_ble_bcs_init()向 GATT 表注册 BCS 服务与特征。启动广播esp_ble_conn_start()失败时依次执行stop/deinit/ 注销事件回调。连接事件处理器是数据下发的关键。当收到ESP_BLE_CONN_EVENT_CONNECTED事件时示例构造一份完整的esp_bcs_val_t测量数据并调用esp_ble_bcs_set_measurement(bcs_val, true)将need_send置为true从而在连接建立后立即向客户端推送一次 Indicationesp_bcs_val_t bcs_val { .bcs_flag BLE_BCS_FLAG_TIME_STAMP | BLE_BCS_FLAG_MULTI_USER | BLE_BCS_FLAG_BASAL_METABOLISM | BLE_BCS_FLAG_MUSCLE_PERCENTAGE | BLE_BCS_FLAG_MUSCLE_MASS | BLE_BCS_FLAG_FAT_FREE_MASS | BLE_BCS_FLAG_SOFT_LEAN_MASS | BLE_BCS_FLAG_BODY_WATER_MASS | BLE_BCS_FLAG_IMPEDENCE | BLE_BCS_FLAG_WEIGHT | BLE_BCS_FLAG_HEIGHT, .timestamp.year 2024, .timestamp.month 11, .timestamp.day 5, .timestamp.hours 15, .timestamp.minutes 15, .timestamp.seconds 6, .user_id 1, .basal_metabolism 0x01, .muscle_percentage 0x02, .muscle_mass 0x03, .fat_free_mass 0x04, .soft_lean_mass 0x05, .body_water_mass 0x06, .impedance 0x01, .weight 0x42, .height 0x33 };ESP_BLE_CONN_EVENT_DISCONNECTED事件当前仅打印日志可用于后续实现重连或低功耗逻辑。七、组件源码级解析数据打包与服务注册7.1 测量值的 AT 报文构建esp_ble_bcs_set_measurement()在 esp_bcs.c 中实现其核心逻辑分两步重建 Feature 位图依据传入bcs_flag中置位的标志将对应的BLE_BCS_FEAT_*能力位重新写入全局变量body_composition_feature从而让后续客户端读取 Feature 特征时拿到与当前数据一致的能力声明打包 Measurement 数据调用内部函数build_bcs_ind_buf()按蓝牙规范将bcs_flag4 字节与各置位字段依序memcpy进indicate_buf_t缓冲区len 最大 100 字节的buf。字段顺序固定为时间戳6 字节→ 用户 ID1 字节→ 基础代谢/肌肉百分比/肌肉量/去脂体重/瘦体重/身体水分量各 2 字节→ 阻抗1 字节→ 体重/身高各 2 字节与 esp_bcs.h 中的标志位定义一一对应。打包完成后若need_send true且启用了CONFIG_BLE_BCS_FEATURE_INDICATE_ENABLE则构造esp_ble_conn_data_t16 位 UUID 类型、UUID 为BLE_BCS_CHR_UUID16_MEASUREMENT并调用esp_ble_conn_write()下发 Indication。7.2 特征注册与回调服务注册通过一张特征查找表完成esp_bcs.cfeature0x2A9B属性为BLE_CONN_GATT_CHR_READ使能 Indication 时追加BLE_CONN_GATT_CHR_INDICATE关联读回调bcs_feature_cb——该回调在客户端读取时动态calloc分配缓冲区将body_composition_feature位图拷回并设置ESP_IOT_ATT_SUCCESS状态异常分支返回ESP_IOT_ATT_INTERNAL_ERROR/ESP_IOT_ATT_INSUF_RESOURCE。measurement0x2A9C属性为BLE_CONN_GATT_CHR_INDICATE无读回调数据仅由esp_ble_bcs_set_measurement()触发下发。随后esp_ble_bcs_init()仅需一行调用esp_ble_conn_add_svc(svc)即可将整个 BCS 服务挂载到 GATT 表——服务与特征的注册细节全部由 ble_conn_mgr 组件托管这也是该示例代码量极小的原因。八、预期运行输出将示例烧录并连接客户端后串口输出类似如下NimBLE 协议栈版本与 MAC 地址因环境而异I (330) BLE_INIT: BT controller compile version [9359a4d] I (340) system_api: Base MAC address is not set I (340) system_api: read default base MAC address from EFUSE I (350) BLE_INIT: Bluetooth MAC: 58:cf:79:1e:9e:de I (350) phy_init: phy_version 1150,7c3c08f,Jan 24 2024,17:32:21 I (420) blecm_nimble: BLE Host Task Started I (420) blecm_nimble: No characteristic(0x2a00) found I (420) blecm_nimble: No characteristic(0x2a01) found I (420) blecm_nimble: No characteristic(0x2a05) found I (430) NimBLE: GAP procedure initiated: stop advertising. I (440) NimBLE: GAP procedure initiated: advertise; I (440) NimBLE: disc_mode2 I (450) NimBLE: adv_channel_map0 own_addr_type0 adv_filter_policy0 adv_itvl_min256 adv_itvl_max256 I (460) NimBLE: I (460) main_task: Returned from app_main()日志中No characteristic(0x2a00) found等行表示连接管理组件在广播名对应特征Device Name、Appearance、Service Changed 等未注册时的正常提示不影响 BCS 功能GAP procedure initiated: advertise表示设备已进入广播状态此时即可用 BLE 扫描 App 搜到名为BLE_BCS的设备并连接。九、验证方法与延伸阅读端到端验证使用任意 BLE 扫描 App 连接设备读取0x2A9BFeature应看到能力位图订阅0x2A9CMeasurement的 Indication 后重新连接或触发数据下发即可收到体成分测量报文。连接管理 APIesp_ble_conn_init、esp_ble_conn_start、esp_ble_conn_add_svc、esp_ble_conn_write等接口的完整定义见 components/bluetooth/ble_conn_mgr/include/esp_ble_conn_mgr.h。同系列示例本仓库 examples/bluetooth/ble_services 目录下还包含 ans、bas、cts、dis、hrs、hts、ias、midi、ota、ots、tps、uds、wss 等标准服务示例均采用相同的 ble_conn_mgr 架构可作为扩展参考。构建前提本示例需要 ESP-IDF依赖声明要求idf: 4.3与支持组件管理器的版本首次构建请确保能访问组件仓库以拉取ble_conn_mgr与ble_services依赖。赞分享物联网嵌入式驱动开发硬件开发【免费下载链接】esp-iot-solutionEspressif IoT Library. IoT Device Drivers, Documentations and Solutions.项目地址https://gitcode.com/GitHub_Trending/es/esp-iot-solution点击查看免费下载相关推荐esp-iot-solution 蓝牙体成分服务BLE BCS开发指南从 GATT 特性设计到示例集成esp iot solution 蓝牙体成分服务BLE BCS开发指南从 GATT 特性设计到示例集成 导读 本文基于 Espressif esp iot物联网嵌入式驱动开发硬件开发ESP IoT Solution 实战基于 esp-iot-solution 的 BLE 健康温度计服务HTSGATT 服务端示例详解ESP IoT Solution 实战基于 esp iot solution 的 BLE 健康温度计服务HTSGATT 服务端示例详解 导读 本指南围绕物联网嵌入式驱动开发硬件开发ESP IoT Solution 蓝牙人体成分服务BLE BCS开发指南从 GATT 服务实现到指示上报实战ESP IoT Solution 蓝牙人体成分服务BLE BCS开发指南从 GATT 服务实现到指示上报实战 本文基于 esp iot solution物联网嵌入式驱动开发硬件开发创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考