This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Java MSB negative value

If I understand it right, in java you cannot define a value as unsigned int. So the MSB of a Byte will decide, if the value is positive or negative.

But I have to use all 8 Bits of the Byte for the value of the variable.

Does anyone have experience with this, and how is it possible still to send 8 Bit variables?

With the MCP everything is working fine. But it should work the same trough a mobile device.

Is it defined by the BLE protocol, that I must send bytes?

Could I also setup a characteristic to send and recieve floats or double?

What other opportunities do I have?

I tried it to mask with '& 0xFF'

links[1] = (byte) (i & (0xFF));

links[2] = (byte) ((i >> 8) & (0xFF));

links[3] = (byte) ((i >> 16) & (0xFF));

As example I take i = 201600

What I get:

links[1] = -128 (should be 0x80) <---Result is false

links[2] = 19 (should be 0x13) <---Result is right

links[3] = 3 (should be 0x03) <---Result is right

Did I wrong mask, or why its still negative and wrong value?

  • The BLE protocols deal only with raw bytes - or "octets" (ie, groups of 8 bits) - they neither know nor care how your application will interpret them (eg, as "signed" or "unsigned" or whatever).

    As you say, this is a Java issue; nothing to do with BLE (nor Android). And, as you note, others have managed to do it - so, hopefully, someone familiar with Java will be along soon to explain it...

  • I'm not sure I fully understand your question so I'll point out a few things I've learned in dealing with BLE characteristic data for Android:

    1. Java, as you said, does not have the concept of unsigned anything which, for us embedded guys, is extremely annoying. However, from a BLE perspective, you simply have to consider the fact that a negative value interpreted by Java requires 8 bits. It is simply the MSb that makes it negative or positive. As long as all of the bits are there, then the BLE APIs will transfer the correct value. Nothing in the Android BLE API strips off this 'negative marker bit'.

    2. If you need to convert BLE characteristic values of say, 4 bytes, to some other value, then you'll need to do some casting to make sure the value ends up being correct. Here is a code snippet for how I handle this:

      int mTotalBytesSent = ((value[1] & 0xFF) + ((value[2] & 0xFF) << 8) + ((value[3] & 0xFF) << 16) + ((value[4] & 0xFF) << 24));

    The important part in this is the '& 0xFF' mask of the value. I initially did this operation without the mask and received some very strange values.

    1. If you don't want to do it the manual way, Android provides some conversion functions to convert a characteristic's bytes into certain types of values. There are functions such as getIntValue, getFloatValue, and getStringValue. All of these take an offset parameter and the number methods also required a type where you can specify types such as FORMAT_UINT8, FORMAT_UINT32, etc.

    For example:

    int val = someChar.getIntValue(BluetoothGattCharacteristic.FORMAT_UINT32, 0);
    

    Hope this helps,

    Eric

  • If links is a byte array, then it will still be interpreted as a negative value. Try making links an int.

  • You are right it is a byte array with the size of 16 bytes. I will try to add 16 bytes in an int, but I think this will be to much.

  • You should be able to simply declare links with type of int instead of a type byte. It is impossible in Java to represent an 8 bit value > 0x7F as an unsigned value unless you convert it to something with more than 8 bits.

Related