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

Can't update BLE-Characteristic

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);

}

}
Related