Skip to content
This repository has been archived by the owner on Aug 1, 2023. It is now read-only.

Problem with Thermometer #89

Open
aydinakcasu opened this issue Sep 25, 2017 · 4 comments
Open

Problem with Thermometer #89

aydinakcasu opened this issue Sep 25, 2017 · 4 comments

Comments

@aydinakcasu
Copy link

aydinakcasu commented Sep 25, 2017

It appears the logic for the Temperature may be off.
I think the bits for the Centigrade values may need to be shifted by one more:
C Value: Byte 3,4 actual, Byte 3,4 expect
1: Actual 0, 7f, Expect 80, 3f
2: Actual 0, 80, Expect 00, 40
3: Actual 40, 80 , Expect 40, 40

@beaufortfrancois
Copy link
Member

Here's what I'm doing:

private void setTemperatureMeasurementValue(float temperatureMeasurementValue) {
/* Set the org.bluetooth.characteristic.temperature_measurement
* characteristic to a byte array of size 5 so
* we can use setValue(value, format, offset);
*
* Flags (8bit) + Temperature Measurement Value (float) = 5 bytes
*
* Flags:
* Temperature Units Flag (0) -> Celsius
* Time Stamp Flag (0) -> Time Stamp field not present
* Temperature Type Flag (0) -> Temperature Type field not present
* Unused (00000)
*/
mTemperatureMeasurementCharacteristic.setValue(new byte[]{0b00000000, 0, 0, 0, 0});
// Characteristic Value: [flags, 0, 0, 0, 0]
int bits = Float.floatToIntBits(temperatureMeasurementValue);
int exponent = (bits & EXPONENT_MASK) >>> EXPONENT_SHIFT;
int mantissa = (bits & MANTISSA_MASK) >>> MANTISSA_SHIFT;
mTemperatureMeasurementCharacteristic.setValue(mantissa, exponent,
TEMPERATURE_MEASUREMENT_VALUE_FORMAT,
/* offset */ 1);
// Characteristic Value: [flags, temperature measurement value]
}

@aydinakcasu
Copy link
Author

aydinakcasu commented Sep 26, 2017

Upon further investigation, it seems like your logic is correct.
For example, if '1' is the input value,
the internal hex bytes are (https://gregstoll.dyndns.org/~gregstoll/floattohex/):
3f 80

This works out to be:

  • exponent = 7f
  • mantissa = 0
    which matches your code.

On the reading end, if we look at the raw bytes (byte 3,4), we get:
7f 00
We should have:
3f 80
unless we are not storing in standard float formats.
Maybe it is storing bytes directly as exponent, mantissa, which will cause problems down the line.

It appears that maybe 'setValue(mantissa, exponent" is not working correctly.

image

@aydinakcasu
Copy link
Author

aydinakcasu commented Sep 26, 2017

Some more info:
https://android.googlesource.com/platform/frameworks/base.git/+/master/core/java/android/bluetooth/BluetoothGattCharacteristic.java

  1. setValue(int mantissa, int exponent, int formatType, int offset)
    is consistent with what we are seeing.
    It is not storing as a regular float, just the raw bytes of the mantissa, and exponent.

  2. Furthermore, the code for the getFloatValue is odd. It eventually calls bytesToFloat, and uses the wrong logic.

bytesToFloat(mValue[offset], mValue[offset + 1], mValue[offset + 2], mValue[offset + 3]);
It does this to the last parameter (b3):
(mantissa * Math.pow(10, b3))
It seems like it should not be based on powers of 10.

Maybe this is old code.

@akapelrud
Copy link

I know this is an old issue, just commenting for future reference. It seems that BLE uses IEEE 11073 encoded floating numbers, which are based on base-10. So there are 8bits assigned to the exponent and 24bits assigned to the mantissa. No sign bit, as usual; the mantissa is instead signed.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants