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

问题描述 投票:0回答:2

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

插件:

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

当我连接到虚拟自行车训练器时,我选择 0x1818 服务,然后订阅 0x2A63 特征以进行自行车功率测量。

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

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

0x3418 = 11010000011000

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

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

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

这张截图是当我停止骑车但踏板和车轮仍在转动时。

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

我的问题是:

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

bluetooth dart flutter bluetooth-lowenergy
2个回答
4
投票

基于蓝牙 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

第 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

然后从第 3.55.2 节开始,您可以根据标志查看位列表: 即时功率是字节2和字节3

(Dec) 0040 == 00000000 00101000 == 40w

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

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

Dec (2958)

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

Cumulative Wheel Revolutions - 4 bytes
Last Wheel Event Time - 2 bytes

就像您提到的,该训练器不提供节奏服务,因此您看不到标志字段(位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);
}

0
投票

你终于找到适合自己特点的flutter找回力量和节奏的方法了吗? 最好的问候

最新问题
© www.soinside.com 2019 - 2024. All rights reserved.