I've got a strange problem with updating my Magnet-Characteristic. I use a service with 4 characteristics (Gyro, Acc, Mag and Temp Values) and update them on a timer base. The other 3 working just fine, the Mag-Char gets update once and then never again. Checked it with debugging, it seems I get new information from my BMX Sensor, but the update just doesn't work like the other 3. The Chars are just copy/paste jobs with changed variables, so it should work. Maybe some of you can tell me what's wrong in the code? Btw, if I set the Offset-Value in the HVX-Params to 1 (the first Byte of my data is useless) it also doesn't update my characteristics anymore. Here's the main function, calling the get sensor data function and the update chars functions.
if(run)
{
spi_enable();
bmx_get_gyro(gyro);
bmx_get_temp(temp);
//spi_send(gyro);
bmx_get_acc(acc);
bmx_get_mag(mag);
spi_disable();
bmx_gyro_char_update(&bmx_service,gyro);
bmx_acc_char_update(&bmx_service,acc);
bmx_temp_char_update(&bmx_service,temp);
bmx_mag_char_update(&bmx_service,mag);
run = false;
}
Here I add the chars to the service
uint32_t bmx_add_chars(ble_svc_bmx *svc)
{
// Add a custom characteristic UUID
uint32_t err_code;
ble_uuid_t gyro_uuid,acc_uuid,mag_uuid,temp_uuid;
ble_uuid128_t base_uuid = BLE_UUID_BASE; // BASE-ID
gyro_uuid.uuid = BLE_UUID_GYRO_UUID; // GYRO-UUID
acc_uuid.uuid = BLE_UUID_ACC_UUID; // ACC-UUID
mag_uuid.uuid = BLE_UUID_MAG_UUID; // MAG-UUID
temp_uuid.uuid = BLE_UUID_TEMP_UUID; // TEMP-UUID
// Register Char-UUIDs to Service
err_code = sd_ble_uuid_vs_add(&base_uuid, &gyro_uuid.type);
err_code = sd_ble_uuid_vs_add(&base_uuid, &acc_uuid.type);
err_code = sd_ble_uuid_vs_add(&base_uuid, &mag_uuid.type);
err_code = sd_ble_uuid_vs_add(&base_uuid, &temp_uuid.type);
APP_ERROR_CHECK(err_code);
// Add read/write properties to characteristic (seen by Client)
ble_gatts_char_md_t gyro_char_md,acc_char_md,mag_char_md,temp_char_md;
memset(&gyro_char_md, 0, sizeof(gyro_char_md));
memset(&acc_char_md, 0, sizeof(acc_char_md));
memset(&mag_char_md, 0, sizeof(mag_char_md));
memset(&temp_char_md, 0, sizeof(temp_char_md));
gyro_char_md.char_props.read = 1;
acc_char_md.char_props.read = 1;
mag_char_md.char_props.read = 1;
temp_char_md.char_props.read = 1;
// Configuring Client Characteristic Configuration Descriptor metadata and add to char_md structure
// Setting Permissions for Chars
ble_gatts_attr_md_t gyro_cccd_md,acc_cccd_md,mag_cccd_md,temp_cccd_md;
// Initialize everything with default
memset(&gyro_cccd_md, 0, sizeof(gyro_cccd_md));
memset(&acc_cccd_md, 0, sizeof(acc_cccd_md));
memset(&mag_cccd_md, 0, sizeof(mag_cccd_md));
memset(&temp_cccd_md, 0, sizeof(temp_cccd_md));
// Set Read and Write Permissions
BLE_GAP_CONN_SEC_MODE_SET_OPEN(&gyro_cccd_md.read_perm);
BLE_GAP_CONN_SEC_MODE_SET_OPEN(&gyro_cccd_md.write_perm);
BLE_GAP_CONN_SEC_MODE_SET_OPEN(&acc_cccd_md.read_perm);
BLE_GAP_CONN_SEC_MODE_SET_OPEN(&acc_cccd_md.write_perm);
BLE_GAP_CONN_SEC_MODE_SET_OPEN(&mag_cccd_md.read_perm);
BLE_GAP_CONN_SEC_MODE_SET_OPEN(&mag_cccd_md.write_perm);
BLE_GAP_CONN_SEC_MODE_SET_OPEN(&temp_cccd_md.read_perm);
BLE_GAP_CONN_SEC_MODE_SET_OPEN(&temp_cccd_md.write_perm);
// Store CCCDs in Stack, allow notifications
static char gyro[] = "Gyro";
static char acc[] = "Acc";
static char mag[] = "Mag";
static char temp[] = "Temp";
gyro_cccd_md.vloc = BLE_GATTS_VLOC_STACK;
gyro_char_md.p_cccd_md = &gyro_cccd_md;
gyro_char_md.char_props.notify = 1;
gyro_char_md.char_user_desc_size = strlen(gyro);
gyro_char_md.char_user_desc_max_size = strlen(gyro);
gyro_char_md.p_char_user_desc = (uint8_t *) gyro;
acc_cccd_md.vloc = BLE_GATTS_VLOC_STACK;
acc_char_md.p_cccd_md = &acc_cccd_md;
acc_char_md.char_props.notify = 1;
acc_char_md.char_user_desc_size = strlen(acc);
acc_char_md.char_user_desc_max_size = strlen(acc);
acc_char_md.p_char_user_desc = (uint8_t *) acc;
mag_cccd_md.vloc = BLE_GATTS_VLOC_STACK;
mag_char_md.p_cccd_md = &mag_cccd_md;
mag_char_md.char_props.notify = 1;
mag_char_md.char_user_desc_size = strlen(mag);
mag_char_md.char_user_desc_max_size = strlen(mag);
mag_char_md.p_char_user_desc = (uint8_t *) mag;
temp_cccd_md.vloc = BLE_GATTS_VLOC_STACK;
temp_char_md.p_cccd_md = &temp_cccd_md;
temp_char_md.char_props.notify = 1;
temp_char_md.char_user_desc_size = strlen(temp);
temp_char_md.char_user_desc_max_size = strlen(temp);
temp_char_md.p_char_user_desc = (uint8_t *) temp;
// Configure the attribute metadata, store in Stack
ble_gatts_attr_md_t gyro_attr_md,acc_attr_md,mag_attr_md,temp_attr_md;
memset(&gyro_attr_md, 0, sizeof(gyro_attr_md));
memset(&acc_attr_md, 0, sizeof(acc_attr_md));
memset(&mag_attr_md, 0, sizeof(mag_attr_md));
memset(&temp_attr_md, 0, sizeof(temp_attr_md));
gyro_attr_md.vloc = BLE_GATTS_VLOC_STACK;
acc_attr_md.vloc = BLE_GATTS_VLOC_STACK;
mag_attr_md.vloc = BLE_GATTS_VLOC_STACK;
temp_attr_md.vloc = BLE_GATTS_VLOC_STACK;
// Set read/write security levels to characteristics, atm open
BLE_GAP_CONN_SEC_MODE_SET_OPEN(&gyro_attr_md.read_perm);
BLE_GAP_CONN_SEC_MODE_SET_OPEN(&acc_attr_md.read_perm);
BLE_GAP_CONN_SEC_MODE_SET_OPEN(&mag_attr_md.read_perm);
BLE_GAP_CONN_SEC_MODE_SET_OPEN(&temp_attr_md.read_perm);
// Configure the characteristic value attribute
ble_gatts_attr_t attr_gyro_value,attr_acc_value,attr_mag_value,attr_temp_value;
memset(&attr_gyro_value, 0, sizeof(attr_gyro_value));
memset(&attr_acc_value, 0, sizeof(attr_acc_value));
memset(&attr_mag_value, 0, sizeof(attr_mag_value));
memset(&attr_temp_value, 0, sizeof(attr_temp_value));
attr_gyro_value.p_uuid = &gyro_uuid;
attr_gyro_value.p_attr_md = &gyro_attr_md;
attr_acc_value.p_uuid = &acc_uuid;
attr_acc_value.p_attr_md = &acc_attr_md;
attr_mag_value.p_uuid = &mag_uuid;
attr_mag_value.p_attr_md = &mag_attr_md;
attr_temp_value.p_uuid = &temp_uuid;
attr_temp_value.p_attr_md = &temp_attr_md;
// Set characteristic length in number of bytes
attr_gyro_value.max_len = 7;
attr_gyro_value.init_len = 2;
uint8_t value[2] = {0xFF,0xFF};
attr_gyro_value.p_value = value;
attr_acc_value.max_len = 7;
attr_acc_value.init_len = 2;
attr_acc_value.p_value = value;
attr_mag_value.max_len = 9;
attr_mag_value.init_len = 2;
attr_mag_value.p_value = value;
attr_temp_value.max_len = 2;
attr_temp_value.init_len = 2;
attr_temp_value.p_value = value;
// Add characteristics to the service
err_code = sd_ble_gatts_characteristic_add(svc->service_handle,
&gyro_char_md,
&attr_gyro_value,
&svc->gyro_handle);
APP_ERROR_CHECK(err_code);
err_code = sd_ble_gatts_characteristic_add(svc->service_handle,
&acc_char_md,
&attr_acc_value,
&svc->acc_handle);
APP_ERROR_CHECK(err_code);
err_code = sd_ble_gatts_characteristic_add(svc->service_handle,
&mag_char_md,
&attr_mag_value,
&svc->mag_handle);
APP_ERROR_CHECK(err_code);
err_code = sd_ble_gatts_characteristic_add(svc->service_handle,
&temp_char_md,
&attr_temp_value,
&svc->temp_handle);
APP_ERROR_CHECK(err_code);
return NRF_SUCCESS;
}
And finally my Magnet-Update function
void bmx_mag_char_update(ble_svc_bmx *bmx_svc, uint8_t *mag_val)
{
// JUST SEND NOTIFICATION IF CONNECTION IS ESTABLISHED - OTHERWISE ERROR FROM STACK!
if (bmx_svc->conn_handle != BLE_CONN_HANDLE_INVALID)
{
uint16_t len = 9;
ble_gatts_hvx_params_t hvx_params;
memset(&hvx_params, 0, sizeof(hvx_params));
// GET HANDLE
hvx_params.handle = bmx_svc->mag_handle.value_handle;
hvx_params.type = BLE_GATT_HVX_NOTIFICATION;
hvx_params.offset = 0;
hvx_params.p_len = &len;
hvx_params.p_data = (uint8_t*)mag_val;
// STORE VALUE AND SEND NOTIFICATION
sd_ble_gatts_hvx(bmx_svc->conn_handle, &hvx_params);
}
}