0

I'm trying to parse int and double values which I receive from a bluetooth device using this lib: https://github.com/Polidea/FlutterBleLib

I receive the following Uint8List data: 31,212,243,57,0,224,7,1,6,5,9,21,0,1,0,0,0,91,228

I found some help here: How do I read a 16-bit int from a Uint8List in Dart?

On Android I have done some similar work, but the library there had so called Value Interpreter which I only passed the data and received back float/int.

Example code from Android:

int offset = 0;
final double spOPercentage = ValueInterpreter.getFloatValue(value, FORMAT_SFLOAT, offset);

Where value is a byte array

Another example from android code, this code if from the library:

public static Float getFloatValue(@NonNull byte[] value, int formatType, @IntRange(from = 0L) int offset) {
    if (offset + getTypeLen(formatType) > value.length) {            
        return null;
    } else {
        switch(formatType) {
        case 50:
            return bytesToFloat(value[offset], value[offset + 1]);
        case 52:
            return bytesToFloat(value[offset], value[offset + 1], value[offset + 2], value[offset + 3]);
        default:               
            return null;
        }
    }
}

private static float bytesToFloat(byte b0, byte b1) {
    int mantissa = unsignedToSigned(unsignedByteToInt(b0) + ((unsignedByteToInt(b1) & 15) << 8), 12);
    int exponent = unsignedToSigned(unsignedByteToInt(b1) >> 4, 4);
    return (float)((double)mantissa * Math.pow(10.0D, (double)exponent));
}
private static float bytesToFloat(byte b0, byte b1, byte b2, byte b3) {
    int mantissa = unsignedToSigned(unsignedByteToInt(b0) + (unsignedByteToInt(b1) << 8) + 
        (unsignedByteToInt(b2) << 16), 24);
    return (float)((double)mantissa * Math.pow(10.0D, (double)b3));
}
private static int unsignedByteToInt(byte b) {
    return b & 255;
}

In flutter/dart I want to write my own value interpreter. The starting example code is:

int offset = 1; 
ByteData bytes = list.buffer.asByteData(); 
bytes.getUint16(offset);

I don't understand how data is manipulated here in dart to get a int value from different position from data list. I need some explanation how to do this, would be great if anyone can give some teaching about this.

ChrisMM
  • 8,448
  • 13
  • 29
  • 48
Lokovsek
  • 1
  • 1
  • 2
  • What is your question? For example if you want to get 3 Unsigned integers of 2 bytes, you just need to call the function 3 times incrementing the offset by 2 every time. – Mattia Jan 07 '20 at 16:41
  • I have this Uint8List and the values are: 31, 212, 243, 57, 0, 224, 7, 1, 6, 5, 9, 21, 0, 1, 0, 0, 0, 91, 228 I use the code below ByteData bytes = list.buffer.asByteData(); int offset = 1; double value = bytes.getFloat32(offset); and value that I expected should be something between 50 and 150 More info on what I am doing can be found here: https://www.bluetooth.com/wp-content/uploads/Sitecore-Media-Library/Gatt/Xml/Characteristics/org.bluetooth.characteristic.plx_spot_check_measurement.xml name="SpO2PR-Spot-Check - SpO2" – Lokovsek Jan 10 '20 at 11:16

2 Answers2

4

Having the following:

values [31, 212, 243, 57, 0, 224, 7, 1, 6, 5, 9, 21, 0, 1, 0, 0, 0, 91, 228];
index    0    1    2   3  4    5  6  7  8  9 10  11 12 13 14 15 16  17   18

When you make:

values.list.buffer.asByteData().getUint16(0);

you interpret [31, 212] as a single unsigned int of two bytes length.

If you want to get a Uint16 from bytes 9 and 10 [5, 9], you'd call:

values.list.buffer.asByteData().getUint16(9);

Regarding your comment (Parse int and float values from Uint8List Dart):

I have this Uint8List and the values are: 31, 212, 243, 57, 0, 224, 7, 1, 6, 5, 9, 21, 0, 1, 0, 0, 0, 91, 228 I use the code below ByteData bytes = list.buffer.asByteData(); int offset = 1; double value = bytes.getFloat32(offset); and value that I expected should be something between 50 and 150 More info on what I am doing can be found here: bluetooth.com/wp-content/uploads/Sitecore-Media-Library/Gatt/… name="SpO2PR-Spot-Check - SpO2"

This property is of type SFLOAT, which according to https://www.bluetooth.com/specifications/assigned-numbers/format-types/ looks like this:

0x16 SFLOAT IEEE-11073 16-bit SFLOAT

As Dart does not seem to have an easy way to get that format, you might have to create a parser yourself using raw bytes.

These might be helpful:

https://stackoverflow.com/a/51391743/6413439

https://stackoverflow.com/a/16474957/6413439

2

Here is something that I used to convert sfloat to double in dart for our flutter app.

double sfloat2double(ieee11073) {
    var reservedValues = {
            0x07FE: 'PositiveInfinity',
            0x07FF: 'NaN',
            0x0800: 'NaN',
            0x0801: 'NaN',
            0x0802: 'NegativeInfinity'
        };
    var mantissa = ieee11073 & 0x0FFF;

    
    if (reservedValues.containsKey(mantissa)){
      return 0.0; // basically error
    }
  
    if ((ieee11073 & 0x0800) != 0){
       mantissa =  -((ieee11073 & 0x0FFF) + 1 );
    }else{
      mantissa = (ieee11073 & 0x0FFF);  
    }
    
    var exponent = ieee11073 >> 12;
    if (((ieee11073 >> 12) & 0x8) != 0){
      exponent = -((~(ieee11073 >> 12) & 0x0F) + 1 );
    }else{
      exponent = ((ieee11073 >> 12) & 0x0F); 
    }
    var magnitude = pow(10, exponent);
    return (mantissa * magnitude);  
}
Kiran Ruth R
  • 902
  • 1
  • 11
  • 28