了解循环功率测量的 BLE 特征值 0x2A63

Yon*_*kee 5 bluetooth dart bluetooth-lowenergy flutter

我目前正在使用 Dart/Flutter BLE 插件来更好地了解 BLE 设备。

插入:

https://pub.dartlang.org/packages/flutter_blue

当我连接到虚拟循环训练器时,我选择 0x1818 服务,然后订阅循环功率测量的 0x2A63 特征。

我正在努力将我得到的响应列表与下面针对此服务/特性的 GATT 文档进行调整。该列表中有 18 个值,但 GATTS 列表中只有 17 个。而且这些价值观似乎没有任何意义。

我还尝试将前两个值“52”、“24”转换为 16 位二进制,看看它是否与第一个字段的标志对齐,但结果如下,这又没有意义。

0x3418 = 11010000011000
Run Code Online (Sandbox Code Playgroud)

https://www.bluetooth.com/specifications/gatt/viewer?attributeXmlFile=org.bluetooth.characteristic.cycling_power_measurement.xml

这是我第一次连接到训练器时的屏幕截图。

在此输入图像描述

这个截图是我骑着自行车轻骑时的

在此输入图像描述

此屏幕截图是当我停止骑车但踏板和车轮仍在转动时的屏幕截图。

在此输入图像描述

自行车训练器是Cycleops Magnus,它没有Cycle Speed Cadence服务1816,但可以提供基于功率的虚拟速度。

我的问题是这样的:

列表中与 GATTS 特征和奖励问题相对应的值是,我如何从该服务中的值推断速度或节奏?

app*_*p4g 5

基于蓝牙 GATT 规范第 3.55 节:

DEC - [52,24,40,0,58,29,59,0,0,0,107,136,23, 0,214, 81, 1,0]
BIT -   0  1  2 3  4  5  6 7 8 9  10  11 12 13  14  15 16 17 
Flag field = 24,52 (bit0 and bit1)

2452 = 00001001 10010100
Run Code Online (Sandbox Code Playgroud)

第 3.55.2.1 节相应的 (1) 等于

- bit2  = Accumulated Torque Present 
- bit4  = Wheel Revolution Data Present
- bit7  = Extreme Torque Magnitudes Present
- bit8  = Extreme Angles Present
- bit11 = Accumulated Energy Present
Run Code Online (Sandbox Code Playgroud)

然后从第 3.55.2 节开始,根据标志向下查看位列表: 即时功率为 bytes2 和 bytes3

(Dec) 0040 == 00000000 00101000 == 40w
Run Code Online (Sandbox Code Playgroud)

为了破译其余的位,我们必须参考标志字段,因为标志字段和即时功率之后的剩余位必须取决于标志字段表示训练器支持的内容。

基于标志字段的位 2,表示“存在累积扭矩”(如果标志字段的位 2 设置为 1,则存在)因此接下来的 2 个字节表示累积扭矩

Dec (2958)
Run Code Online (Sandbox Code Playgroud)

然后,下一个数据将基于标志字段的位 4 - 车轮转速数据存在(如果标志字段的位 4 设置为 1,则存在)。这是车轮速度,一旦考虑到车轮周长,就会转化为速度。对于车轮转速数据,由接下来的 6 位表示。

Cumulative Wheel Revolutions - 4 bytes
Last Wheel Event Time - 2 bytes
Run Code Online (Sandbox Code Playgroud)

正如您提到的,该训练器不提供节奏服务,因此您看不到标志字段(位 5)为 1。因此您无法从该数据集中推断节奏。

对于车轮速度,您可以根据 Cum Wheel Rev 和 Last Wheel Event Time 对 6 位数据进行解码。我无法为您提供有关如何解码 6 位的代码,因为您正在使用 flutter,而且我没有 flutter 语言的经验。(我使用 Swift)但可能可以查看 GoldenCheetah 的这段代码并进行相应的转换。

BT40Device::getWheelRpm(QDataStream& ds)
{
    quint32 wheelrevs;
    quint16 wheeltime;
    ds >> wheelrevs;
    ds >> wheeltime;

    double rpm = 0.0;

    if(!prevWheelStaleness) {
        quint16 time = wheeltime - prevWheelTime;
        quint32 revs = wheelrevs - prevWheelRevs;
        // Power sensor uses 1/2048 second time base and CSC sensor 1/1024
        if (time) rpm = (has_power ? 2048 : 1024)*60*revs / double(time);
    }
    else prevWheelStaleness = false;

    prevWheelRevs = wheelrevs;
    prevWheelTime = wheeltime;
    dynamic_cast<BT40Controller*>(parent)->setWheelRpm(rpm);
}
Run Code Online (Sandbox Code Playgroud)

  • 您在解释中混合了位和字节,使其非常难以阅读:) (3认同)