How to send Hex string as a unsigned byte[] to BLE characteristic? - android

byte bytes[] = {0x04,0x08,0x0F,0x66,(byte)0x99,0x41,0x52,0x43,0x55,(byte)0xAA};
ch.setValue(bytes);
If I log the output of this array I get (note the negative values):
[4, 8, 15, 102, -103, 65, 82, 67, 85, -86]
But in theory this should only be java's representation of the values and shouldn't affect the perceived values when they hit the Bluetooth device but this doesn't seem to be the case
These values are required by the manufacturer so cannot be changed, however, 2 of the values are out of the range of an unsigned byte/int and it appears that this is the reason the device isn't recognizing the command.
When I write this command to the characteristic I get a success. But the device doesn't act upon the command.
So, my question is, am I sending this in the correct way, or should I be formatting/processing the byte array in order to maintain the perceived values contained within?
Any advice greatly appreciated!!!

Related

How to parse and only get the EPC data from UHF tag?

I am using bluetooth low enery (BLE) method to read UHF passive tags.
The reading of tags works fine. I am just not sure how to separate the other information and only obtain the "EPC" data.
For example, the EPC data of the tag is 2b00.
I get this List<int> when I read it.
[1, 0, 70, 246, 170, 18, 0, 0, 9, 0, 2, 43, 0, 8, 0, 1, 1, 69, 234, 89]
Then, I convert it to Hex:
String dataHex = hex.encode(data);
print(dataHex); // gives me: '010046f6aa1200000900022b000800010145ea59'
As we can see the EPC data 2b00 is shown within the String. Now I am not sure what the rest of the information is exactly about, could be the CRC ,TID & user data.
Could someone point me in the right direction on how to separate and isolate these values from the hex string, please?

BLE Heart Rate Senser Value Interpretation

