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

Best flow for notifications

HI, I have a custom service with customs characteristics and I need the maximum speed posible. 

I have one service for write without response and another service only with notifications. 

I have the min_conn_interval and the max_conn_interval at 7.5.

The NRF_SDH_BLE_GATT_MAX_MTU_SIZE is in 247. 

The NRF_SDH_BLE_GAP_DATA_LENGTH is in 251.

On advertising_init() I have setted the  init.config.ble_adv_primary_phy = BLE_GAP_PHY_1MBPS.

Also I have the DLE enabled.

And I have two questions :

I'm using a boolean as semaphore, It turn off each time that I update the characteristic,  and after that I turn on again with the event BLE_GATTS_EVT_HVN_TX_COMPLETE, but doing that the data trans its so so slow. But, if I don't do this I lost a lot of data packages

I use the next function to update the notify characteristic: 

uint32_t update_acc_read_value(ble_cus_t *p_cus, uint8_t *custom_value) {
    if (p_cus == NULL) {
        return NRF_ERROR_NULL;
    }
    uint32_t
    err_code = NRF_SUCCESS;
    // Send value if connected and notifying.
    if ((p_cus->conn_handle != BLE_CONN_HANDLE_INVALID)) {

        uint16_t
        length = 1 + strlen(custom_value);
        isNotificationReaded = false; // SEMAPHORE = FALSE
        ble_gatts_hvx_params_t hvx_params;
        memset(&hvx_params, 0, sizeof(hvx_params));
        hvx_params.handle = p_cus->custom_value_acc.value_handle;
        hvx_params.type = BLE_GATT_HVX_NOTIFICATION;
        hvx_params.p_len = &length;
        hvx_params.p_data = custom_value;

        err_code = sd_ble_gatts_hvx(p_cus->conn_handle, &hvx_params);
    } else {
        err_code = NRF_ERROR_INVALID_STATE;
    }
    return err_code;
}

With the next function the data transfer is 'faster' but I get repeated data.

I get in 50 seconds 5780 packages * 246 bytes = 1421880 bytes = 11375050 bits, 

11375050 / 50 = 22750 bits/second

void test_mode() {
    NRF_LOG_INFO("TEST")
    nrf_delay_ms(1000);
    isNotificationReaded = true;

    char buff[247];
    for (int i = 0; i < 246; i++) {
        buff[i] = 'A';
    }
    for (int i = 0; i < 4000;) {
        update_acc_read_value(&m_cus, buff);
        if (isNotificationReaded) {
            i++;
        }
    } 
}

But if I use the function correctly with my semaphore flow: 

I get in 63 seconds 4000 packages * 246 bytes = 984000 bytes = 7872000 bits, 

7872000 / 63 = 124952 bits/second

void test_mode() {
    NRF_LOG_INFO("TEST")
    nrf_delay_ms(1000);
    isNotificationReaded = true;

    char buff[247];
    for (int i = 0; i < 246; i++) {
        buff[i] = 'A';
    }
    for (int i = 0; i < 4000;) {
        if (isNotificationReaded) {
        update_acc_read_value(&m_cus, buff);
            i++;
        }
    } 
}

So, My questions are : 

- Its correct my semaphore flow ? If is not correct, how can I send fasters notifications but without data loss ? 

- How can I improve the speed even more ? Because I wasted a few days researching about that and I only find that, time_interval min as posible and packages larger as posible, DLE enabled and not much more.

Im developing with raspberry pi as ble_server but I have tested on iPhone and android and the results are even worst.

Thanks a lot ! 

Parents
  • Hi,

    For maximum throughput you need to check if there is tx buffers left. So call sd_ble_gatts_hvx and place data in the tx buffers until you get the error: NRF_ERROR_RESOURCES, When this happens you have to wait for a BLE_GATTS_EVT_HVN_TX_COMPLETE event and retry. If you do not check that you have succesfully placed data in the tx buffers you will lose data.

    Message sequence chart here.

    Notice that it might be possible to transfer data faster by using a longer connection interval and DLE. See SD documentation.

  • Could I see the correct flow in one example ?? 

    I still lossig data packets or if I do a ' do while ' with the sd_ble_gatts_hvx function I get repeated packets of data ! 

    Wich advertisal time its better for this proposal , now its setted and 7,5 both, min and max 

    In the ble_hrs for example the hvx add data function its used on ble_hrs_heart_rate_measurement_send, and these function its called in the main.c file, inside the hrs_c_evt_handler function. And its used one time.

    edit: solved with a delay, no data loss 

    do {
    nrf_delay_ms(25);
    err_code = sd_ble_gatts_hvx(p_cus->conn_handle, &hvx_params);
    } while (err_code != NRF_SUCCESS);

    But its slower. 

Reply
  • Could I see the correct flow in one example ?? 

    I still lossig data packets or if I do a ' do while ' with the sd_ble_gatts_hvx function I get repeated packets of data ! 

    Wich advertisal time its better for this proposal , now its setted and 7,5 both, min and max 

    In the ble_hrs for example the hvx add data function its used on ble_hrs_heart_rate_measurement_send, and these function its called in the main.c file, inside the hrs_c_evt_handler function. And its used one time.

    edit: solved with a delay, no data loss 

    do {
    nrf_delay_ms(25);
    err_code = sd_ble_gatts_hvx(p_cus->conn_handle, &hvx_params);
    } while (err_code != NRF_SUCCESS);

    But its slower. 

Children
Related