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

}

}
Parents
  • I'm getting 9 Bytes from the magnetometer that are stored in an uint8_t array. After filling the array with data I'm calling the bmx_mag_char_update function with a reference to the data. The same method works for the other characteristics but not for this one, it just get stored/updated once but the debug functionality tells me I'm getting new data on every timer interrupt from the sensors. As for now I'm not chopping anything as far as I can see. The values are stored in an array inside my main static uint8_t gyro[7],acc[7],mag[9],temp[2];, then the data gets written to it

    void bmx_get_mag(uint8_t *rx)
    {
    static uint8_t tx[2] = {BMX_MAG_PWR_CTRL2,0x02};
    // ...
    tx[0]=BMX_MAG_DATA;
    nrf_gpio_pin_clear(SPI_CS_MAG);
    nrf_drv_spi_transfer(&spi, tx, 1, rx, 9);		// Get Data
    wait_for_SPI();
    nrf_gpio_pin_set(SPI_CS_MAG);
    }
    

    then calling the bmx_mag_char_update

Reply
  • I'm getting 9 Bytes from the magnetometer that are stored in an uint8_t array. After filling the array with data I'm calling the bmx_mag_char_update function with a reference to the data. The same method works for the other characteristics but not for this one, it just get stored/updated once but the debug functionality tells me I'm getting new data on every timer interrupt from the sensors. As for now I'm not chopping anything as far as I can see. The values are stored in an array inside my main static uint8_t gyro[7],acc[7],mag[9],temp[2];, then the data gets written to it

    void bmx_get_mag(uint8_t *rx)
    {
    static uint8_t tx[2] = {BMX_MAG_PWR_CTRL2,0x02};
    // ...
    tx[0]=BMX_MAG_DATA;
    nrf_gpio_pin_clear(SPI_CS_MAG);
    nrf_drv_spi_transfer(&spi, tx, 1, rx, 9);		// Get Data
    wait_for_SPI();
    nrf_gpio_pin_set(SPI_CS_MAG);
    }
    

    then calling the bmx_mag_char_update

Children
No Data
Related