Closed rbrondi closed 6 years ago
Hi Raffaello,
I'm sorry but for both the question the answer is no.
From the library point of view you just enable the notification, the update frequency is decided by the firmware.
To change the connection interval, in theory you can request a connection interval from android using this method: requestConnectionPriority
but I didn't use it because I can not control what means "high priority".
We change the connection interval from the firmware using the function: aci_l2cap_connection_parameter_update_request
.
We use it in the FP-SNS-ALLMEMS1 when we transmit the audio data from the sensor tile/bluecoin. If I remember well we set it to 11.5 because not all device (and ios) where supporting lower configuration.
Note that the accelerometer and gyroscope data are transmitted together with the magnetometer data. If you don't need the magnetometer and you need an high frequency I will consider to remove the magnetometer data (changing the characteristics uuid and format) so save bandwidth.
Best Regards Giovanni
Hi Vincenzo, thanks for your reply.
I tried to edit the ALLMEMS firmware in order to change the max connection interval parameter.
I've downloaded the sample code, compiled it and flashed the board. Everything works fine. Then I tryed to change the BLE max connection interval. If I'm not wrong, you change it using the aci_l2cap_connection_parameter_update_request
function inside sensor_service.c@1452
. I tryed to call the function with the same parameters just outside the if
statement (if(TargetBoardFeatures.AudioBVIsInitalized){
).
The function is called when I connect to the board returning a BLE_STATUS_SUCCESS status (I switched on a led upon success). But when I try to interact with the board with the application I receive an error.
D/BluetoothGatt: onClientConnParamsChanged() - Device=C0:83:28:31:57:XX interval=12 status=0
W/BluetoothGatt: onCharacteristicRead() - Device=C0:85:4A:37:54:XX handle=26 Status=133
E/com.st.BlueSTSDK.Node: Error reading the characteristics: android.bluetooth.BluetoothGattCharacteristic@48e4462
Error connecting to the node:null
D/BluetoothGatt: close()
D/BluetoothGatt: unregisterApp() - mClientIf=7
W/STConnection: onStateChange: new state Dead
D/BluetoothGatt: onClientConnectionState() - status=8 clientIf=7 device=C0:85:4A:37:54:XX
W/BluetoothGatt: Unhandled exception in callback
java.lang.NullPointerException: Attempt to invoke virtual method 'void android.bluetooth.BluetoothGattCallback.onConnectionStateChange(android.bluetooth.BluetoothGatt, int, int)' on a null object reference
at android.bluetooth.BluetoothGatt$1.onClientConnectionState(BluetoothGatt.java:228)
at android.bluetooth.IBluetoothGattCallback$Stub.onTransact(IBluetoothGattCallback.java:70)
at android.os.Binder.execTransact(Binder.java:573)
I don't know if this is the place where asking for this kind of support. If not, can you please tell me where I can ask? Thanks a lot. Raffaello
It is strange that the node is null.. Can you post the line from the connection to the error? It is happening in your application or in the example application? Could you try also the example application?
In the meantime I will check with the Fw people if your change is correct.
Best Regards Giovanni
Good morning Vincenzo.
Yesterday I wrongly assumed that the if statement where the library sets the intervals was not executed by default. Today I verified instead that the code is alway called. So probably the issue was related to a double call to aci_l2cap_connection_parameter_update_request
.
I removed the call to aci_l2cap_connection_parameter_update_request
function I inserted yesterday and I tried to change the original values (sensor_service.c@1452):
ret = aci_l2cap_connection_parameter_update_request(handle,
8 /* interval_min*/,
17 /* interval_max */,
0 /* slave_latency */,
400 /*timeout_multiplier*/);
Setting interval_max to a lower(11) or greater(110) value did not change the data rate on the tablet.
I then tried to remove the magnetometer values from the BLE package editing the function AccGyroMag_Update in sensor_service.c:
tBleStatus AccGyroMag_Update(SensorAxes_t *Acc,SensorAxes_t *Gyro,SensorAxes_t *Mag)
{
tBleStatus ret;
int32_t AXIS_X;
int32_t AXIS_Y;
int32_t AXIS_Z;
const size_t buff_dim = 2+3*2*2;
// uint8_t buff[2+3*3*2];
uint8_t buff[buff_dim];
STORE_LE_16(buff ,(HAL_GetTick()>>3));
STORE_LE_16(buff+2 ,Acc->AXIS_X);
STORE_LE_16(buff+4 ,Acc->AXIS_Y);
STORE_LE_16(buff+6 ,Acc->AXIS_Z);
Gyro->AXIS_X/=100;
Gyro->AXIS_Y/=100;
Gyro->AXIS_Z/=100;
STORE_LE_16(buff+8 ,Gyro->AXIS_X);
STORE_LE_16(buff+10,Gyro->AXIS_Y);
STORE_LE_16(buff+12,Gyro->AXIS_Z);
/* Apply Magneto calibration */
/*AXIS_X = Mag->AXIS_X - MAG_Offset.AXIS_X;
AXIS_Y = Mag->AXIS_Y - MAG_Offset.AXIS_Y;
AXIS_Z = Mag->AXIS_Z - MAG_Offset.AXIS_Z;
STORE_LE_16(buff+14,AXIS_X);
STORE_LE_16(buff+16,AXIS_Y);
STORE_LE_16(buff+18,AXIS_Z);
*/
// ret = ACI_GATT_UPDATE_CHAR_VALUE(HWServW2STHandle, AccGyroMagCharHandle, 0, 2+3*3*2, buff);
ret = ACI_GATT_UPDATE_CHAR_VALUE(HWServW2STHandle, AccGyroMagCharHandle, 0, buff_dim, buff);
if (ret != BLE_STATUS_SUCCESS){
if(W2ST_CHECK_CONNECTION(W2ST_CONNECT_STD_ERR)){
BytesToWrite =sprintf((char *)BufferToWrite, "Error Updating Acc/Gyro/Mag Char\r\n");
Stderr_Update(BufferToWrite,BytesToWrite);
} else {
ALLMEMS1_PRINTF("Error Updating Acc/Gyro/Mag Char\r\n");
}
return BLE_STATUS_ERROR;
}
return BLE_STATUS_SUCCESS;
}
The result was the same (frequencies are still lower than 50Hz). My final attempt was to disable all the unneeded sensors in the Init_MEM1_Sensors
function, but still no luck.
Could you please help me in trying to increase the sensor data rate?
Thanks, Raffaello
Hi Raffaelo,
First of all my name is Giovanni, not Vincenzo :)
Then:
to force a connection interval the min and max must have the same value, if you use a bigger range like 11-110 probably noting will happen since the default value is inside that range.
changing the connection interval will increase the maximum number of notifications that you can send, but it doesn't change how many notification the fw is sending
to change the number of notification, try to change/see the define DEFAULT_uhCCR4_Val
.
inside our sdk each characteristics prefix describe what the characteristics contains, for example the mems charateristics is: 0xE00000 = 0x800000 (accelerometer) + 0x400000 (gyroscope) + 0x200000 ( magnetometer) . if you want to remove the magneto you have to define the characteristics with 0xC00000 as prefix, search: COPY_ACC_GYRO_MAG_W2ST_CHAR_UUID
to see how define a charateristics.
remove the charateristics 0xE00000 to avoid that the sdk choose that one, when you enable the accelerometer or gyroscope notification
Best Regards Giovanni
Hi Giovanni,
I really apologize for the mistake. I absolutely don't know why I called you Vincezo..so embarassing :S
Thanks again for your inputs. I've successfully increased the data rate by changing the value of the variable DEFAULT_uhCCR4_Val
Now I'm trying to understand how to interpret the data I'm receiving on the mobile device. Looking at the datasheet of the sensor LSM6DSM and the source code of the firmware, looks like that the sensors are streaming accelerations using mG
and angular velocities using mdps
measurement units. Is it right?
In my application I need to work with accelerations expressed in g
and angular velocities expressed in dps
. So I thought to just multiply each sample component by 0.001. When I looked at FeatureGyroscope
source code(line 130) I've seen that each component is multiplied by 0.1 while no conversion is applied to acceleration data in FeatureAcceleration
(line 142). Is my assumption wrong? Why did you multiply angular velocity components by 0.1?
As regard as the null value for the node name I think the problem is related to the fact that I'm manually creating a Node
instance for each sensor I've to connect. The application I'm developing needs to directly connect to the sensors without making a previous scan.
Looking at the BlueSTSDK code I've seen that to obtain an instance of a Node
you need to interact with the Manager
class which mantains a list of discovered node. Since the list is empty in my case, to create a new Node
I used the same code of the test suit :
private Node createNode(BluetoothDevice device) {
//taken from ST test suit. Create a generic ble node using a default advertisement array
byte[] advertisement = new byte[]{0x07, (byte) 0xFF, (byte) 0x01, (byte) 0x00, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF};
try {
return new Node(device, 10, advertisement);
} catch (InvalidBleAdvertiseFormat invalidBleAdvertiseFormat) {
//should never happen
throw new RuntimeException(invalidBleAdvertiseFormat);
}
}
Is this wrong? Is there a better way to achive the result?
Thanks a lot Raffaello
Hi Raffaello,
to know the units you can see the FEATURE_UNIT
constant in the feature class.
for the Accelorometer when you use the getAccX()
method, you have the data in mg.
for the Gyroscope when you use the getGyroX()
method you have the data in dps. I'm dividing by 10 because we send also 1 decimal position.
if you create the node by hand you can add it to the manager with the addNode method.
Giovanni
Hi all,
I've started using the library to interact with a BlueCoin and a SensorTile boards. So far I successfully connect to the board, receive battery information and stream gyro and accelerometer data from both boards at the same time.
I've recorded accelerations and angular velocities for some seconds and the data rate varies between 20hz and 45hz. Is there a way to set the desired frequencies for both the sensors using the BlueSTSDK library? Which is the maximum throughput for the two boards? How can I maximize the data throughput?
For the project I'm working on, it is crucial to receive data from 3 up to 5 IMUs simultaneously at about 50hz. I've read in other posts that on Android a way to maximize the throughput of the BLE is to set the max connection interval to 11,5ms (or 7,5ms depending on the OS version). Is there a way to set this parameter using the BlueSTSDK library?
Thanks Raffaello