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

如何拆分BLE FTMS室内单车数据为20字节以内的两个数据块

ESP32 BLE FTMS服务分块传输故障排查求助

我首次在ESP32上开发BLE FTMS服务,也是第一个C++项目。目前已经成功创建FTMS服务,能给KinoMap这类训练APP发送数据,但只能处理不超过20字节的数据包。

根据FTMS规范,超过20字节的数据需要拆分为两个数据块,并且要在第一块中设置more data bit告知客户端还有第二块数据。我尝试过用0x01设置这个位,但不确定是否正确。

可正常运行的20字节限制代码

...
byte features[] = {0x07,0x52,0x00,0x00};

void transmitFTMS(double rpm, double avgRpm, double cadence, double avgCadence, double kph, double avgKph, double power, double avgPower, 
                  double runningDistance, double runningCalories, unsigned long elapsedTime)
{
    uint16_t transmittedKph        = (uint16_t) (kph * 100);         //(0.01 resolution)
    uint16_t transmittedTime       = (uint16_t) (elapsedTime / 1000);//(1.0 resolution)
    uint16_t transmittedAvgKph     = (uint16_t) (avgKph * 100);      //(0.01 resolution)
    uint16_t transmittedRpm        = (uint16_t) (rpm * 2);           //(0.5 resolution)
    uint16_t transmittedAvgRpm     = (uint16_t) (avgRpm * 2);         //(0.1 resolution)
    uint16_t transmittedCadence    = (uint16_t) (cadence * 2);
    uint16_t transmittedAvgCadence = (uint16_t) (avgCadence * 2);
    uint16_t transmittedPower      = (uint16_t) (power * 2);      //(1.0 resolution)
    uint16_t transmittedAvgPower   = (uint16_t) (avgPower * 2);        //(1.0 resolution)
    uint32_t transmittedDistance   = (uint32_t) (runningDistance * 1000);// runningDistance in km, need m 
    uint16_t transmittedTotalCal   = (uint16_t) (runningCalories * 10);                   //(1.0 resolution)
    uint16_t transmittedCalHr      = (uint16_t) (runningCalories * 60 * 60 / elapsedTime);//(1.0 resolution) 
    uint8_t transmittedCalMin      = (uint8_t)  (runningCalories * 60 / elapsedTime);     //(1.0 resolution)
    
    bool disconnecting = !deviceConnected && oldDeviceConnected;
    bool connecting = deviceConnected && !oldDeviceConnected;
    
    byte bikeData[20]={0x56,0x09,
                    (uint8_t)transmittedKph,        (uint8_t)(transmittedKph >> 8),
                    (uint8_t)transmittedAvgKph,     (uint8_t)(transmittedAvgKph >> 8),
                    (uint8_t)transmittedCadence,    (uint8_t)(transmittedCadence >> 8),
                    (uint8_t)transmittedDistance,   (uint8_t)(transmittedDistance >> 8),
                    (uint8_t)(transmittedDistance >> 16),        
                    (uint8_t)transmittedPower,      (uint8_t)(transmittedPower >> 8),                   
                    (uint8_t)transmittedTotalCal,   (uint8_t)(transmittedTotalCal >> 8),                    
                    (uint8_t)transmittedCalHr,      (uint8_t)(transmittedCalHr >> 8),                    
                    transmittedCalMin,
                    (uint8_t)transmittedTime,      (uint8_t)(transmittedTime >> 8)
      };
    if (deviceConnected)
    {
        indoorBikeDataCharacteristic->setValue((uint8_t *)&bikeData, 20);
        indoorBikeDataCharacteristic->notify();
    }
...

修改后的分块传输代码

...
    byte bikeData1[20]={0x56,0x09,
                    (uint8_t)transmittedKph,        (uint8_t)(transmittedKph >> 8),
                    (uint8_t)transmittedAvgKph,     (uint8_t)(transmittedAvgKph >> 8),
                    (uint8_t)transmittedCadence,    (uint8_t)(transmittedCadence >> 8),
                    (uint8_t)transmittedRpm,        (uint8_t)(transmittedRpm >> 8),
                    (uint8_t)transmittedAvgRpm,     (uint8_t)(transmittedAvgRpm >> 8),
                    (uint8_t)transmittedAvgCadence, (uint8_t)(transmittedAvgCadence >> 8),
                    (uint8_t)transmittedDistance,   (uint8_t)(transmittedDistance >> 8),
                    (uint8_t)(transmittedDistance >> 16),        
                    (uint8_t)transmittedPower,      (uint8_t)(transmittedPower >> 8),
                    0x01
    };
    byte bikeData2[9]={
                    (uint8_t)transmittedAvgPower,   (uint8_t)(transmittedAvgPower >> 8),
                    (uint8_t)transmittedTotalCal,   (uint8_t)(transmittedTotalCal >> 8),                    
                    (uint8_t)transmittedCalHr,      (uint8_t)(transmittedCalHr >> 8),                    
                    transmittedCalMin,
                    (uint8_t)transmittedTime,      (uint8_t)(transmittedTime >> 8)
      };
    if (deviceConnected)
    {
        indoorBikeDataCharacteristic->setValue((uint8_t *)&bikeData1, 20);
        indoorBikeDataCharacteristic->notify();

        indoorBikeDataCharacteristic->setValue((uint8_t *)&bikeData2, 9);
        indoorBikeDataCharacteristic->notify();
    }
...

当前问题

修改分块传输代码后,客户端APP无法处理传输的数据。我已经花了3周时间尝试调整数据顺序、修改分块内容,但都没有解决问题,也不知道该如何调试。希望能得到排查方向的指引。

内容的提问来源于stack exchange,提问作者Damn

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 16:07:02