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

Sending consecutive BLE notifications

Hi! I've got a nRF52 dev kit and I'm programming it with SDK 15 with Keil. When I send 3 consecutive BLE notifications (each notification is 4 bytes) to the Android app, the app reads the last notification 3 times.

I send the notifications in a loop like this (data is different in each iteration):

for (uint8_t i = 0; i < 3; i++)
{       
    err_code = ble_send(m_conn_handle, &m_abc, (uint8_t*)&data);
    while (err_code != NRF_SUCCESS);
    nrf_delay_ms(100);
}

WITHOUT the delay between sending the notifications, the Android app receives the same data that was last sent, 3 times. WITH the delay, the Android app receives all 3 notifications correctly. How can I make it work without delay?

In the Android app I use the Nordic Android BLE library and initialize my callback to receive notifications:

private final BleManagerGattCallback mGattCallback = new BleManagerGattCallback() {
	@Override
	protected void initialize() {
        setNotificationCallback(mCharacteristic).with(mDataCallback);
    }
}

mDataCallback implements DataReceivedCallback.

For the dev kit, BLE connection parametes are defined like this:

#define MIN_CONN_INTERVAL  MSEC_TO_UNITS(20, UNIT_1_25_MS)
#define MAX_CONN_INTERVAL  MSEC_TO_UNITS(30, UNIT_1_25_MS)
#define SLAVE_LATENCY      0                            
#define CONN_SUP_TIMEOUT   MSEC_TO_UNITS(1000, UNIT_10_MS)

Thanks for any help in advance!

Parents
  • Can you post the code of ble_send()? How is data updated between calls to ble_send() in the loop?

  • This is ble_send():

    uint32_t ble_send(uint16_t conn_handle, ble_abc_t * p_abc, uint8_t * data)
    {
    	ble_gatts_hvx_params_t params;
    	uint16_t len = 4;
    
        memset(&params, 0, sizeof(params));
        params.type   = BLE_GATT_HVX_NOTIFICATION;
        params.handle = p_ams->config_char_handles.value_handle;
        params.p_data = data;
        params.p_len  = &len;
    
        return sd_ble_gatts_hvx(conn_handle, &params);
    }

    This is the function where notifications are sent:

    void sendDataControl(void)
    {
    	ret_code_t err_code;
    	
    	if(isDataReady)
    	{
            uint16_t data[2];
    
            for (uint8_t i = 0; i < 3; i++)
            {
    	        data[0] = i+1;
    	        data[1] = u16_sensor_data[i]; // copy data from global array
    			
    	        err_code = ble_send(m_conn_handle, &m_abc, (uint8_t*)&data);
    	        while (err_code != NRF_SUCCESS); // wait for NRF_SUCCESS
    	        nrf_delay_ms(100); // with delay, phone app gets all data correctly
    			                   // without delay, phone app gets the lastly sent data 3 times
    	        if (err_code != NRF_SUCCESS &&
    	        err_code != BLE_ERROR_INVALID_CONN_HANDLE &&
    	        err_code != NRF_ERROR_INVALID_STATE &&
    	        err_code != BLE_ERROR_GATTS_SYS_ATTR_MISSING)
    	        {
    		        APP_ERROR_CHECK(err_code);
    	        }
            }
            
            isDataReady = false;
        }
    }

Reply
  • This is ble_send():

    uint32_t ble_send(uint16_t conn_handle, ble_abc_t * p_abc, uint8_t * data)
    {
    	ble_gatts_hvx_params_t params;
    	uint16_t len = 4;
    
        memset(&params, 0, sizeof(params));
        params.type   = BLE_GATT_HVX_NOTIFICATION;
        params.handle = p_ams->config_char_handles.value_handle;
        params.p_data = data;
        params.p_len  = &len;
    
        return sd_ble_gatts_hvx(conn_handle, &params);
    }

    This is the function where notifications are sent:

    void sendDataControl(void)
    {
    	ret_code_t err_code;
    	
    	if(isDataReady)
    	{
            uint16_t data[2];
    
            for (uint8_t i = 0; i < 3; i++)
            {
    	        data[0] = i+1;
    	        data[1] = u16_sensor_data[i]; // copy data from global array
    			
    	        err_code = ble_send(m_conn_handle, &m_abc, (uint8_t*)&data);
    	        while (err_code != NRF_SUCCESS); // wait for NRF_SUCCESS
    	        nrf_delay_ms(100); // with delay, phone app gets all data correctly
    			                   // without delay, phone app gets the lastly sent data 3 times
    	        if (err_code != NRF_SUCCESS &&
    	        err_code != BLE_ERROR_INVALID_CONN_HANDLE &&
    	        err_code != NRF_ERROR_INVALID_STATE &&
    	        err_code != BLE_ERROR_GATTS_SYS_ATTR_MISSING)
    	        {
    		        APP_ERROR_CHECK(err_code);
    	        }
            }
            
            isDataReady = false;
        }
    }

Children
No Data
Related