This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts
This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

BLE send and receive speed, GATTS

Hello,

Currently i am doing some testing with the NRF52 DK. I am measuring the time it takes to send and receive a BLE message. I am using the high bandwidth setting the the TX and RX.

conn_bw.conn_bw.conn_bw_rx = BLE_CONN_BW_HIGH;
conn_bw.conn_bw.conn_bw_tx = BLE_CONN_BW_HIGH;

also i am using a write command instead of a write request.

writeParameters.write_op = BLE_GATT_OP_WRITE_CMD;
err = sd_ble_gattc_write(connectionHandle, &writeParameters);

For the connection interval I use both on 7.5 ms

uint16_t meshMinConnectionInterval = MSEC_TO_UNITS(7.5, UNIT_1_25_MS);   	
uint16_t meshMaxConnectionInterval = MSEC_TO_UNITS(7.5, UNIT_1_25_MS);  

The packet length is 20 bytes. What i found was that the time it took to send and receive that message was very unreliable. I did the test a 100 times and found these results:

> Average time = 35,86364746 ms 
> longest time = 86,36474609 ms 
> shortest time =1,525878906 ms

I was wondering how this can take so long sometimes?

Thanks in advance.

  • How are you measuring? Do you measure from the sd_ble_gattc_write(..) command is sent to the TX complete event is received or to the packet is received on the other side?

    You will naturally have variable latency in BLE because of the connection interval. If you manage to update the SoftDevice buffer right before the connection event, you will have the lowest latency, if you do it right after, you will have the highest latency (lowest + connection interval).

    You should check that the connection interval is actually set to 7.5 ms, from your measurements it looks like it may be closer to 85 ms.

    The application can also delay the measurements depending on interrupt levels and where you start/stop the measurements or where you call sd_ble_gattc_write(..).

  • I am setting the interval here. with the setting above, also slavelatancy is 0.

    ble_gap_conn_params_t gapConnectionParams;
    	memset(&gapConnectionParams, 0, sizeof(gapConnectionParams));
    	gapConnectionParams.min_conn_interval = Config->meshMinConnectionInterval;
    	gapConnectionParams.max_conn_interval = Config->meshMaxConnectionInterval;
    	gapConnectionParams.slave_latency = Config->meshPeripheralSlaveLatency;
    	gapConnectionParams.conn_sup_timeout = Config->meshConnectionSupervisionTimeout;
    	err = sd_ble_gap_ppcp_set(&gapConnectionParams);
    	APP_ERROR_CHECK(err); //OK
    
  • when i start sending i set a gpio pin high, this is measured on a other nrf52DK and i take a RTC timestamp wich is 30US per tick. When I receive the message on my other device, i am polling with:

    sizeOfCurrentEvent = sizeOfEvent;
    err = sd_ble_evt_get((u8*)currentEventBuffer, &sizeOfCurrentEvent);
    

    if err == NRF_SUCCES then I check if it my messeage, if so I set another GPIO pin high. my 3rd NRF52Dk will take a second time stamp, timestamp2-timestamp1 = result/32768*1000 = result in ms

  • I did the same test but now i send 100 packets with 20 bytes payload.

    Average = 384,0847778 == 260 packet/s
    Max = 537,5976563 == 186 packet/s
    Min = 223,7243652 == 446 packet/s 
    

    I shouldn't be to reach 446 packets/s with 85 ms delay. With 446 packets/s = ~13,5 ms delay, 800 pakcets/s = 7.5 ms,

  • To update the connection parameters you will have to call sd_ble_gap_conn_param_update(..), with sd_ble_gap_ppcp_set(..) you are only setting the preferred connection parameters. Basically this is the way it goes:

    • The central will decide the initial connection parameters. If you are using an nRF device for the central, the desired connection parameters (the SoftDevice may choose higher values if it is not possible due to too many connections) are the last parameter in sd_ble_gap_connect(..).

    • The central or peripheral can later update or request to update the connection parameters by calling sd_ble_gap_conn_param_update(..)

    Check what the connection parameters used by the central is. I also advise you to use the SDK connection parameters negotiation library which is used by most of our BLE examples.

Related