You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

BLE FTMS服务在Python中无法发现,但nrfconnect App可正常识别

问题:ESP32实现的FTMS服务在Bleak中无法识别,nRF Connect正常

我基于ESP32实现了**FTMS(Fitness Machine Service)**蓝牙服务,在nRF Connect App中可以正常发现并识别该服务,但使用Python的Bleak库编写扫描/连接脚本后,无法检测到FTMS服务,反而出现未知的无效服务条目,仅前两个自定义服务能被正常识别。

相关代码

ESP32 FTMS服务核心实现代码

#include <BLEDevice.h>
#include <BLEServer.h>
#include <BLEUtils.h>
#include <BLE2902.h>

// 自定义服务UUID
static BLEUUID service1UUID("4fafc201-1fb5-459e-8fcc-c5c9c331914b");
static BLEUUID service2UUID("0000ffe0-0000-1000-8000-00805f9b34fb");
// FTMS服务UUID
static BLEUUID ftmsServiceUUID("00001826-0000-1000-8000-00805f9b34fb");

BLEServer* pServer = NULL;

void setup() {
  Serial.begin(115200);

  BLEDevice::init("ESP32-FTMS");
  pServer = BLEDevice::createServer();

  // 创建自定义服务1
  BLEService* pService1 = pServer->createService(service1UUID);
  BLECharacteristic* pChar1 = pService1->createCharacteristic(
                                      "beb5483e-36e1-4688-b7f5-ea07361b26a8",
                                      BLECharacteristic::PROPERTY_READ |
                                      BLECharacteristic::PROPERTY_WRITE
                                    );
  pChar1->setValue("Service 1 Data");
  pService1->start();

  // 创建自定义服务2
  BLEService* pService2 = pServer->createService(service2UUID);
  BLECharacteristic* pChar2 = pService2->createCharacteristic(
                                      "0000ffe1-0000-1000-8000-00805f9b34fb",
                                      BLECharacteristic::PROPERTY_NOTIFY
                                    );
  pChar2->setValue("Service 2 Notify");
  pService2->start();

  // 创建FTMS服务
  BLEService* pFtmsService = pServer->createService(ftmsServiceUUID);
  // 添加FTMS标准特征(示例:健身机器特征)
  BLECharacteristic* pFtmsChar = pFtmsService->createCharacteristic(
                                      "00002ad2-0000-1000-8000-00805f9b34fb",
                                      BLECharacteristic::PROPERTY_READ |
                                      BLECharacteristic::PROPERTY_NOTIFY
                                    );
  pFtmsChar->setValue("FTMS Data");
  pFtmsService->start();

  // 启动广播
  BLEAdvertising* pAdvertising = BLEDevice::getAdvertising();
  pAdvertising->addServiceUUID(service1UUID);
  pAdvertising->addServiceUUID(service2UUID);
  pAdvertising->addServiceUUID(ftmsServiceUUID);
  pAdvertising->setScanResponse(true);
  pAdvertising->start();
  Serial.println("FTMS服务已启动,等待连接...");
}

void loop() {
  delay(1000);
}

Python Bleak扫描与连接代码

import asyncio
from bleak import BleakScanner, BleakClient

DEVICE_NAME = "ESP32-FTMS"

async def scan_and_connect():
    # 扫描设备
    devices = await BleakScanner.discover()
    target_device = None
    for d in devices:
        if d.name == DEVICE_NAME:
            target_device = d
            print(f"找到目标设备: {d.name}, MAC: {d.address}")
            print(f"扫描到的服务UUIDs: {d.metadata.get('uuids', [])}")
            break
    
    if not target_device:
        print("未找到目标设备")
        return
    
    # 连接设备并读取服务
    async with BleakClient(target_device.address) as client:
        print(f"已连接设备: {client.is_connected}")
        services = await client.get_services()
        print("\n设备服务列表:")
        for service in services:
            print(f"服务UUID: {service.uuid}, 服务名称: {service.description or '未知服务'}")

if __name__ == "__main__":
    asyncio.run(scan_and_connect())

运行结果对比

nRF Connect App识别结果

nRF Connect App中正常显示FTMS服务的截图

截图显示:设备广播中包含FTMS服务(UUID 0x1826),连接后可查看完整的FTMS服务及特征。

Python Bleak运行结果

Bleak脚本检测到未知服务的截图

截图显示:扫描到的服务列表中,前两个自定义服务正常显示,第三个服务为未知UUID(格式异常),无FTMS服务条目。

可能的原因及解决方案

  • UUID格式兼容性问题:
    Bleak对BLE UUID的解析对格式敏感,ESP32中若混用16位和128位UUID,可能导致Bleak无法正确映射。确保FTMS服务在ESP32代码中使用完整128位UUID声明,而非仅16位缩写。
  • 广播数据未正确包含FTMS UUID:
    检查ESP32广播设置,确认FTMS服务UUID已被添加到广播数据中。部分情况下,Bleak依赖广播中的服务UUID来识别服务,若广播未包含,可能需要在扫描时显式指定UUID过滤:
    devices = await BleakScanner.discover(service_uuids=["00001826-0000-1000-8000-00805f9b34fb"])
    
  • Bleak版本问题:
    不同版本的Bleak对BLE服务的解析逻辑存在差异,尝试升级到最新稳定版(如pip install --upgrade bleak)或降级到已知兼容版本(如0.21.0)。
  • ESP32服务注册冲突:
    检查ESP32代码中是否存在UUID重复、服务未正确启动的情况。可通过在setup()中打印服务注册状态,确认FTMS服务已成功启动。
  • 系统BLE栈兼容性:
    若运行Python脚本的主机(如Windows/macOS/Linux)BLE栈存在解析bug,可尝试在不同系统上测试,或使用BleakScanner的scanning_mode参数调整扫描模式:
    scanner = BleakScanner(scanning_mode="passive")
    devices = await scanner.discover()
    

验证步骤

  1. 在Python脚本中打印扫描到的原始UUID列表,对比ESP32中声明的UUID是否完全一致:
    print(f"原始扫描UUIDs: {target_device.metadata['uuids']}")
    
  2. 在ESP32代码中,确保FTMS服务的所有特征也使用完整128位UUID,避免混用格式。
  3. 尝试在Bleak连接后,直接通过UUID获取FTMS服务:
    ftms_service = client.services.get_service("00001826-0000-1000-8000-00805f9b34fb")
    print(f"是否找到FTMS服务: {ftms_service is not None}")
    

内容的提问来源于stack exchange,提问作者Muhammad Hamza Farooq

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.21 03:11:00