I have an Android App where I get Heart Rate Measurements from a Polar H10 Device.
I'm totally lost on how to interpret the heart rate. Various links to the bluetooth.com site are resulting in 404 errors unfortunately.
The characteristics value is i.e.
[16, 59, 83, 4]
From what I understood the second byte (59) is the heart rate in BPM. But this does not seem to be decimal as the value goes up to 127 and then goes on -127, -126, -125, ... It is not hex either.
I tried (in kotlin)
characteristic.value[1].toUInt()
characteristic.value[1].toInt()
characteristic.value[1].toShort()
characteristic.value[1].toULong()
characteristic.value[1].toDouble()
All values freak out as soon as the -127 appears.
Do I have to convert the 59 to binary (59=111011) and see it in there? Please give me some insight.
### Edit (12th April 2021) ###
What I do to get those values is a BluetoothDevice.connectGatt().
Then hold the GATT.
In order to get heart rate values I look for
Service 0x180d and its
characteristic 0x2a37 and its only
descriptor 0x2902.
Then I enable notifications by setting 0x01 on the descriptor. I then get ongoing events in the GattClientCallback.onCharacteristicChanged() callback. I will add a screenshot below with all data.
From what I understood the response should be 6 bytes long instead of 4, right? What am I doing wrong?
On the picture you see the characteristic on the very top. It is linked to the service 180d and the characteristic holds the value with 4 bytes on the bottom.
See Heart Rate Value in BLE for the links to the documents. As in that answer, here's the decode:
Byte 0 - Flags: 16 (0001 0000)
Bits are numbered from LSB (0) to MSB (7).
Bit 0 - Heart Rate Value Format: 0 => UINT8 beats per minute
Bit 1-2 - Sensor Contact Status: 00 => Not supported or detected
Bit 3 - Energy Expended Status: 0 => No Present
Bit 4 - RR-Interval: 1 => One or more values are present
So the first byte is a heart rate in UInt8 format, and the next two bytes are an RR interval.
To read this in Kotlin:
characteristic.getIntValue(FORMAT_UINT8, 1)
This return a heart rate of 56 bpm.
And ignore the other two bytes unless you want the RR.
It seems I found a way by retrieving the value as follows
val hearRateDecimal = characteristic.getIntValue(BluetoothGattCharacteristic.FORMAT_UINT8, 1)
2 things are important
first - the format of UINT8 (although I don't know when to use UINT8 and when UINT16. Actually I thought I need to use UINT16 as the first byte is actually 16 (see the question above)
second - the offset parameter 1
What I now get is an Integer even beyond 127 -> 127, 128, 129, 130, ...

Meaning of values from Audiorecord.read()

I am trying to understand what do the values obtained with Audiorecord.read() actually mean.
I am trying to create an app that will start recording sound when it will detect an impulse reponse (therefore I have though to set a treshold in which any sound above it will be considered an impulse).
The problem is that I donĀ“t really know what do the values stored in "data" represent when I call this method:
read = recorder.read(data, 0, bufferSize);
These are some of the values that I obtain:
[96, 2, 101, 3, 101, 2, 110, 1, -41, 2, -80, 2, -117, 2, 119, 2, -94, 0 .........]
The idea is to set the treshold from these values but firstly I need to know what do they represent.
Can you guys help me with this?
The data depends on the parameters you sent to the constructor. AudioRecord (int audioSource, int sampleRateInHz, int channelConfig, int audioFormat, int bufferSizeInBytes)
sampleRateInHz is the number of samples per second. channel config is either MONO or STEREO meaning 1 or 2 channels. format is PCM8 or PCM16 meaning 8 bits or 16 bits per sample.
So the data is an array of samples. Each sample is an array of channels. Each channel is going to have an 8 or 16 bit value, depending on what you asked for. No data will be skipped, it will always be a fixed size format.
So if you chose 1 channel and 8 bits, each byte is a single sound heard, and you should see sampleRateInHz sounds per second. If you choose 16 bits, each sound is 2 bytes long. If you use 2 channels, it should go in order channel 1 then channel 2 for each sample.
The individual values are the amplitude of the sound data when sampled at the requested frequency. See http://en.wikipedia.org/wiki/Pulse-code_modulation for more information on how it works.

Compute the power consumption(mW) of an Android/iPhone app

I want to calculate and show in a plot the power consumption of my app over the time. The x axis is the time (hours) and the y axis the power consumption in mW.
I have the discharge values for my application (100, 93, 82, 78, 71, 64, 59, 49, 41) that correspond to initial charge, 1h, 2h... The battery of the smartphone is 3.7V and 1850mAh. I calculated the power consumption the same way:
cons(W) = voltage (V) * discharge amount (%) * capacity (mAh) / discharge time (h)
cons (W) = 3.7V * 1.85 Ah * [100, 93, 82, 78, 71, 64, 59, 49, 41] / [0.1 1 2 3 4 5 6 7 8 ]
Is that correct? I know there is a way to directly obtain the values I need but I want to compare several apps and I don't have time to compute the values again. So, based on the previous calculation, What I am doing wrong? I am obtaining values too large. Any suggestion?
Android and iOS have the possibility to show power consumption on a per-app basis.
At least Android should support API calls, to access these values.
(These calculations are more valid then just using battery drain, still not perfect. [i.e. they use processor time, readout of sensor-values, ...])
possible duplicate: https://stackoverflow.com/questions/23428675/android-to-check-battery-stats-per-application

How do you send an extended-ascii AT-command (CCh) from Android bluetooth to a serial device?

This one really has me banging my head. I'm sending alphanumeric data from an Android app, through the BluetoothChatService, to a serial bluetooth adaptor connected to the serial input of a radio transceiver.
Everything works fine except when I try to configure the radio on-the-fly with its AT-commands. The AT+++ (enter command mode) is received OK, but the problem comes with the extended-ascii characters in the next two commands: Changing the radio destination address (which is what I'm trying to do) requires CCh 10h (plus 3 hex radio address bytes), and exiting the command mode requires CCh ATO.
I know the radio can be configured OK because I've done it on an earlier prototype with the serial commands from PIC basic, and it also can be configured by entering the commands directly from hyperterm. Both these methods somehow convert that pesky CCh into a form the radio understands.
I've have tried just about everything an Android noob could possibly come up with to finagle the encoding such as:
private void command_address() {
byte[] addrArray = {(byte) 0xCC, 16, 36, 65, 21, 13};
CharSequence addrvalues = EncodingUtils.getString(addrArray, "UTF-8");
sendMessage((String) addrvalues);
}
but no matter what, I can't seem to get that high-order byte (CCh/204/-52) to behave as it should. All other (< 127) bytes, command or data, transmit with no problem. Any help here would be greatly appreciated.
-Dave
Welll ... turns out the BluetoothChat code re-creates the byte array with message.getBytes() before sending to the service. (after all, being chat code it would normally source only regular ascii strings) As others on this site have pointed out, getBytes() can create encoding issues in some cases. So, for purposes of sending these extended-ascii commands, I don't mess with strings and just send the byte array to the service with
private void sendCommand(byte[] cmd) {
mChatService.write(cmd);
}
The so-called command array is first initialized with placeholders for the hex radio address elements
byte[] addrArray = {(byte) 0xCC, 16, 0, 0, 0, 13};
and then filled in with the help of the conversion method
radioArray = HexStringToByteArray(radioAddr1);
which can be found here: HexStringToByteArray#stackoverflow

Categories

Resources