alexdmejias
alexdmejias

Reputation: 1419

Decode bluetooth data from the Indoor Bike Data characteristic

I'm trying to use the Fitness Machine Service + the Indoor Bike Data characteristic to get the cadence data. By using the nRF Connect Android App I can see that the data is there, sample data:

inst. speed  8.5km/h
inst. cadence 45.0 per min
inst. power 8W
Heart rate 0 bpm

//same data as hex 44 02 52 03 5A 00 08 00 00 

Looking at spec for the Indoor Bike Data characteristic it says that the flag field should be encoded as 16bit(spec) but when I try something like,

const characteristic = await char.startNotifications()
characteristic.addEventListener('characteristicvaluechanged', (data) => {
  const flags = data.getUint16(0, true);
    
  console.table([ flags & 0x0,flags & 0x1, flags & 0x2,flags & 0x3, flags & 0x4,flags & 0x5, flags & 0x6,flags & 0x7, flags & 0x8,flags & 0x9, flags & 0x10,flags & 0x11, flags & 0x12,flags & 0x13, flags & 0x14,flags & 0x15, flags & 0x16])
});

which outputs:

enter image description here

The data doesn't match up with the above data from nRF Connect Android. Does anyone know why the data provided and the values in the screenshot don't match up and how I can get the rest of the data?

Upvotes: 2

Views: 1997

Answers (1)

ukBaz
ukBaz

Reputation: 8004

Your bitwise operation on the flags field does not look to be correct.

I have done the following:

var ble_bytes = new Uint8Array([0x44, 0x02, 0x52, 0x03, 0x5A, 0x00, 0x08, 0x00, 0x00]).buffer;
var view = new DataView(ble_bytes)

flags = view.getUint16(0, true);
var i;
for (i = 0; i < 16; i++) {
  console.log('flags[' + i + '] = ' + (!!(flags >>> i & 1)));
}
console.log('Instantaneous Speed = ' + view.getUint16(2, true) / 100)
console.log('Instantaneous Cadence = ' + view.getUint16(4, true) * 0.5)
console.log('Instantaneous Power  = ' + view.getInt16(6, true))
console.log('Heart Rate  = ' + view.getUint8(8, true))

Which gave me the output of:

> "flags[0] = false"
> "flags[1] = false"
> "flags[2] = true"
> "flags[3] = false"
> "flags[4] = false"
> "flags[5] = false"
> "flags[6] = true"
> "flags[7] = false"
> "flags[8] = false"
> "flags[9] = true"
> "flags[10] = false"
> "flags[11] = false"
> "flags[12] = false"
> "flags[13] = false"
> "flags[14] = false"
> "flags[15] = false"
> "Instantaneous Speed = 8.5"
> "Instantaneous Cadence = 45"
> "Instantaneous Power  = 8"
> "Heart Rate  = 0"

Which indicates there is Instantaneous Cadence present, Instantaneous Power present, Heart Rate present. The field Instantaneous Speed is always present.

I've converted the bytes according to that and it seems to match with what you got from the nRF Connect app.

Upvotes: 4

Related Questions